简体   繁体   中英

implement a write function to a debugfs file

I try to implement a write function to a debugfs file. I hope I can use echo "hello" > /sys/kernel/debugfs/mydir/myfile to write a string to the file. And use echo "world" >> /sys/kernel/debugfs/mydir/myfile to append world after hello . I found two problem in my implementation. One is the echo command would stuck if the length of input string is over the buffer size. The other is the echo "world" >> /sys/kernel/debugfs/mydir/myfile never append the string. Instead, it new a string. Below is my implementation.

#include <linux/module.h>       /* Needed by all modules */
#include <linux/kernel.h>       /* Needed for KERN_INFO */
#include <linux/init.h>         /* Needed for the macros */
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/debugfs.h>
#include <linux/fs.h>
#include <linux/sched.h>
MODULE_LICENSE("GPL");

#define BUF_SIZE 10

static char foo_buf[BUF_SIZE];
static struct dentry *debug_dir;
static struct dentry *debug_foo;

static ssize_t foo_read(struct file *file, char __user *buf, size_t count,
            loff_t *f_pos)
{
    return simple_read_from_buffer(buf, count, f_pos, foo_buf, sizeof(foo_buf));
}

static ssize_t foo_write(struct file *file, const char __user *buf, size_t count,
                    loff_t *f_pos)
{
    size_t ret;

    if (*f_pos > BUF_SIZE)
            return -EINVAL;
    ret = simple_write_to_buffer(foo_buf, sizeof(foo_buf), f_pos, buf, count);
    if (ret < 0)
            return ret;
    foo_buf[ret] = '\0';

    return ret;
}

static const struct file_operations foo_fops = {
    .owner = THIS_MODULE,
    .read = foo_read,
    .write = foo_write,
};

static int __init debugfs_start(void)
{

    pr_err("init debugfs");

    debug_dir = debugfs_create_dir("mydir", NULL);
    if (debug_dir == NULL) {
            pr_err("debugfs create my dir failed");
            return -ENOMEM;
    }

    debug_foo = debugfs_create_file("foo", 0744, debug_dir,
                                       NULL, &foo_fops);
    if (!debug_foo) {
            debugfs_remove(debug_dir);
            return -ENOMEM;
    }
    return 0;
}

static void __exit debugfs_end(void)
{
    pr_err("exit debugfs");
    debugfs_remove_recursive(debug_dir);
}

module_init(debugfs_start);
module_exit(debugfs_end);

One is the echo command would stuck if the length of input string is over the buffer size.

This is because it keeps retrying to write to the file while each attempt would fail.

The other is the echo "world" >> /sys/kernel/debugfs/mydir/myfile never append the string. Instead, it new a string.

this is expected with your implementation. you would need to cat the new one to the existing string if you want to have it appended. That is, you need to keep a record of the string length. But this is different than the f_pos which is specific for a open file of a process.

How do I identify what commands(echo > or echo >>) users will use?

so you mean whether or not the user 'truncates' the file after opening it? debugfs doesn't seem to support seek but i suppose you can provide your .open function and also the .llseek function to implement that. You need to see to the end of the file when opening the file if it is for APPEND.

Sorry I could not provide the complete code but just some pointers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM