Как макрос __ATTR используется в ядре Linux?

Я хотел бы создать запись sysfs, которая делается с использованием структуры «атрибут». Для этого рекомендуется использовать макрос __ATTR, например:

static ssize_t functionCalledOnRead(struct kobject *, struct attribute *, char *);
static ssize_t functionCalledOnRead(struct kobject *, struct attribute *, char *);

static struct attribute genericSysfsAttribute = __ATTR(attr_name, S_IRUGO | S_IRUSR, functionCalledOnRead, functionCalledOnWrite);

Однако это не работает.

/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:15: warning: braces around scalar initializer
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:15: warning: (near initialization for 'genericSysfsAttribute.name')
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:15: error: field name not in record or union initializer
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:15: error: (near initialization for 'genericSysfsAttribute.name')
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:15: error: field name not in record or union initializer
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:15: error: (near initialization for 'genericSysfsAttribute.name')
In file included from include/linux/thread_info.h:11:0,
                 from include/asm-generic/preempt.h:4,
                 from arch/arm/include/generated/asm/preempt.h:1,
                 from include/linux/preempt.h:59,
                 from include/linux/spinlock.h:50,
                 from include/linux/seqlock.h:35,
                 from include/linux/time.h:5,
                 from include/linux/stat.h:18,
                 from include/linux/module.h:10,
                 from /home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:2:
include/linux/bug.h:34:45: warning: excess elements in scalar initializer
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^
include/linux/kernel.h:842:3: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
   BUILD_BUG_ON_ZERO((perms) & 2) +     \
   ^
include/linux/sysfs.h:102:12: note: in expansion of macro 'VERIFY_OCTAL_PERMISSIONS'
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
            ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:49: note: in expansion of macro '__ATTR'
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                                                 ^
include/linux/bug.h:34:45: warning: (near initialization for 'genericSysfsAttribute.name')
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^
include/linux/kernel.h:842:3: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
   BUILD_BUG_ON_ZERO((perms) & 2) +     \
   ^
include/linux/sysfs.h:102:12: note: in expansion of macro 'VERIFY_OCTAL_PERMISSIONS'
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
            ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:49: note: in expansion of macro '__ATTR'
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                                                 ^
include/linux/bug.h:34:45: error: unknown field 'show' specified in initializer
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^
include/linux/kernel.h:842:3: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
   BUILD_BUG_ON_ZERO((perms) & 2) +     \
   ^
include/linux/sysfs.h:102:12: note: in expansion of macro 'VERIFY_OCTAL_PERMISSIONS'
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
            ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:49: note: in expansion of macro '__ATTR'
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                                                 ^
include/linux/bug.h:34:45: warning: initialization makes integer from pointer without a cast
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^
include/linux/kernel.h:842:3: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
   BUILD_BUG_ON_ZERO((perms) & 2) +     \
   ^
include/linux/sysfs.h:102:12: note: in expansion of macro 'VERIFY_OCTAL_PERMISSIONS'
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
            ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:49: note: in expansion of macro '__ATTR'
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                                                 ^
include/linux/bug.h:34:45: warning: (near initialization for 'genericSysfsAttribute.mode')
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^
include/linux/kernel.h:842:3: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
   BUILD_BUG_ON_ZERO((perms) & 2) +     \
   ^
include/linux/sysfs.h:102:12: note: in expansion of macro 'VERIFY_OCTAL_PERMISSIONS'
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
            ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:49: note: in expansion of macro '__ATTR'
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                                                 ^
include/linux/bug.h:34:45: error: initializer element is not computable at load time
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^
include/linux/kernel.h:842:3: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
   BUILD_BUG_ON_ZERO((perms) & 2) +     \
   ^
include/linux/sysfs.h:102:12: note: in expansion of macro 'VERIFY_OCTAL_PERMISSIONS'
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
            ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:49: note: in expansion of macro '__ATTR'
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                                                 ^
include/linux/bug.h:34:45: error: (near initialization for 'genericSysfsAttribute.mode')
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^
include/linux/kernel.h:842:3: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
   BUILD_BUG_ON_ZERO((perms) & 2) +     \
   ^
