2017-01-26 6 views
0

Я пишу модуль для ядра Linux.Как изменить права доступа sysfs_create_file() позже?

Этот модуль обнажая некоторые ввода/вывода в файл /sys/kernel/mymodule/foo:

static struct kobj_attribute foo_attribute =__ATTR(foo, 0660, foo_show, foo_store); 
...   
ret = sysfs_create_file(&mymodule->kobj, &foo_attribute.attr); 

Я хочу, чтобы иметь возможность изменить 0660 разрешений на 0440, как только некоторые данные были записаны в /sys/kernel/mymodule/foo. Я буду делать это в функции foo_store().

Я исследовал макрос __ATTR - он вызывает взрыв кода, в основном манипулируя разрешениями. Код выше разложена в:

static struct foo_attribute = { .attr = {.name = "foo", .mode = ((sizeof(struct { int:-!!((0660) < 0); })) + (sizeof(struct { int:-!!((0660) > 0777); })) + (sizeof(struct { int:-!!(((0660) >> 6) < (((0660) >> 3) & 7)); })) + (sizeof(struct { int:-!!((((0660) >> 3) & 7) < ((0660) & 7)); })) + (sizeof(struct { int:-!!((0660) & 2); })) + (0660)) }, .show = foo_show, .store = foo_store, }; 
... 
ret = sysfs_create_file(&vr2200pmu->kobj, &revision_attribute.attr); 

с помощью gcc -E mymodule.c -I../../include -I../../arch/arm/include -I../../arch/arm/include/generated в директории модуля.

Как я могу достичь этого в чистом, переносном пути?

+0

Похоже, макрос просто во время компиляции проверки прав доступа, с помощью 'SizeOf (struct {int: - !! (whatever);}) ', что приведет к ошибке времени компиляции (бит-бит отрицательной длины), если' whatever' отличен от нуля. – fadedbee

+0

Это макрокоманды 'BUILD_BUG_ON_ZERO', которые проверяют правильность разрешений. Просто просмотрите определение макроса '__ATTR()' в [исходных файлах ядра] (http://lxr.free-electrons.com/source/include/linux/sysfs.h#L100). – Tsyvarev

ответ

1

Неуверенный, является ли он предназначен способ для изменения разрешений sysfs файлов программно, но это должно работать:

// Obtain kernfs object for directory 
struct kernfs_node* dir_knode = kobj->sd; 
// Obtain kernfs object for file in the directory 
struct kernfs_node* file_knode = sysfs_get_dirent(dir_knode, foo_attr.attr.name); 
// Change permissions. Set only permissions-related bits. 
file_knode->mode = (file_knode->mode & S_IFMT) | 0440; 
Смежные вопросы