aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/filesystems/sysfs.txt
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /Documentation/filesystems/sysfs.txt
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'Documentation/filesystems/sysfs.txt')
-rw-r--r--Documentation/filesystems/sysfs.txt341
1 files changed, 341 insertions, 0 deletions
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
new file mode 100644
index 000000000000..60f6c2c4d477
--- /dev/null
+++ b/Documentation/filesystems/sysfs.txt
@@ -0,0 +1,341 @@
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,0644,show_foo,store_foo);
103
104is equivalent to doing:
105
106static struct device_attribute dev_attr_foo = {
107 .attr = {
108 .name = "foo",
109 .mode = 0644,
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, char * buf)
218{
219 return sprintf(buf,"%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 strlen(buf);
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