linux内核4.15中的路径查找
Posted
技术标签:
【中文标题】linux内核4.15中的路径查找【英文标题】:Path lookup in linux kernel 4.15 【发布时间】:2020-05-14 12:42:38 【问题描述】:我正在尝试编写一个简单的内核模块,仅用于教学目的。 特别是让我头疼的是路径查找。 我想要一个 sysfs 条目,并且在存储操作中我想接收一个缓冲区,并且我只想在它是有效路径时才保存它。所以我尝试使用来自namei.c 的 vfs_path_lookup 导出符号。但即使插入有效路径,它也会打印 ENOENT 错误。
这是我的代码:
进入标题:
extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct path *path);
进入模块存储功能:
ssize_t path_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
int err = vfs_path_lookup(current->fs->root.dentry, current->fs->root.mnt, buf, LOOKUP_DIRECTORY, base_path);
printk(KERN_DEBUG "%s\n", __FUNCTION__);
printk(KERN_DEBUG "Received: %s err is %d\n", buf, err);
strncpy(base_addr, buf, MAX_FILENAME_SIZE);
printk(KERN_DEBUG "Base Addr: %s\n", base_addr);
return strlen(base_addr);
我试图写入文件的是字符串“/home/osboxes/Documents”,它是一个现有目录。我怀疑我没有得到该功能的真正用法,也许是带有标志的东西。提前感谢您的帮助。
编辑: 这是请求进入 cmets 的示例(再次感谢)
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#define MAX_FILENAME_SIZE 256
struct path *base_path ;
struct kobject *conf_kobj;
char base_addr[MAX_FILENAME_SIZE] = "/home/osboxes/Documenti";
struct kobj_attribute *get_attribute(char *name, umode_t mode, ssize_t (*show)(struct kobject *, struct kobj_attribute *, char *), ssize_t (*store)(struct kobject *, struct kobj_attribute *,
const char *, size_t));
ssize_t path_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
printk(KERN_DEBUG "%s\n", __FUNCTION__);
return sprintf(buf, "%s", base_addr);
ssize_t path_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
int err = kern_path(buf, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, base_path);
printk(KERN_DEBUG "%s\n", __FUNCTION__);
printk(KERN_DEBUG "Received: %s err is %d\n", buf, err);
strncpy(base_addr, buf, MAX_FILENAME_SIZE);
printk(KERN_DEBUG "Base Addr: %s\n", base_addr);
return strlen(base_addr);
static int __init init_mymodule(void)
struct kobj_attribute *path_attr;
printk(KERN_DEBUG "Module inserted\n");
path_attr = get_attribute(base_addr, 0666, path_show, path_store);
base_path = kmalloc(sizeof(struct path), GFP_KERNEL);
conf_kobj = kobject_create_and_add("conf", kernel_kobj);
sysfs_create_file(conf_kobj, &path_attr->attr);
return 0;
struct kobj_attribute *get_attribute(char *name, umode_t mode, ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf), ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count))
struct kobj_attribute *attribute = kmalloc(sizeof(struct kobj_attribute), GFP_KERNEL);
attribute->attr.name = name;
attribute->attr.mode = mode;
if(show)
attribute->show = show;
if(store)
attribute->store = store;
return attribute;
static void __exit exit_mymodule(void)
kobject_put(conf_kobj);
kfree(base_addr);
printk(KERN_INFO "Module removed\n");
module_init(init_mymodule);
module_exit(exit_mymodule);
MODULE_LICENSE("GPL");
我还按照@Tsyvarev 的建议将 vfs_path_lookup 替换为 kern_path。 当我写入终端时出现错误
echo "/home/osboxes/Documenti" > /sys/kernel/conf/path
当我在“buf”变量中使用地址时,在这种情况下它是硬编码的,但不起作用。
【问题讨论】:
函数vfs_path_lookup
在标题fs/internal.h
中声明,顾名思义,它不是供外部使用的。 (只有include/
下的标头可以在外部代码中使用)。为什么不改用kern_path
?
我在使用 buf 和标志的 kern_path 中遇到了同样的错误(LOOKUP_FOLLOW | LOOKUP_DIRECTORY)
@MichaelMoretti 你能写一个minimal reproducible example 的一个简单模块,它不能按照你想要的方式工作吗?只需简单查找硬编码路径即可。
我编辑了帖子
当你运行这个时你的 printk/debug 消息是什么样的?
【参考方案1】:
我解决了这个问题,因为“store”方法在字符串末尾添加了一个换行符,所以我存储了一个无效的路径。谢谢大家
【讨论】:
以上是关于linux内核4.15中的路径查找的主要内容,如果未能解决你的问题,请参考以下文章