The Wayback Machine - https://web.archive.org/web/20100201234857/http://kerneltrap.org:80/node/4394

Linux: DebugFS

Submitted by Jeremy
on December 11, 2004 - 7:40pm

Greg Kroah-Hartman announced the creation of debugfs, an in-kernel filesystem designed to help kernel developers easily export debug data to userspace. (Greg's debugfs has nothing to do with the ext2 file system debugger of the same name.) He offered a little background information on the idea, "a while ago a comment from another kernel developer about why they put a huge file in sysfs (one that was bigger than a single page and contained more than just 1 type of information), was something like, 'well, it was just so easy, and there was no other place to put debugging stuff like that,' got me to thinking." He went on to summarize, "debugfs is meant for putting stuff that kernel developers need to see exported to userspace, yet don't always want hanging around."

Along with the patch which applies against 2.6.10-rc3 [story], Greg offered a few examples to show how easy debugfs is to use. For example, to export a single value to userspace, he gave this example: struct dentry *debugfs_create_u8(const char *name, mode_t mode, struct dentry *parent, u8 *value); "That's it, one line of code and you have a variable that can be read and written to from userspace." As a further example, he provided a patch for the USB uhci driver converting it from using /proc/driver/uhci to using debugfs, reducing the driver's overall size. Greg noted the patch needs a little more cleanup, but that it is fully functional and ready for feedback.


From: Greg KH [email blocked]
To:  linux-kernel, [email blocked]
Subject: [RFC PATCH] debugfs - yet another in-kernel file system
Date: 	Thu, 9 Dec 2004 16:50:56 -0800

A while ago a comment from another kernel developer about why they put a
huge file in sysfs (one that was bigger than a single page and contained
more than just 1 type of information), was something like, "well, it was
just so easy, and there was no other place to put debugging stuff like
that," got me to thinking.

What if there was a in-kernel filesystem that was explicitly just for
putting debugging stuff?  Some place other than proc and sysfs, and that
was easier than both of them to use.  Yet it needed to also be able to
handle complex stuff like seq file and raw file_ops if needed.

Thus debugfs was born (yes, I know there's a userspace program called
debugfs, this is an in-kernel filesystem and has nothing to do with
that.)  debugfs is meant for putting stuff that kernel developers need to
see exported to userspace, yet don't always want hanging around.

To create a file using debugfs the call is just:
  struct dentry *debugfs_create_file(const char *name, mode_t mode,
			             struct dentry *parent, void *data,
				     struct file_operations *fops);

If that looks too complex for you, and you just want to export a single
value to userspace, how about:
  struct dentry *debugfs_create_u8(const char *name, mode_t mode, struct dentry *parent, u8 *value);

That's it, one line of code and you have a variable that can be read and
written to from userspace.  Dave Hansen, you can stop complaining about
complexity right now :)

And if you want to create a directory to put all of your stuff in (which
is a good idea, as no one is going to even try to manage the debugfs
namespace):
  struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)

That will give you a dentry to use in the other debugfs functions.

So, here's a patch against 2.6.10-rc3 (it will probably apply cleanly
against 2.6.9, but I haven't tried it.)  It still needs a bit more
cleanup (it shouldn't be a module and the init level needs to be bumped
up if core kernel code uses it) but it works and I'm asking for comments
about it.

Do we want more simple types of files?  A "string" type isn't really
needed as it's only about 3 lines of code to create your own "read"
function these days.

And I'll follow this patch up with a patch for the USB uhci driver that
converts from using /proc/driver/uhci to use debugfs, which makes that
driver smaller.

thanks,

greg k-h

p.s. I think the recently posted infiband driver can take advantage of
this fs instead of having to create it's own debug filesystem.


-------------------

[patch]


