요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
Rules on how to access information in sysfs
===========================================
The kernel-exported sysfs exports internal kernel implementation details
and depends on internal kernel structures and layout. It is agreed upon
by the kernel developers that the Linux kernel does not provide a stable
internal API. Therefore, there are aspects of the sysfs interface that
may not be stable across kernel releases.
To minimize the risk of breaking users of sysfs, which are in most cases
low-level userspace applications, with a new kernel release, the users
of sysfs must follow some rules to use an as-abstract-as-possible way to
access this filesystem. The current udev and HAL programs already
implement this and users are encouraged to plug, if possible, into the
abstractions these programs provide instead of accessing sysfs directly.
But if you really do want or need to access sysfs directly, please follow
the following rules and then your programs should work with future
versions of the sysfs interface.
- Do not use libsysfs
It makes assumptions about sysfs which are not true. Its API does not
offer any abstraction, it exposes all the kernel driver-core
implementation details in its own API. Therefore it is not better than
reading directories and opening the files yourself.
Also, it is not actively maintained, in the sense of reflecting the
current kernel development. The goal of providing a stable interface
to sysfs has failed; it causes more problems than it solves. It
violates many of the rules in this document.
- sysfs is always at ``/sys``
Parsing ``/proc/mounts`` is a waste of time. Other mount points are a
system configuration bug you should not try to solve. For test cases,
possibly support a ``SYSFS_PATH`` environment variable to overwrite the
application's behavior, but never try to search for sysfs. Never try
to mount it, if you are not an early boot script.
- devices are only "devices"
There is no such thing like class-, bus-, physical devices,
interfaces, and such that you can rely on in userspace. Everything is
just simply a "device". Class-, bus-, physical, ... types are just
kernel implementation details which should not be expected by
applications that look for devices in sysfs.
The properties of a device are:
- devpath (``/devices/pci0000:00/0000:00:1d.1/usb2/2-2/2-2:1.0``)
- identical to the DEVPATH value in the event sent from the kernel
at device creation and removal
- the unique key to the device at that point in time
- the kernel's path to the device directory without the leading
``/sys``, and always starting with a slash
- all elements of a devpath must be real directories. Symlinks
pointing to /sys/devices must always be resolved to their real
target and the target path must be used to access the device.
That way the devpath to the device matches the devpath of the
kernel used at event time.
- using or exposing symlink values as elements in a devpath string
is a bug in the application
- kernel name (``sda``, ``tty``, ``0000:00:1f.2``, ...)
- a directory name, identical to the last element of the devpath
- applications need to handle spaces and characters like ``!`` in
the name
- subsystem (``block``, ``tty``, ``pci``, ...)
- simple string, never a path or a link
- retrieved by reading the "subsystem"-link and using only the
last element of the target path
- driver (``tg3``, ``ata_piix``, ``uhci_hcd``)
- a simple string, which may contain spaces, never a path or a
link
- it is retrieved by reading the "driver"-link and using only the
last element of the target path
- devices which do not have "driver"-link just do not have a
driver; copying the driver value in a child device context is a
bug in the application
- attributes
- the files in the device directory or files below subdirectories
of the same device directory
- accessing attributes reached by a symlink pointing to another device,
like the "device"-link, is a bug in the application
Everything else is just a kernel driver-core implementation detail
that should not be assumed to be stable across kernel releases.
- Properties of parent devices never belong into a child device.
Always look at the parent devices themselves for determining device
context properties. If the device ``eth0`` or ``sda`` does not have a
"driver"-link, then this device does not have a driver. Its value is empty.
Never copy any property of the parent-device into a child-device. Parent
device properties may change dynamically without any notice to the
child device.
- Hierarchy in a single device tree
There is only one valid place in sysfs where hierarchy can be examined
and this is below: ``/sys/devices.``
It is planned that all device directories will end up in the tree
below this directory.
- Classification by subsystem
There are currently three places for classification of devices:
``/sys/block,`` ``/sys/class`` and ``/sys/bus.`` It is planned that these will
not contain any device directories themselves, but only flat lists of
symlinks pointing to the unified ``/sys/devices`` tree.
All three places have completely different rules on how to access
device information. It is planned to merge all three
classification directories into one place at ``/sys/subsystem``,
following the layout of the bus directories. All buses and
classes, including the converted block subsystem, will show up
there.
The devices belonging to a subsystem will create a symlink in the
"devices" directory at ``/sys/subsystem/<name>/devices``,
If ``/sys/subsystem`` exists, ``/sys/bus``, ``/sys/class`` and ``/sys/block``
can be ignored. If it does not exist, you always have to scan all three
places, as the kernel is free to move a subsystem from one place to
the other, as long as the devices are still reachable by the same
subsystem name.
Assuming ``/sys/class/<subsystem>`` and ``/sys/bus/<subsystem>``, or
``/sys/block`` and ``/sys/class/block`` are not interchangeable is a bug in
the application.
- Block
The converted block subsystem at ``/sys/class/block`` or
``/sys/subsystem/block`` will contain the links for disks and partitions
at the same level, never in a hierarchy. Assuming the block subsystem to
contain only disks and not partition devices in the same flat list is
a bug in the application.
- "device"-link and <subsystem>:<kernel name>-links
Never depend on the "device"-link. The "device"-link is a workaround
for the old layout, where class devices are not created in
``/sys/devices/`` like the bus devices. If the link-resolving of a
device directory does not end in ``/sys/devices/``, you can use the
"device"-link to find the parent devices in ``/sys/devices/``, That is the
single valid use of the "device"-link; it must never appear in any
path as an element. Assuming the existence of the "device"-link for
a device in ``/sys/devices/`` is a bug in the application.
Accessing ``/sys/class/net/eth0/device`` is a bug in the application.
Never depend on the class-specific links back to the ``/sys/class``
directory. These links are also a workaround for the design mistake
that class devices are not created in ``/sys/devices.`` If a device
directory does not contain directories for child devices, these links
may be used to find the child devices in ``/sys/class.`` That is the single
valid use of these links; they must never appear in any path as an
element. Assuming the existence of these links for devices which are
real child device directories in the ``/sys/devices`` tree is a bug in
the application.
It is planned to remove all these links when all class device
directories live in ``/sys/devices.``
- Position of devices along device chain can change.
Never depend on a specific parent device position in the devpath,
or the chain of parent devices. The kernel is free to insert devices into
the chain. You must always request the parent device you are looking for
by its subsystem value. You need to walk up the chain until you find
the device that matches the expected subsystem. Depending on a specific
position of a parent device or exposing relative paths using ``../`` to
access the chain of parents is a bug in the application.
- When reading and writing sysfs device attribute files, avoid dependency
on specific error codes wherever possible. This minimizes coupling to
the error handling implementation within the kernel.
In general, failures to read or write sysfs device attributes shall
propagate errors wherever possible. Common errors include, but are not
limited to:
``-EIO``: The read or store operation is not supported, typically
returned by the sysfs system itself if the read or store pointer
is ``NULL``.
``-ENXIO``: The read or store operation failed
Error codes will not be changed without good reason, and should a change
to error codes result in user-space breakage, it will be fixed, or the
the offending change will be reverted.
Userspace applications can, however, expect the format and contents of
the attribute files to remain consistent in the absence of a version
attribute change in the context of a given attribute.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Rules on how to access information in sysfs
1-20kernel이 export하는 sysfs는 내부 kernel 구현 세부 사항을 드러내며 내부 구조와 layout에 의존합니다. Linux kernel은 안정적인 internal API를 제공하지 않기로 합의되어 있으므로 sysfs interface의 일부는 kernel release 사이에서 안정적이지 않을 수 있습니다.
대부분 low-level userspace application인 sysfs 사용자가 새 kernel release에서 고장날 위험을 줄이려면 가능한 한 추상화된 방법으로 filesystem에 접근해야 합니다. 현재 udev와 HAL은 이미 이 원칙을 구현하므로 가능하면 sysfs에 직접 접근하지 말고 이 program들이 제공하는 abstraction에 연결하는 것이 권장됩니다.
직접 접근해야 한다면 아래 규칙을 따라야 미래 sysfs interface에서도 program이 동작할 가능성이 높습니다.
libsysfs를 사용하지 말 것
21-30libsysfs는 사실이 아닌 sysfs 가정을 사용하고, API가 abstraction을 제공하지 않은 채 kernel driver-core 구현 세부 사항을 그대로 노출합니다. 따라서 directory를 직접 읽고 file을 여는 것보다 낫지 않습니다.
현재 kernel development를 반영하는 의미에서 적극적으로 유지보수되지도 않습니다. sysfs에 안정된 interface를 제공한다는 목표는 실패했고 해결하는 문제보다 일으키는 문제가 많으며, 이 문서의 여러 규칙을 위반합니다.
sysfs 위치는 항상 /sys
31-37sysfs는 항상 `/sys`에 있습니다. `/proc/mounts`를 parse하는 것은 낭비이며 다른 mount point는 application이 해결하려 들지 말아야 할 system configuration bug입니다.
test case에서는 application 동작을 override하는 `SYSFS_PATH` environment variable을 지원할 수 있지만 sysfs를 검색해서는 안 됩니다. early boot script가 아니라면 직접 mount하려고도 하지 마십시오.
모든 대상은 단순히 device
38-93userspace가 의존할 수 있는 class device, bus device, physical device, interface 같은 별도 유형은 없습니다. 모두 단순히 device이며 이런 유형 구분은 sysfs에서 device를 찾는 application이 기대해서는 안 되는 kernel 구현 세부 사항입니다.
| 속성 | 규칙 |
|---|---|
| devpath | 예: `/devices/pci0000:00/0000:00:1d.1/usb2/2-2/2-2:1.0`. 생성·제거 event의 `DEVPATH`와 같고 그 시점의 unique key이며, 선행 `/sys` 없이 slash로 시작하는 kernel device directory path |
| kernel name | 예: `sda`, `tty`, `0000:00:1f.2`. devpath 마지막 요소와 같은 directory 이름이며 space와 `!` 같은 문자도 처리해야 함 |
| subsystem | 예: `block`, `tty`, `pci`. path나 link가 아닌 단순 string이며 `subsystem` link target의 마지막 요소만 사용 |
| driver | 예: `tg3`, `ata_piix`, `uhci_hcd`. space를 포함할 수 있는 단순 string이며 `driver` link target의 마지막 요소만 사용 |
| attributes | device directory 안의 file 또는 같은 device directory 아래 subdirectory의 file |
devpath의 모든 요소는 real directory여야 합니다. `/sys/devices`를 가리키는 symlink는 real target으로 resolve하고 그 target path로 device에 접근해야 event 시점의 kernel devpath와 일치합니다. devpath string에 symlink 값을 쓰거나 노출하는 것은 application bug입니다.
`driver` link가 없는 device에는 driver가 없습니다. child device context에 driver 값을 복사하면 안 됩니다. `device` link처럼 다른 device를 가리키는 symlink를 통해 attribute에 접근하는 것도 bug입니다. 그 밖의 내용은 release 사이에서 안정적이라고 가정할 수 없는 driver-core 구현 세부 사항입니다.
parent 속성을 child에 복사하지 말 것
94-101device context 속성은 항상 parent device 자체에서 확인합니다. `eth0`이나 `sda`에 `driver` link가 없으면 그 device에는 driver가 없고 값은 빈 상태입니다. parent 속성은 child에 알리지 않고 동적으로 바뀔 수 있으므로 child에 복사하면 안 됩니다.
단일 device tree의 hierarchy
102-107sysfs에서 hierarchy를 검사할 수 있는 유일하게 유효한 위치는 `/sys/devices.` 아래입니다. 모든 device directory가 이 tree 아래에 위치하도록 할 계획입니다. 실제 경로 표기는 `/sys/devices`입니다.
subsystem별 분류
108-131현재 device 분류 위치는 `/sys/block,`, `/sys/class`, `/sys/bus.` 세 곳입니다. 이들은 자체 device directory 대신 통합 `/sys/devices` tree를 가리키는 flat symlink list만 갖도록 할 계획입니다.
접근 규칙이 서로 다른 세 분류 directory는 bus directory layout을 따르는 `/sys/subsystem` 한 곳으로 합칠 계획입니다. converted block subsystem을 포함한 모든 bus와 class가 나타나고, subsystem 소속 device는 `/sys/subsystem/<name>/devices`의 `devices` directory에 symlink를 만듭니다.
`/sys/subsystem`이 있으면 `/sys/bus`, `/sys/class`, `/sys/block`은 무시할 수 있습니다. 없으면 kernel이 같은 subsystem name으로 접근 가능하게 유지하는 한 위치를 옮길 수 있으므로 세 곳을 모두 scan해야 합니다.
`/sys/class/<subsystem>`과 `/sys/bus/<subsystem>`, 또는 `/sys/block`과 `/sys/class/block`이 서로 바뀔 수 없다고 가정하는 것은 application bug입니다.
Block subsystem
132-138converted block subsystem인 `/sys/class/block` 또는 `/sys/subsystem/block`은 disk와 partition link를 hierarchy 없이 같은 level에 둡니다. flat list에 disk만 있고 partition device는 없다고 가정하면 안 됩니다.
device link와 역방향 class link
139-162`device` link에 의존하지 마십시오. 이는 class device가 bus device처럼 `/sys/devices/`에 만들어지지 않던 old layout의 workaround입니다. device directory를 resolve한 결과가 `/sys/devices/`에서 끝나지 않을 때 parent를 찾는 용도로만 쓸 수 있으며 path 요소로 포함하면 안 됩니다.
`/sys/devices/`의 device에 `device` link가 있다고 가정하거나 `/sys/class/net/eth0/device`에 접근하는 것은 application bug입니다.
`/sys/class`로 돌아가는 class-specific link에도 의존하지 마십시오. 원문은 old design을 `/sys/class.`와 `/sys/devices.`로 표기합니다. child directory가 없는 device에서 child를 찾는 단 한 용도로만 쓸 수 있고 path 요소로 넣으면 안 됩니다. 모든 class device directory가 `/sys/devices`에 살게 되면 이 link들은 제거할 계획입니다.
device chain 위치 변화에 대비할 것
163-171devpath나 parent chain에서 특정 parent 위치에 의존하면 안 됩니다. kernel은 chain 중간에 device를 삽입할 수 있습니다. 원하는 parent를 subsystem 값으로 요청하고 기대한 subsystem과 일치할 때까지 위로 순회해야 합니다.
특정 parent 위치에 의존하거나 `../` 상대 path를 노출해 parent chain에 접근하는 것은 application bug입니다.
attribute I/O와 error 처리
172-192sysfs device attribute file을 읽고 쓸 때 가능한 한 특정 error code 의존을 피해야 kernel 내부 error 처리 구현과의 coupling을 줄일 수 있습니다. 일반적으로 read/write 실패는 가능한 한 error로 전파해야 합니다.
| error | 의미 |
|---|---|
| `-EIO` | read 또는 store operation이 지원되지 않음. 흔히 read/store pointer가 `NULL`일 때 sysfs 자체가 반환 |
| `-ENXIO` | read 또는 store operation 실패 |
타당한 이유 없이 error code를 바꾸지 않으며 변경으로 userspace가 고장나면 수정하거나 문제 변경을 revert합니다. 특정 attribute에 version attribute 변화가 없다면 userspace application은 attribute file의 format과 content가 일관되게 유지될 것을 기대할 수 있습니다.
요약과 해설
sysfs-rules.rst:1-192sysfs consumer의 핵심 규칙은 `/sys/devices`의 real path와 subsystem identity를 기준으로 device를 찾고, 편의를 위한 symlink layout이나 parent chain의 고정 위치를 API처럼 사용하지 않는 것입니다.