在内核中逐行读取配置文件
Read Config File Line By Line in Kernel
我正在尝试读取我正在工作的模块的配置文件(位于内核中特定位置的 located/generated)。
我可以通过使用 filp_open 和 O_RDONLY 标志(只读)来读取整个文件,但我想不出一种逐行读取它的方法。
当前代码
f = filp_open("/etc/my_module",O_RDONLY, 0);
if ( f==NULL) {
printk("Error in loading config for birdge.\n");
return 1;
} else {
fs = get_fs();
set_fs(get_ds());
/* read line config here */
f->f_op->read(f, buf, 128, &f->f_pos);
set_fs(fs);
printk("buf:%s\n",buf);
}
Linux 内核版本:3.8.0-29-generic
我想要实现的是将每(第 n )行放入一个缓冲区数组(char *buf[128][128]),稍后我将使用纯 c 将参数和值分块。
通过这种方式,配置文件中的变量可以在模块的运行时使用,当然我会进行一些条件检查是否配置正确。
谢谢
[TL;DR: 避免直接从内核读取文件系统文件这样的事情 space。]
你几乎完成了。
您目前唯一需要的是使用 kcalloc()
(类似于 libc calloc()
分配一个字符串数组,您可以设置一个额外的参数 [为了示例] as GFP_KERNEL), 然后用 f->f_op->read(f, &chr, 1, &f->f_pos);
遍历文件(逐个字符读取字符,类似于 libc read(f, &chr, 1)
...您可以稍后通过分块读取文件和处理来优化它块以避免内核中的大量读取 space).
这将为您在内核领域提供与 fgetc()
类似的方法,并为您的 char *buf[]
数组提供与 calloc()
类似的接口。
您也可以实现自己的(优化不佳)kfgetc()
,例如:
int kfgetc(struct file *f) {
char chr = 0;
f->f_op->read(f, &chr, 1, &f->f_pos);
return chr;
}
通过这个示例,您可以轻松创建一个 kfgets()
(只需循环 kfgetc()
直到找到 '\n' 或没有其他内容可读)。
请注意,总的来说,您所做的似乎不是一个好的做法(老实说,这是一个非常糟糕的主意),但是把它放在一边(因为我不知道为什么你正在做),以上是让它工作的良好开端。当它开始工作时,然后查看可以在哪里对其进行优化(另请参阅其他内核组件如何检索配置,如@ZanLynx 所述)。
其他一些对您的情况有用的内存分配器(因为如果您不知道文件中有多少行,kcalloc()
可能无法解决您的问题):kmalloc()
和 krealloc()
(类似于 libc malloc()
和 realloc()
)。
在内核中解析配置文件既麻烦又危险。不要那样做。
如果您的内核模块需要配置,这通常是通过在加载模块时传递参数来完成的,例如insmod example.ko foo=123
。您可以使用 module_param
宏在您的模块中声明这些参数。 the Linux Kernel Module Programming Guide.
中提供了有关如何执行此操作的信息
如果您的模块需要比使用模块参数更复杂的配置,您的模块可能适合在 sysfs 中为此配置创建端点。请注意,这都意味着您的模块很可能需要用户空间帮助脚本来配置它。 这是正常的,没问题。在用户空间编写这个脚本比在内核中编写运行要简单和安全得多。
我正在尝试读取我正在工作的模块的配置文件(位于内核中特定位置的 located/generated)。
我可以通过使用 filp_open 和 O_RDONLY 标志(只读)来读取整个文件,但我想不出一种逐行读取它的方法。
当前代码
f = filp_open("/etc/my_module",O_RDONLY, 0);
if ( f==NULL) {
printk("Error in loading config for birdge.\n");
return 1;
} else {
fs = get_fs();
set_fs(get_ds());
/* read line config here */
f->f_op->read(f, buf, 128, &f->f_pos);
set_fs(fs);
printk("buf:%s\n",buf);
}
Linux 内核版本:3.8.0-29-generic
我想要实现的是将每(第 n )行放入一个缓冲区数组(char *buf[128][128]),稍后我将使用纯 c 将参数和值分块。
通过这种方式,配置文件中的变量可以在模块的运行时使用,当然我会进行一些条件检查是否配置正确。
谢谢
[TL;DR: 避免直接从内核读取文件系统文件这样的事情 space。]
你几乎完成了。
您目前唯一需要的是使用 kcalloc()
(类似于 libc calloc()
分配一个字符串数组,您可以设置一个额外的参数 [为了示例] as GFP_KERNEL), 然后用 f->f_op->read(f, &chr, 1, &f->f_pos);
遍历文件(逐个字符读取字符,类似于 libc read(f, &chr, 1)
...您可以稍后通过分块读取文件和处理来优化它块以避免内核中的大量读取 space).
这将为您在内核领域提供与 fgetc()
类似的方法,并为您的 char *buf[]
数组提供与 calloc()
类似的接口。
您也可以实现自己的(优化不佳)kfgetc()
,例如:
int kfgetc(struct file *f) {
char chr = 0;
f->f_op->read(f, &chr, 1, &f->f_pos);
return chr;
}
通过这个示例,您可以轻松创建一个 kfgets()
(只需循环 kfgetc()
直到找到 '\n' 或没有其他内容可读)。
请注意,总的来说,您所做的似乎不是一个好的做法(老实说,这是一个非常糟糕的主意),但是把它放在一边(因为我不知道为什么你正在做),以上是让它工作的良好开端。当它开始工作时,然后查看可以在哪里对其进行优化(另请参阅其他内核组件如何检索配置,如@ZanLynx 所述)。
其他一些对您的情况有用的内存分配器(因为如果您不知道文件中有多少行,kcalloc()
可能无法解决您的问题):kmalloc()
和 krealloc()
(类似于 libc malloc()
和 realloc()
)。
在内核中解析配置文件既麻烦又危险。不要那样做。
如果您的内核模块需要配置,这通常是通过在加载模块时传递参数来完成的,例如insmod example.ko foo=123
。您可以使用 module_param
宏在您的模块中声明这些参数。 the Linux Kernel Module Programming Guide.
如果您的模块需要比使用模块参数更复杂的配置,您的模块可能适合在 sysfs 中为此配置创建端点。请注意,这都意味着您的模块很可能需要用户空间帮助脚本来配置它。 这是正常的,没问题。在用户空间编写这个脚本比在内核中编写运行要简单和安全得多。