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 v2.6.29-rc4 357 lines 11 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 one 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 forward seeks 180 arbitrarily over the entire file at will. If userspace seeks back to 181 zero or does a pread(2) with an offset of '0' the show() method will 182 be called again, rearmed, to fill the buffer. 183 184- On write(2), sysfs expects the entire buffer to be passed during the 185 first write. Sysfs then passes the entire buffer to the store() 186 method. 187 188 When writing sysfs files, userspace processes should first read the 189 entire file, modify the values it wishes to change, then write the 190 entire buffer back. 191 192 Attribute method implementations should operate on an identical 193 buffer when reading and writing values. 194 195Other notes: 196 197- Writing causes the show() method to be rearmed regardless of current 198 file position. 199 200- The buffer will always be PAGE_SIZE bytes in length. On i386, this 201 is 4096. 202 203- show() methods should return the number of bytes printed into the 204 buffer. This is the return value of snprintf(). 205 206- show() should always use snprintf(). 207 208- store() should return the number of bytes used from the buffer. This 209 can be done using strlen(). 210 211- show() or store() can always return errors. If a bad value comes 212 through, be sure to return an error. 213 214- The object passed to the methods will be pinned in memory via sysfs 215 referencing counting its embedded object. However, the physical 216 entity (e.g. device) the object represents may not be present. Be 217 sure to have a way to check this, if necessary. 218 219 220A very simple (and naive) implementation of a device attribute is: 221 222static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) 223{ 224 return snprintf(buf, PAGE_SIZE, "%s\n", dev->name); 225} 226 227static ssize_t store_name(struct device * dev, const char * buf) 228{ 229 sscanf(buf, "%20s", dev->name); 230 return strnlen(buf, PAGE_SIZE); 231} 232 233static DEVICE_ATTR(name, S_IRUGO, show_name, store_name); 234 235 236(Note that the real implementation doesn't allow userspace to set the 237name for a device.) 238 239 240Top Level Directory Layout 241~~~~~~~~~~~~~~~~~~~~~~~~~~ 242 243The sysfs directory arrangement exposes the relationship of kernel 244data structures. 245 246The top level sysfs directory looks like: 247 248block/ 249bus/ 250class/ 251dev/ 252devices/ 253firmware/ 254net/ 255fs/ 256 257devices/ contains a filesystem representation of the device tree. It maps 258directly to the internal kernel device tree, which is a hierarchy of 259struct device. 260 261bus/ contains flat directory layout of the various bus types in the 262kernel. Each bus's directory contains two subdirectories: 263 264 devices/ 265 drivers/ 266 267devices/ contains symlinks for each device discovered in the system 268that point to the device's directory under root/. 269 270drivers/ contains a directory for each device driver that is loaded 271for devices on that particular bus (this assumes that drivers do not 272span multiple bus types). 273 274fs/ contains a directory for some filesystems. Currently each 275filesystem wanting to export attributes must create its own hierarchy 276below fs/ (see ./fuse.txt for an example). 277 278dev/ contains two directories char/ and block/. Inside these two 279directories there are symlinks named <major>:<minor>. These symlinks 280point to the sysfs directory for the given device. /sys/dev provides a 281quick way to lookup the sysfs interface for a device from the result of 282a stat(2) operation. 283 284More information can driver-model specific features can be found in 285Documentation/driver-model/. 286 287 288TODO: Finish this section. 289 290 291Current Interfaces 292~~~~~~~~~~~~~~~~~~ 293 294The following interface layers currently exist in sysfs: 295 296 297- devices (include/linux/device.h) 298---------------------------------- 299Structure: 300 301struct device_attribute { 302 struct attribute attr; 303 ssize_t (*show)(struct device * dev, char * buf); 304 ssize_t (*store)(struct device * dev, const char * buf); 305}; 306 307Declaring: 308 309DEVICE_ATTR(_name, _str, _mode, _show, _store); 310 311Creation/Removal: 312 313int device_create_file(struct device *device, struct device_attribute * attr); 314void device_remove_file(struct device * dev, struct device_attribute * attr); 315 316 317- bus drivers (include/linux/device.h) 318-------------------------------------- 319Structure: 320 321struct bus_attribute { 322 struct attribute attr; 323 ssize_t (*show)(struct bus_type *, char * buf); 324 ssize_t (*store)(struct bus_type *, const char * buf); 325}; 326 327Declaring: 328 329BUS_ATTR(_name, _mode, _show, _store) 330 331Creation/Removal: 332 333int bus_create_file(struct bus_type *, struct bus_attribute *); 334void bus_remove_file(struct bus_type *, struct bus_attribute *); 335 336 337- device drivers (include/linux/device.h) 338----------------------------------------- 339 340Structure: 341 342struct driver_attribute { 343 struct attribute attr; 344 ssize_t (*show)(struct device_driver *, char * buf); 345 ssize_t (*store)(struct device_driver *, const char * buf); 346}; 347 348Declaring: 349 350DRIVER_ATTR(_name, _mode, _show, _store) 351 352Creation/Removal: 353 354int driver_create_file(struct device_driver *, struct driver_attribute *); 355void driver_remove_file(struct device_driver *, struct driver_attribute *); 356 357