If you are building a free embedded systems course study plan or working through a free Linux device drivers course, sysfs is one interface you cannot skip. This lesson explains the sysfs one value per file rule in plain language, why the kernel community enforces it, and how attribute files are written correctly on a modern 6.x kernel.
What You Will Learn
- What sysfs is and why it exists
- The sysfs one value per file rule explained
- Why the rule exists (ABI stability reasons)
- Modern sysfs_emit() usage on kernel 6.x
- Good vs bad attribute design
- Common mistakes driver authors make
Prerequisites
Before starting this free Linux kernel development course lesson, you should already know:
- Basic C programming
- How to build and load a kernel module
- Basic idea of what a kobject is
What Is Sysfs?
Sysfs is a virtual, in-memory filesystem that the Linux kernel exposes at /sys. It lets kernel objects (devices, drivers, subsystems) publish their properties to user space as ordinary files. A user space program simply reads or writes a file under /sys instead of calling a special system call.
cat / echo on /sys file
show() / store()
The Sysfs One Value Per File Rule
The kernel documentation is strict about one thing: each sysfs attribute file must represent exactly one value. A file should not hold a comma-separated list, a multi-line dump, or a mix of unrelated fields.
| Correct Design | Incorrect Design |
|---|---|
/sys/class/hwmon/hwmon0/temp1_input returns just the temperature |
One file returning “temp=42,humidity=60,pressure=1013” |
Separate files: speed, direction, enabled |
One file dumping an entire driver context structure |
Because of this rule, sysfs is excellent for reporting sensor readings, toggles, and simple settings — but it is a poor fit for verbose debugging output. That limitation is exactly why the kernel offers a second, more relaxed interface: debugfs, which we cover in the next lesson.
Why Does This Rule Exist?
Sysfs is treated as a stable user space ABI. If a file mixed multiple values together, any change to that internal format would silently break scripts and tools that parse it. Keeping one value per file means each attribute can evolve independently, and existing consumers of other attributes are never affected.
Each attribute is an independent ABI contract
Scripts can read a value with a single
catNo parsing logic required in user space
Writing Sysfs Attributes on a Modern 6.x Kernel
Older code (and older books) commonly used snprintf() inside a sysfs show() callback. On current kernels this is discouraged. The recommended helper today is sysfs_emit(), introduced to guarantee the output never exceeds the fixed PAGE_SIZE buffer that sysfs hands to a show callback, and to catch a class of bugs that plagued the old snprintf-based pattern.
#include <linux/sysfs.h>
#include <linux/mutex.h>
static unsigned int demo_value;
static DEFINE_MUTEX(demo_mtx);
static ssize_t demo_value_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
unsigned int val;
mutex_lock(&demo_mtx);
val = demo_value;
mutex_unlock(&demo_mtx);
/* sysfs_emit() is the modern, safe replacement for snprintf() here */
return sysfs_emit(buf, "%u\n", val);
}
static ssize_t demo_value_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned int val;
if (kstrtouint(buf, 10, &val))
return -EINVAL;
mutex_lock(&demo_mtx);
demo_value = val;
mutex_unlock(&demo_mtx);
return count;
}
static DEVICE_ATTR_RW(demo_value);
Notice how this single attribute exposes exactly one value: demo_value. If you needed to expose a second property, the correct approach is to add a second DEVICE_ATTR and a second file — never to pack both values into one buffer.
Common Mistakes With Sysfs Attributes
- Returning multiple fields in one show() callback
- Using sysfs for large or free-form debug dumps
- Forgetting to guard shared state with a mutex
- Not validating input in store() before applying it
- Using raw snprintf() instead of sysfs_emit() on new code
Best Practices for Sysfs Attribute Design
- One attribute file per logical value
- Prefer sysfs_emit() / sysfs_emit_at() over snprintf()
- Always take a lock around shared driver state
- Keep attribute names short and self-descriptive
- Use debugfs instead when you need rich, multi-field output
Security Considerations
Sysfs files are reachable by any process with the right file permissions, so a store() callback must never trust its input blindly. Always validate the parsed value’s range, and never use a sysfs attribute to accept a raw pointer, buffer length, or anything that could be used to influence kernel memory operations without strict bounds checking.
Summary / Key Takeaways
- Sysfs exposes kernel object properties as files under /sys
- Each file must hold exactly one value — the core ABI rule
- The rule keeps sysfs simple, stable, and script-friendly
- Use sysfs_emit() instead of snprintf() on modern kernels
- For rich debug output, use debugfs instead of sysfs
Frequently Asked Questions
Q1. What is the sysfs one value per file rule?
It is the kernel convention that every sysfs attribute file must expose exactly one value, keeping the interface simple and stable.
Q2. Why can’t I return multiple values from one sysfs file?
Because sysfs is treated as a stable user space ABI, and mixing values in one file breaks that stability whenever the format changes.
Q3. Should I use snprintf() or sysfs_emit() in a show() callback?
On modern kernels, use sysfs_emit(), which is designed specifically for the fixed PAGE_SIZE buffer sysfs provides.
Q4. What should I use if I need to dump a whole structure for debugging?
Use debugfs, which has no one-value-per-file restriction and is meant for debug-only interfaces.
Q5. Is sysfs still relevant on modern Linux kernels?
Yes. Sysfs remains the standard way to expose stable device and driver attributes to user space on all current kernel versions.
Q6. Do I need a mutex in my sysfs show/store callbacks?
Yes, whenever the callback reads or writes shared driver state, to avoid race conditions between concurrent user space accesses.
Conclusion
The sysfs one value per file rule looks like a small detail, but it is the reason sysfs has stayed a dependable, stable interface for over two decades of kernel development. As you continue this free Linux kernel programming course, keep this rule in mind every time you design a new device attribute — and remember that debugfs is there for the cases sysfs was never meant to handle.
More lessons on device drivers, kernel synchronization, and embedded Linux are coming up on EmbeddedPathashala.

2 Comments