From: Greg KH [email blocked] To: linux-kernel, [email blocked] Subject: [RFC PATCH] convert uhci-hcd to use debugfs Date: Thu, 9 Dec 2004 16:55:14 -0800 And here's the uhci-hcd patch. Signed-off-by: Greg Kroah-Hartman [email blocked] thanks, greg k-h ----------------- [patch]
From: Jörn Engel [email blocked] Subject: Re: [RFC PATCH] debugfs - yet another in-kernel file system Date: Fri, 10 Dec 2004 18:21:26 +0100 Two-word summary: cool stuff! Thanks! On Thu, 9 December 2004 16:50:56 -0800, Greg KH wrote: > > Thus debugfs was born (yes, I know there's a userspace program called > debugfs, this is an in-kernel filesystem and has nothing to do with > that.) debugfs is ment for putting stuff that kernel developers need to > see exported to userspace, yet don't always want hanging around. In principle, it is the same as /proc, just with the explicit information that binary compatibility will never be a goal, right? Details differ, sure. > diff -Nru a/fs/debugfs/debugfs_test.c b/fs/debugfs/debugfs_test.c Nice example code. But I'd vote for either killing it or renaming it to debugfs_example.c. Just to document that anyone actually compiling it in is stupid. > +static ssize_t default_read_file(struct file *file, char __user *user_buf, > + size_t count, loff_t *ppos) For a similar reason, I'd call this example_read_file(). You actually fooled me for a moment and I was wondering why the heck this should be part of debugfs. ;) > +#define simple_type(type, format, temptype, strtolfn) \ > +static ssize_t read_file_##type(struct file *file, > char __user *user_buf, size_t count, loff_t *ppos) \ Long lines. Taste varies, but... > +{ \ > + char buf[32]; \ > + type *val = file->private_data; \ > + \ > + snprintf(buf, sizeof(buf), format, *val); \ > + return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); \ > +} \ > +static ssize_t write_file_##type(struct file *file, > const char __user *user_buf, size_t count, loff_t *ppos) \ > +{ \ > + char *endp; \ > + char buf[32]; \ > + int buf_size; \ > + type *val = file->private_data; \ > + temptype tmp; \ > + \ > + memset(buf, 0x00, sizeof(buf)); \ > + buf_size = min(count, (sizeof(buf)-1)); \ > + if (copy_from_user(buf, user_buf, buf_size)) \ > + return -EFAULT; \ > + \ > + tmp = strtolfn(buf, &endp, 0); \ > + if ((endp == buf) || ((type)tmp != tmp)) \ > + return -EINVAL; \ > + *val = tmp; \ > + return count; \ > +} \ > +static struct file_operations fops_##type = { \ > + .read = read_file_##type, \ > + .write = write_file_##type, \ > + .open = default_open, \ > + .llseek = default_file_lseek, \ > +}; \ > +struct dentry *debugfs_create_##type(const char *name, mode_t mode, > struct dentry *parent, type *value) \ > +{ \ > + return debugfs_create_file(name, mode, parent, value, &fops_##type); \ > +} > + > +simple_type(u8, "%c", unsigned long, simple_strtoul); > +simple_type(u16, "%hi", unsigned long, simple_strtoul); > +simple_type(u32, "%i", unsigned long, simple_strtoul); > +EXPORT_SYMBOL_GPL(debugfs_create_u8); > +EXPORT_SYMBOL_GPL(debugfs_create_u16); > +EXPORT_SYMBOL_GPL(debugfs_create_u32); Move above three lines into the macro? Or do you prefer to me the export move obvious? > +#include <linux/config.h> > +#include <linux/module.h> > +#include <linux/fs.h> > +#include <linux/mount.h> > +#include <linux/pagemap.h> > +#include <linux/init.h> > +#include <linux/namei.h> I like to sort the above alphabetically. Shouldn't matter, but it looks neat and since there is no other natural order... > +static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev) > +{ > + struct inode *inode = new_inode(sb); > + > + if (inode) { > + inode->i_mode = mode; > + inode->i_uid = 0; > + inode->i_gid = 0; > + inode->i_blksize = PAGE_CACHE_SIZE; > + inode->i_blocks = 0; > + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; > + switch (mode & S_IFMT) { > + default: > + init_special_inode(inode, mode, dev); Just out of curiosity: why would anyone want special nodes under /debug? > + break; > + case S_IFREG: > + inode->i_fop = &debugfs_file_operations; > + break; > + case S_IFDIR: > + inode->i_op = &simple_dir_inode_operations; > + inode->i_fop = &simple_dir_operations; > + > + /* directory inodes start off with i_nlink == 2 (for "." entry) */ > + inode->i_nlink++; > + break; > + } > + } > + return inode; > +} > +static inline struct dentry *debugfs_create_file(const char *name, mode_t mode, > struct dentry *parent, void *data, struct file_operations *fops) > +{ return ERR_PTR(-ENODEV); } Nice. Gotta remember that one. Jörn -- To recognize individual spam features you have to try to get into the mind of the spammer, and frankly I want to spend as little time inside the minds of spammers as possible. -- Paul Graham
From: Greg KH [email blocked] Subject: Re: [RFC PATCH] debugfs - yet another in-kernel file system Date: Fri, 10 Dec 2004 09:35:56 -0800 On Fri, Dec 10, 2004 at 06:21:26PM +0100, J?rn Engel wrote: > Two-word summary: cool stuff! Thanks! > > On Thu, 9 December 2004 16:50:56 -0800, Greg KH wrote: > > > > Thus debugfs was born (yes, I know there's a userspace program called > > debugfs, this is an in-kernel filesystem and has nothing to do with > > that.) debugfs is ment for putting stuff that kernel developers need to > > see exported to userspace, yet don't always want hanging around. > > In principle, it is the same as /proc, just with the explicit > information that binary compatibility will never be a goal, right? Yes, that is correct. > > diff -Nru a/fs/debugfs/debugfs_test.c b/fs/debugfs/debugfs_test.c > > Nice example code. But I'd vote for either killing it or renaming it > to debugfs_example.c. Just to document that anyone actually compiling > it in is stupid. Yeah, I forgot I left it in the patch, that was part of my initial test code. I'll clean it up and mark it as such. > > +static ssize_t default_read_file(struct file *file, char __user *user_buf, > > + size_t count, loff_t *ppos) > > For a similar reason, I'd call this example_read_file(). You actually > fooled me for a moment and I was wondering why the heck this should be > part of debugfs. ;) Heh, ok, will do. > > +#define simple_type(type, format, temptype, strtolfn) \ > > +static ssize_t read_file_##type(struct file *file, > char __user *user_buf, size_t count, loff_t *ppos) \ > > Long lines. Taste varies, but... Good point, I'll fix that, thanks. > > +simple_type(u8, "%c", unsigned long, simple_strtoul); > > +simple_type(u16, "%hi", unsigned long, simple_strtoul); > > +simple_type(u32, "%i", unsigned long, simple_strtoul); > > +EXPORT_SYMBOL_GPL(debugfs_create_u8); > > +EXPORT_SYMBOL_GPL(debugfs_create_u16); > > +EXPORT_SYMBOL_GPL(debugfs_create_u32); > > Move above three lines into the macro? Or do you prefer to me the > export move obvious? Hm, I don't remember why I did that. I'll move that in the macro just to save 2 lines of code :) > > +#include <linux/config.h> > > +#include <linux/module.h> > > +#include <linux/fs.h> > > +#include <linux/mount.h> > > +#include <linux/pagemap.h> > > +#include <linux/init.h> > > +#include <linux/namei.h> > > I like to sort the above alphabetically. Shouldn't matter, but it > looks neat and since there is no other natural order... Well config.h should be first. After that, sometimes it matters, but usually not. > > +static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev) > > +{ > > + struct inode *inode = new_inode(sb); > > + > > + if (inode) { > > + inode->i_mode = mode; > > + inode->i_uid = 0; > > + inode->i_gid = 0; > > + inode->i_blksize = PAGE_CACHE_SIZE; > > + inode->i_blocks = 0; > > + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; > > + switch (mode & S_IFMT) { > > + default: > > + init_special_inode(inode, mode, dev); > > Just out of curiosity: why would anyone want special nodes under > /debug? Just being "correct" :) I don't think they would want special nodes, but hey, let's not prevent anyone from doing anything. If some looney person wants to make device nodes in debugfs, then they deserve the ridicule they will get when doing it... Thanks for reviewing the code, I appreciate it. greg k-h <hr /> From: David Brownell [email blocked] Subject: Re: [linux-usb-devel] [RFC PATCH] debugfs - yet another in-kernel file system Date: Fri, 10 Dec 2004 17:29:01 -0800 On Thursday 09 December 2004 4:50 pm, Greg KH wrote: > What if there was a in-kernel filesystem that was explicitly just for > putting debugging stuff? Â Some place other than proc and sysfs, and that > was easier than both of them to use. Â Yet it needed to also be able to > handle complex stuff like seq file and raw file_ops if needed. The problem with sysfs here is: no seq_file support. Otherwise it solves the basic "where to put the debug files associated with "device X" or "driver Y" problems in a good non-confusing way: there are directories already set up for devices and for drivers. The problem with procfs here is that it doesn't have such a naming solution: there's no automatic mapping betwen a /proc/driver/...file and its device, or vice versa. That issue is shared with debugfs. Couldn't debugfs just be a thin shim on top of sysfs, adding seq_file support? Or on top of procfs, adding device/driver naming domains, and maybe file-per-value read/write support for drivers that want them? What I'd really want out of a debug file API is to resolve the naming issues, work with seq_file, and "softly and silently vanish away". I think this patch has the last two, but not the first one! - Dave
From: Greg KH [email blocked] Subject: Re: [linux-usb-devel] [RFC PATCH] debugfs - yet another in-kernel file system Date: Fri, 10 Dec 2004 17:39:30 -0800 On Fri, Dec 10, 2004 at 05:29:01PM -0800, David Brownell wrote: > On Thursday 09 December 2004 4:50 pm, Greg KH wrote: > > What if there was a in-kernel filesystem that was explicitly just for > > putting debugging stuff? ?Some place other than proc and sysfs, and that > > was easier than both of them to use. ?Yet it needed to also be able to > > handle complex stuff like seq file and raw file_ops if needed. > > The problem with sysfs here is: no seq_file support. > Otherwise it solves the basic "where to put the debug > files associated with "device X" or "driver Y" problems > in a good non-confusing way: there are directories > already set up for devices and for drivers. Yes, but that's a design decision for sysfs. no seq_file support is a feature, not a shortcoming :) > The problem with procfs here is that it doesn't have > such a naming solution: there's no automatic mapping > betwen a /proc/driver/...file and its device, or vice > versa. That issue is shared with debugfs. Agreed. > Couldn't debugfs just be a thin shim on top of sysfs, > adding seq_file support? Or on top of procfs, adding > device/driver naming domains, and maybe file-per-value > read/write support for drivers that want them? Ick. > What I'd really want out of a debug file API is to resolve > the naming issues, work with seq_file, and "softly and > silently vanish away". I think this patch has the last > two, but not the first one! I considered adding a kobject as a paramater to the debugfs interface. The file created would be equal to the path that the kobject has. Would that work for you? thanks, greg k-h

