Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 77b2555b52a894a2e39a42e43d993df875c46a6a 341 lines 9.9 kB view raw
1 2sysfs - _The_ filesystem for exporting kernel objects. 3 4Patrick Mochel <mochel@osdl.org> 5 610 January 2003 7 8 9What it is: 10~~~~~~~~~~~ 11 12sysfs is a ram-based filesystem initially based on ramfs. It provides 13a means to export kernel data structures, their attributes, and the 14linkages between them to userspace. 15 16sysfs is tied inherently to the kobject infrastructure. Please read 17Documentation/kobject.txt for more information concerning the kobject 18interface. 19 20 21Using sysfs 22~~~~~~~~~~~ 23 24sysfs is always compiled in. You can access it by doing: 25 26 mount -t sysfs sysfs /sys 27 28 29Directory Creation 30~~~~~~~~~~~~~~~~~~ 31 32For every kobject that is registered with the system, a directory is 33created for it in sysfs. That directory is created as a subdirectory 34of the kobject's parent, expressing internal object hierarchies to 35userspace. Top-level directories in sysfs represent the common 36ancestors of object hierarchies; i.e. the subsystems the objects 37belong to. 38 39Sysfs internally stores the kobject that owns the directory in the 40->d_fsdata pointer of the directory's dentry. This allows sysfs to do 41reference counting directly on the kobject when the file is opened and 42closed. 43 44 45Attributes 46~~~~~~~~~~ 47 48Attributes can be exported for kobjects in the form of regular files in 49the filesystem. Sysfs forwards file I/O operations to methods defined 50for the attributes, providing a means to read and write kernel 51attributes. 52 53Attributes should be ASCII text files, preferably with only one value 54per file. It is noted that it may not be efficient to contain only 55value per file, so it is socially acceptable to express an array of 56values of the same type. 57 58Mixing types, expressing multiple lines of data, and doing fancy 59formatting of data is heavily frowned upon. Doing these things may get 60you publically humiliated and your code rewritten without notice. 61 62 63An attribute definition is simply: 64 65struct attribute { 66 char * name; 67 mode_t mode; 68}; 69 70 71int sysfs_create_file(struct kobject * kobj, struct attribute * attr); 72void sysfs_remove_file(struct kobject * kobj, struct attribute * attr); 73 74 75A bare attribute contains no means to read or write the value of the 76attribute. Subsystems are encouraged to define their own attribute 77structure and wrapper functions for adding and removing attributes for 78a specific object type. 79 80For example, the driver model defines struct device_attribute like: 81 82struct device_attribute { 83 struct attribute attr; 84 ssize_t (*show)(struct device * dev, char * buf); 85 ssize_t (*store)(struct device * dev, const char * buf); 86}; 87 88int device_create_file(struct device *, struct device_attribute *); 89void device_remove_file(struct device *, struct device_attribute *); 90 91It also defines this helper for defining device attributes: 92 93#define DEVICE_ATTR(_name, _mode, _show, _store) \ 94struct device_attribute dev_attr_##_name = { \ 95 .attr = {.name = __stringify(_name) , .mode = _mode }, \ 96 .show = _show, \ 97 .store = _store, \ 98}; 99 100For example, declaring 101 102static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo); 103 104is equivalent to doing: 105 106static struct device_attribute dev_attr_foo = { 107 .attr = { 108 .name = "foo", 109 .mode = S_IWUSR | S_IRUGO, 110 }, 111 .show = show_foo, 112 .store = store_foo, 113}; 114 115 116Subsystem-Specific Callbacks 117~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 118 119When a subsystem defines a new attribute type, it must implement a 120set of sysfs operations for forwarding read and write calls to the 121show and store methods of the attribute owners. 122 123struct sysfs_ops { 124 ssize_t (*show)(struct kobject *, struct attribute *, char *); 125 ssize_t (*store)(struct kobject *, struct attribute *, const char *); 126}; 127 128[ Subsystems should have already defined a struct kobj_type as a 129descriptor for this type, which is where the sysfs_ops pointer is 130stored. See the kobject documentation for more information. ] 131 132When a file is read or written, sysfs calls the appropriate method 133for the type. The method then translates the generic struct kobject 134and struct attribute pointers to the appropriate pointer types, and 135calls the associated methods. 136 137 138To illustrate: 139 140#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 141#define to_dev(d) container_of(d, struct device, kobj) 142 143static ssize_t 144dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) 145{ 146 struct device_attribute * dev_attr = to_dev_attr(attr); 147 struct device * dev = to_dev(kobj); 148 ssize_t ret = 0; 149 150 if (dev_attr->show) 151 ret = dev_attr->show(dev, buf); 152 return ret; 153} 154 155 156 157Reading/Writing Attribute Data 158~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 159 160To read or write attributes, show() or store() methods must be 161specified when declaring the attribute. The method types should be as 162simple as those defined for device attributes: 163 164 ssize_t (*show)(struct device * dev, char * buf); 165 ssize_t (*store)(struct device * dev, const char * buf); 166 167IOW, they should take only an object and a buffer as parameters. 168 169 170sysfs allocates a buffer of size (PAGE_SIZE) and passes it to the 171method. Sysfs will call the method exactly once for each read or 172write. This forces the following behavior on the method 173implementations: 174 175- On read(2), the show() method should fill the entire buffer. 176 Recall that an attribute should only be exporting one value, or an 177 array of similar values, so this shouldn't be that expensive. 178 179 This allows userspace to do partial reads and seeks arbitrarily over 180 the entire file at will. 181 182- On write(2), sysfs expects the entire buffer to be passed during the 183 first write. Sysfs then passes the entire buffer to the store() 184 method. 185 186 When writing sysfs files, userspace processes should first read the 187 entire file, modify the values it wishes to change, then write the 188 entire buffer back. 189 190 Attribute method implementations should operate on an identical 191 buffer when reading and writing values. 192 193Other notes: 194 195- The buffer will always be PAGE_SIZE bytes in length. On i386, this 196 is 4096. 197 198- show() methods should return the number of bytes printed into the 199 buffer. This is the return value of snprintf(). 200 201- show() should always use snprintf(). 202 203- store() should return the number of bytes used from the buffer. This 204 can be done using strlen(). 205 206- show() or store() can always return errors. If a bad value comes 207 through, be sure to return an error. 208 209- The object passed to the methods will be pinned in memory via sysfs 210 referencing counting its embedded object. However, the physical 211 entity (e.g. device) the object represents may not be present. Be 212 sure to have a way to check this, if necessary. 213 214 215A very simple (and naive) implementation of a device attribute is: 216 217static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) 218{ 219 return snprintf(buf, PAGE_SIZE, "%s\n", dev->name); 220} 221 222static ssize_t store_name(struct device * dev, const char * buf) 223{ 224 sscanf(buf, "%20s", dev->name); 225 return strnlen(buf, PAGE_SIZE); 226} 227 228static DEVICE_ATTR(name, S_IRUGO, show_name, store_name); 229 230 231(Note that the real implementation doesn't allow userspace to set the 232name for a device.) 233 234 235Top Level Directory Layout 236~~~~~~~~~~~~~~~~~~~~~~~~~~ 237 238The sysfs directory arrangement exposes the relationship of kernel 239data structures. 240 241The top level sysfs diretory looks like: 242 243block/ 244bus/ 245class/ 246devices/ 247firmware/ 248net/ 249 250devices/ contains a filesystem representation of the device tree. It maps 251directly to the internal kernel device tree, which is a hierarchy of 252struct device. 253 254bus/ contains flat directory layout of the various bus types in the 255kernel. Each bus's directory contains two subdirectories: 256 257 devices/ 258 drivers/ 259 260devices/ contains symlinks for each device discovered in the system 261that point to the device's directory under root/. 262 263drivers/ contains a directory for each device driver that is loaded 264for devices on that particular bus (this assumes that drivers do not 265span multiple bus types). 266 267 268More information can driver-model specific features can be found in 269Documentation/driver-model/. 270 271 272TODO: Finish this section. 273 274 275Current Interfaces 276~~~~~~~~~~~~~~~~~~ 277 278The following interface layers currently exist in sysfs: 279 280 281- devices (include/linux/device.h) 282---------------------------------- 283Structure: 284 285struct device_attribute { 286 struct attribute attr; 287 ssize_t (*show)(struct device * dev, char * buf); 288 ssize_t (*store)(struct device * dev, const char * buf); 289}; 290 291Declaring: 292 293DEVICE_ATTR(_name, _str, _mode, _show, _store); 294 295Creation/Removal: 296 297int device_create_file(struct device *device, struct device_attribute * attr); 298void device_remove_file(struct device * dev, struct device_attribute * attr); 299 300 301- bus drivers (include/linux/device.h) 302-------------------------------------- 303Structure: 304 305struct bus_attribute { 306 struct attribute attr; 307 ssize_t (*show)(struct bus_type *, char * buf); 308 ssize_t (*store)(struct bus_type *, const char * buf); 309}; 310 311Declaring: 312 313BUS_ATTR(_name, _mode, _show, _store) 314 315Creation/Removal: 316 317int bus_create_file(struct bus_type *, struct bus_attribute *); 318void bus_remove_file(struct bus_type *, struct bus_attribute *); 319 320 321- device drivers (include/linux/device.h) 322----------------------------------------- 323 324Structure: 325 326struct driver_attribute { 327 struct attribute attr; 328 ssize_t (*show)(struct device_driver *, char * buf); 329 ssize_t (*store)(struct device_driver *, const char * buf); 330}; 331 332Declaring: 333 334DRIVER_ATTR(_name, _mode, _show, _store) 335 336Creation/Removal: 337 338int driver_create_file(struct device_driver *, struct driver_attribute *); 339void driver_remove_file(struct device_driver *, struct driver_attribute *); 340 341