【问题标题】:Is there any limit on the iterations with seq_fileseq_file 的迭代是否有任何限制
【发布时间】:2019-09-07 09:42:14
【问题描述】:

我编写了一个基本代码,它将使用 proc 文件中的 seq_file 打印进程名称。

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>   
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include <linux/seq_file.h>
#include <linux/sched.h>
#include <linux/sched/task.h>
#include <linux/sched/signal.h>

MODULE_LICENSE("GPL");


static struct proc_dir_entry *dir_entry;

/**
 * This function is called at the beginning of a sequence.
 * ie, when:
 *  - the /proc file is read (first time)
 *  - after the function stop (end of sequence)
 *
 */

static void *my_seq_start(struct seq_file *s, loff_t *pos)
{
    loff_t index = *pos;
    if (index == 0) {
        seq_printf(s, "Current all the processes in system:\n"
                "%-24s%-5s\n", "name", "pid");
        return &init_task;
    }
    else {
        return NULL;
    }

}

/**
 * This function is called after the beginning of a sequence.
 * It's called untill the return is NULL (this ends the sequence).
 *
 */

static void *my_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
    struct task_struct *task = (struct task_struct *)v;
    task = next_task(task);
    if ((*pos != 0) && (task == &init_task)) {
        return NULL;
    }
    ++*pos;
    return task;
}

/**
 * This function is called at the end of a sequence
 *
 */
static void my_seq_stop(struct seq_file *s, void *v)
{
}

/**
 * This function is called for each "step" of a sequence
 *
 */
static int my_seq_show(struct seq_file *s, void *v)
{
    struct task_struct * task = (struct task_struct *)v;
    seq_printf(s, "%-24s%-5d\n", task->comm, task->pid);
    return 0;
}

static struct seq_operations my_seq_ops = {
    .start = my_seq_start,
    .next  = my_seq_next,
    .stop  = my_seq_stop,
    .show  = my_seq_show
};

static int my_open(struct inode *inode, struct file *filp)
{
    return seq_open(filp, &my_seq_ops);
}


static struct file_operations proc_ops = 
{
    .owner = THIS_MODULE,
    .open = my_open, //user supplied
    .read = seq_read, //interface supplied
    .release = seq_release, //interface supplied
    .llseek = seq_lseek //interface supplied
};

static int proc_init(void)
{
    dir_entry = proc_mkdir("embedded", NULL);

    proc_create("pid",0640,dir_entry,&proc_ops);
    pr_info("ldd proc entry created\n");
    return 0;
}

static void proc_cleanup(void)
{
    remove_proc_entry("pid", dir_entry);
    remove_proc_entry("embedded", NULL);
}

module_init(proc_init);
module_exit(proc_cleanup);

并非所有进程都被打印,它在打印 300 个进程后停止。我们可以使用procfs的seq api移动的迭代次数是否有任何限制。

我在上面的代码中有什么错误吗?我们可以用 seq api 只打印页面大小吗?

【问题讨论】:

  • 30 * 300 = 9000 大于一页的大小。其他东西会阻止你看到所有这些。
  • 所以,页面大小不是罪魁祸首。
  • "不是所有进程都打印出来,打印300个进程后就停止了。" - 你确定还有更多的流程吗?您是否尝试将一些 printk 调用添加到 my_seq_next 函数中,例如进入返回 NULL 的分支?
  • 如果你 both printkseq_printk 会打印相同数量的进程吗?请注意,使用next_task 正确遍历任务意味着使用 RCU 读锁进行包装。否则可能会得到错误的任务列表(甚至导致一些错误)。
  • 代码看起来不太安全。在您遍历列表时,可以创建或销毁进程。

标签: c linux linux-kernel linux-device-driver procfs


【解决方案1】:

start() 每次都在 stop() 之后调用。在此处查看第一张图片: https://linux.die.net/lkmpg/x861.html

你可以这样做:

static void *my_seq_start(struct seq_file *seq, loff_t *pos)
{
    struct task_struct *taskptr; 
    loff_t off = 0;
    rcu_read_lock();
    seq_printf(seq, "Current all the processes in system:\n"
                "%-6s%-24s\n", "pid", "name");
    for_each_process(taskptr) {
        if (*pos == off++) {
            return taskptr;}
    }
    return NULL;    //returning NULL if we reached the end
}

【讨论】:

    猜你喜欢
    • 2018-12-08
    • 2012-09-08
    • 2023-03-05
    • 1970-01-01
    • 2021-06-25
    • 2011-10-04
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多