include/linux/sysfs.h:102:12: note: in expansion of macro 'VERIFY_OCTAL_PERMISSIONS'
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
            ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:49: note: in expansion of macro '__ATTR'
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                                                 ^
include/linux/bug.h:34:45: error: unknown field 'store' specified in initializer
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^
include/linux/kernel.h:842:3: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
   BUILD_BUG_ON_ZERO((perms) & 2) +     \
   ^
include/linux/sysfs.h:102:12: note: in expansion of macro 'VERIFY_OCTAL_PERMISSIONS'
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
            ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:49: note: in expansion of macro '__ATTR'
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                                                 ^
include/linux/bug.h:34:45: warning: excess elements in struct initializer
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^
include/linux/kernel.h:842:3: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
   BUILD_BUG_ON_ZERO((perms) & 2) +     \
   ^
include/linux/sysfs.h:102:12: note: in expansion of macro 'VERIFY_OCTAL_PERMISSIONS'
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
            ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:49: note: in expansion of macro '__ATTR'
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                                                 ^
include/linux/bug.h:34:45: warning: (near initialization for 'genericSysfsAttribute')
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^
include/linux/kernel.h:842:3: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
   BUILD_BUG_ON_ZERO((perms) & 2) +     \
   ^
include/linux/sysfs.h:102:12: note: in expansion of macro 'VERIFY_OCTAL_PERMISSIONS'
    .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },  \
            ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:49: note: in expansion of macro '__ATTR'
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                                                 ^
/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.c:32:25: warning: 'genericSysfsAttribute' defined but not used [-Wunused-variable]
 static struct attribute genericSysfsAttribute = __ATTR(attr_name,S_IRUGO | S_IRUSR,functionCalledOnRead,functionCalledOnWrite);
                         ^
scripts/Makefile.build:297: recipe for target '/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.o' failed
make[2]: *** [/home/osboxes/Documents/kernel_modules/sysfsmodule/sysfsmodule.o] Error 1
Makefile:1425: recipe for target '_module_/home/osboxes/Documents/kernel_modules/sysfsmodule' failed
make[1]: *** [_module_/home/osboxes/Documents/kernel_modules/sysfsmodule] Error 2
make[1]: Leaving directory '/home/osboxes/Documents/linux-mykonos'
Makefile:7: recipe for target 'cross' failed
make: *** [cross] Error 2

Я действительно не понимаю, о чем говорит большинство этих ошибок, поскольку они говорят о включенном коде, а не о том, что я написал. Однако, поскольку первый аргумент — это просто имя, а второй — просто число, я не ожидаю, что с ними что-то не так, поэтому похоже, что это как-то связано с тем, как я даю имена этим двум функциям. не работает. Как передать такую ​​функцию?


person Zephyr    schedule 20.01.2017    source источник


Ответы (2)


Макрос __ATTR предназначен не для прямого использования, а для использования разработчиками подсистем, которые определяют тип для kobject и создает структуру атрибутов, "производную" от struct attribute.

Кроме того, простой struct attribute имеет небольшой смысл:

Чистый атрибут не содержит средств для чтения или записи значения атрибута. Подсистемам рекомендуется определять свою собственную структуру атрибутов и функции-оболочки для добавления и удаления атрибутов для определенного типа объекта.

person Tsyvarev    schedule 21.01.2017

Ошибка возникает из-за значения режима, которое вы передаете в макрос, т.е. S_IRUGO|S_IRUSR. В модуле <linux/kernel.h> проверка разрешений вызывает ошибку, если разрешения нарушают любое из следующих условий:

  1. USER_READABLE >= GROUP_READABLE >= OTHER_READABLE
  2. ‹777 и >0
  3. USER_WRITABLE >= GROUP_WRITABLE
  4. OTHER_WRITABLE = 0 (не рекомендуется разрешать здесь запись)
person Alan Nair    schedule 01.03.2020