18c2ecf20Sopenharmony_ciRules on how to access information in sysfs 28c2ecf20Sopenharmony_ci=========================================== 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ciThe kernel-exported sysfs exports internal kernel implementation details 58c2ecf20Sopenharmony_ciand depends on internal kernel structures and layout. It is agreed upon 68c2ecf20Sopenharmony_ciby the kernel developers that the Linux kernel does not provide a stable 78c2ecf20Sopenharmony_ciinternal API. Therefore, there are aspects of the sysfs interface that 88c2ecf20Sopenharmony_cimay not be stable across kernel releases. 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ciTo minimize the risk of breaking users of sysfs, which are in most cases 118c2ecf20Sopenharmony_cilow-level userspace applications, with a new kernel release, the users 128c2ecf20Sopenharmony_ciof sysfs must follow some rules to use an as-abstract-as-possible way to 138c2ecf20Sopenharmony_ciaccess this filesystem. The current udev and HAL programs already 148c2ecf20Sopenharmony_ciimplement this and users are encouraged to plug, if possible, into the 158c2ecf20Sopenharmony_ciabstractions these programs provide instead of accessing sysfs directly. 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ciBut if you really do want or need to access sysfs directly, please follow 188c2ecf20Sopenharmony_cithe following rules and then your programs should work with future 198c2ecf20Sopenharmony_civersions of the sysfs interface. 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci- Do not use libsysfs 228c2ecf20Sopenharmony_ci It makes assumptions about sysfs which are not true. Its API does not 238c2ecf20Sopenharmony_ci offer any abstraction, it exposes all the kernel driver-core 248c2ecf20Sopenharmony_ci implementation details in its own API. Therefore it is not better than 258c2ecf20Sopenharmony_ci reading directories and opening the files yourself. 268c2ecf20Sopenharmony_ci Also, it is not actively maintained, in the sense of reflecting the 278c2ecf20Sopenharmony_ci current kernel development. The goal of providing a stable interface 288c2ecf20Sopenharmony_ci to sysfs has failed; it causes more problems than it solves. It 298c2ecf20Sopenharmony_ci violates many of the rules in this document. 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci- sysfs is always at ``/sys`` 328c2ecf20Sopenharmony_ci Parsing ``/proc/mounts`` is a waste of time. Other mount points are a 338c2ecf20Sopenharmony_ci system configuration bug you should not try to solve. For test cases, 348c2ecf20Sopenharmony_ci possibly support a ``SYSFS_PATH`` environment variable to overwrite the 358c2ecf20Sopenharmony_ci application's behavior, but never try to search for sysfs. Never try 368c2ecf20Sopenharmony_ci to mount it, if you are not an early boot script. 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci- devices are only "devices" 398c2ecf20Sopenharmony_ci There is no such thing like class-, bus-, physical devices, 408c2ecf20Sopenharmony_ci interfaces, and such that you can rely on in userspace. Everything is 418c2ecf20Sopenharmony_ci just simply a "device". Class-, bus-, physical, ... types are just 428c2ecf20Sopenharmony_ci kernel implementation details which should not be expected by 438c2ecf20Sopenharmony_ci applications that look for devices in sysfs. 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci The properties of a device are: 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci - devpath (``/devices/pci0000:00/0000:00:1d.1/usb2/2-2/2-2:1.0``) 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci - identical to the DEVPATH value in the event sent from the kernel 508c2ecf20Sopenharmony_ci at device creation and removal 518c2ecf20Sopenharmony_ci - the unique key to the device at that point in time 528c2ecf20Sopenharmony_ci - the kernel's path to the device directory without the leading 538c2ecf20Sopenharmony_ci ``/sys``, and always starting with a slash 548c2ecf20Sopenharmony_ci - all elements of a devpath must be real directories. Symlinks 558c2ecf20Sopenharmony_ci pointing to /sys/devices must always be resolved to their real 568c2ecf20Sopenharmony_ci target and the target path must be used to access the device. 578c2ecf20Sopenharmony_ci That way the devpath to the device matches the devpath of the 588c2ecf20Sopenharmony_ci kernel used at event time. 598c2ecf20Sopenharmony_ci - using or exposing symlink values as elements in a devpath string 608c2ecf20Sopenharmony_ci is a bug in the application 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci - kernel name (``sda``, ``tty``, ``0000:00:1f.2``, ...) 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci - a directory name, identical to the last element of the devpath 658c2ecf20Sopenharmony_ci - applications need to handle spaces and characters like ``!`` in 668c2ecf20Sopenharmony_ci the name 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci - subsystem (``block``, ``tty``, ``pci``, ...) 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci - simple string, never a path or a link 718c2ecf20Sopenharmony_ci - retrieved by reading the "subsystem"-link and using only the 728c2ecf20Sopenharmony_ci last element of the target path 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci - driver (``tg3``, ``ata_piix``, ``uhci_hcd``) 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci - a simple string, which may contain spaces, never a path or a 778c2ecf20Sopenharmony_ci link 788c2ecf20Sopenharmony_ci - it is retrieved by reading the "driver"-link and using only the 798c2ecf20Sopenharmony_ci last element of the target path 808c2ecf20Sopenharmony_ci - devices which do not have "driver"-link just do not have a 818c2ecf20Sopenharmony_ci driver; copying the driver value in a child device context is a 828c2ecf20Sopenharmony_ci bug in the application 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci - attributes 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci - the files in the device directory or files below subdirectories 878c2ecf20Sopenharmony_ci of the same device directory 888c2ecf20Sopenharmony_ci - accessing attributes reached by a symlink pointing to another device, 898c2ecf20Sopenharmony_ci like the "device"-link, is a bug in the application 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci Everything else is just a kernel driver-core implementation detail 928c2ecf20Sopenharmony_ci that should not be assumed to be stable across kernel releases. 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci- Properties of parent devices never belong into a child device. 958c2ecf20Sopenharmony_ci Always look at the parent devices themselves for determining device 968c2ecf20Sopenharmony_ci context properties. If the device ``eth0`` or ``sda`` does not have a 978c2ecf20Sopenharmony_ci "driver"-link, then this device does not have a driver. Its value is empty. 988c2ecf20Sopenharmony_ci Never copy any property of the parent-device into a child-device. Parent 998c2ecf20Sopenharmony_ci device properties may change dynamically without any notice to the 1008c2ecf20Sopenharmony_ci child device. 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci- Hierarchy in a single device tree 1038c2ecf20Sopenharmony_ci There is only one valid place in sysfs where hierarchy can be examined 1048c2ecf20Sopenharmony_ci and this is below: ``/sys/devices.`` 1058c2ecf20Sopenharmony_ci It is planned that all device directories will end up in the tree 1068c2ecf20Sopenharmony_ci below this directory. 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci- Classification by subsystem 1098c2ecf20Sopenharmony_ci There are currently three places for classification of devices: 1108c2ecf20Sopenharmony_ci ``/sys/block,`` ``/sys/class`` and ``/sys/bus.`` It is planned that these will 1118c2ecf20Sopenharmony_ci not contain any device directories themselves, but only flat lists of 1128c2ecf20Sopenharmony_ci symlinks pointing to the unified ``/sys/devices`` tree. 1138c2ecf20Sopenharmony_ci All three places have completely different rules on how to access 1148c2ecf20Sopenharmony_ci device information. It is planned to merge all three 1158c2ecf20Sopenharmony_ci classification directories into one place at ``/sys/subsystem``, 1168c2ecf20Sopenharmony_ci following the layout of the bus directories. All buses and 1178c2ecf20Sopenharmony_ci classes, including the converted block subsystem, will show up 1188c2ecf20Sopenharmony_ci there. 1198c2ecf20Sopenharmony_ci The devices belonging to a subsystem will create a symlink in the 1208c2ecf20Sopenharmony_ci "devices" directory at ``/sys/subsystem/<name>/devices``, 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci If ``/sys/subsystem`` exists, ``/sys/bus``, ``/sys/class`` and ``/sys/block`` 1238c2ecf20Sopenharmony_ci can be ignored. If it does not exist, you always have to scan all three 1248c2ecf20Sopenharmony_ci places, as the kernel is free to move a subsystem from one place to 1258c2ecf20Sopenharmony_ci the other, as long as the devices are still reachable by the same 1268c2ecf20Sopenharmony_ci subsystem name. 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci Assuming ``/sys/class/<subsystem>`` and ``/sys/bus/<subsystem>``, or 1298c2ecf20Sopenharmony_ci ``/sys/block`` and ``/sys/class/block`` are not interchangeable is a bug in 1308c2ecf20Sopenharmony_ci the application. 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci- Block 1338c2ecf20Sopenharmony_ci The converted block subsystem at ``/sys/class/block`` or 1348c2ecf20Sopenharmony_ci ``/sys/subsystem/block`` will contain the links for disks and partitions 1358c2ecf20Sopenharmony_ci at the same level, never in a hierarchy. Assuming the block subsystem to 1368c2ecf20Sopenharmony_ci contain only disks and not partition devices in the same flat list is 1378c2ecf20Sopenharmony_ci a bug in the application. 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci- "device"-link and <subsystem>:<kernel name>-links 1408c2ecf20Sopenharmony_ci Never depend on the "device"-link. The "device"-link is a workaround 1418c2ecf20Sopenharmony_ci for the old layout, where class devices are not created in 1428c2ecf20Sopenharmony_ci ``/sys/devices/`` like the bus devices. If the link-resolving of a 1438c2ecf20Sopenharmony_ci device directory does not end in ``/sys/devices/``, you can use the 1448c2ecf20Sopenharmony_ci "device"-link to find the parent devices in ``/sys/devices/``, That is the 1458c2ecf20Sopenharmony_ci single valid use of the "device"-link; it must never appear in any 1468c2ecf20Sopenharmony_ci path as an element. Assuming the existence of the "device"-link for 1478c2ecf20Sopenharmony_ci a device in ``/sys/devices/`` is a bug in the application. 1488c2ecf20Sopenharmony_ci Accessing ``/sys/class/net/eth0/device`` is a bug in the application. 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci Never depend on the class-specific links back to the ``/sys/class`` 1518c2ecf20Sopenharmony_ci directory. These links are also a workaround for the design mistake 1528c2ecf20Sopenharmony_ci that class devices are not created in ``/sys/devices.`` If a device 1538c2ecf20Sopenharmony_ci directory does not contain directories for child devices, these links 1548c2ecf20Sopenharmony_ci may be used to find the child devices in ``/sys/class.`` That is the single 1558c2ecf20Sopenharmony_ci valid use of these links; they must never appear in any path as an 1568c2ecf20Sopenharmony_ci element. Assuming the existence of these links for devices which are 1578c2ecf20Sopenharmony_ci real child device directories in the ``/sys/devices`` tree is a bug in 1588c2ecf20Sopenharmony_ci the application. 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci It is planned to remove all these links when all class device 1618c2ecf20Sopenharmony_ci directories live in ``/sys/devices.`` 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci- Position of devices along device chain can change. 1648c2ecf20Sopenharmony_ci Never depend on a specific parent device position in the devpath, 1658c2ecf20Sopenharmony_ci or the chain of parent devices. The kernel is free to insert devices into 1668c2ecf20Sopenharmony_ci the chain. You must always request the parent device you are looking for 1678c2ecf20Sopenharmony_ci by its subsystem value. You need to walk up the chain until you find 1688c2ecf20Sopenharmony_ci the device that matches the expected subsystem. Depending on a specific 1698c2ecf20Sopenharmony_ci position of a parent device or exposing relative paths using ``../`` to 1708c2ecf20Sopenharmony_ci access the chain of parents is a bug in the application. 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci- When reading and writing sysfs device attribute files, avoid dependency 1738c2ecf20Sopenharmony_ci on specific error codes wherever possible. This minimizes coupling to 1748c2ecf20Sopenharmony_ci the error handling implementation within the kernel. 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci In general, failures to read or write sysfs device attributes shall 1778c2ecf20Sopenharmony_ci propagate errors wherever possible. Common errors include, but are not 1788c2ecf20Sopenharmony_ci limited to: 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci ``-EIO``: The read or store operation is not supported, typically 1818c2ecf20Sopenharmony_ci returned by the sysfs system itself if the read or store pointer 1828c2ecf20Sopenharmony_ci is ``NULL``. 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci ``-ENXIO``: The read or store operation failed 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci Error codes will not be changed without good reason, and should a change 1878c2ecf20Sopenharmony_ci to error codes result in user-space breakage, it will be fixed, or the 1888c2ecf20Sopenharmony_ci the offending change will be reverted. 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci Userspace applications can, however, expect the format and contents of 1918c2ecf20Sopenharmony_ci the attribute files to remain consistent in the absence of a version 1928c2ecf20Sopenharmony_ci attribute change in the context of a given attribute. 193