Related Links:

Looks like there's some horizontal stretching going on

on
December 11, 2004 - 9:56pm

FYI. Feel free to delete.

re: Looks like there's some horizontal stretching going on

on
December 11, 2004 - 10:29pm

Thanks, fixed.

Any security issue ?

Anonymous
on
December 12, 2004 - 9:54am

Wonder if this could lead to possible security issues : AFA I've understood it, you may read and write from userland to kernel land. Is it as safe (or as unsafe :) as any other filesystem ?

You can write to proc files t

on
December 12, 2004 - 10:59am

You can write to proc files too, so debugfs isn't that different. It's only much simpler, thus easier to make secure, and in critical systems it won't be enabled, so security isn't a problem. Even if you wanted to enable such debugging stuff on such system then it's easier to control access to debugfs because disallowing access to proc for everyone will break things. Moving things to debugfs which don't really belong in proc and could cause security problems only improves the overall security.

Debugfs is safer than other pseudofilesystems because of it's nature.

This seems cool

Anonymous (not verified)
on
December 12, 2004 - 3:15pm

procfs was always sort of a catch-all pseudofilesystem. With sysfs and debugfs everything that isn't strictly process related can be moved out of /proc, making it more like the BSD proc it is supposed to be.

That'll be nice, assuming debugfs is good enough to be merged.

where is the root directory of debugfs

sunzen (not verified)
on
January 29, 2007 - 8:12am

BTW, where is the root directory of debugfs?
I configure debugfs option as in-built for kernel 2.6.18.1, but i can't find its root directory.
Any help is appreciated.

Be aware: Treat it as other pseudo fielsystems(proc, sysfs)

sunzen (not verified)
on
January 30, 2007 - 4:08am

Before debugfs services, it should be mounted firstly.
On Fedora 5, it is desired to be mounted on /sys/kernel/debug. of course users can custom the mount point.
Fedora 5 doesn't include an entry in /etc/fstab for debugfs.
Users can add an entry, or just directly use mount command(mount -t debugfs debugfs $ROOTPATH).
After that, the created debugfs entry can be accessed.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.