Linux 内核 IIO 事件 sysfs 文件仅可读
Linux Kernel IIO events sysfs files only readable
我在为上升和下降阈值注册 IIO 事件时遇到了问题。
我可以在事件子文件夹中看到 sysfs 文件并可以读取它们,但是当我尝试编写一个新的阈值时,它显示 "permission denied".
以下设置:
static const struct iio_event_spec as6200_events[] = {
{
.type = IIO_EV_TYPE_THRESH,
.dir = IIO_EV_DIR_RISING,
.mask_separate = BIT(IIO_EV_INFO_VALUE),
}, {
.type = IIO_EV_TYPE_THRESH,
.dir = IIO_EV_DIR_FALLING,
.mask_separate = BIT(IIO_EV_INFO_VALUE),
}
};
static const struct iio_chan_spec as6200_channels[] = {
{
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_SCALE),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.event_spec = as6200_events,
.num_event_specs = ARRAY_SIZE(as6200_events),
}
};
finding: it works when I change the permissions of the in_temp_thresh_rising_value
file to 666
via sudo
. But why is it not created with this permissions via IIO subsystem?
这是 sysfs 文件的常见做法,因为写入这些文件会改变系统的行为,甚至危及或破坏系统。所以如果你想写入这些文件,你应该从 root 执行,或者将你的用户添加到相应的组,或者更改文件模式(通过 udev 规则或手动)。
这是在 IIO 代码中的实现方式:
- IIO sysfs 节点名称源自 drivers/iio/industrialio-event.c 中的下一个表:
iio_ev_type_text
、iio_ev_dir_text
和 iio_ev_info_text
- 接下来是节点创建路径:
iio_device_add_event()
-> __iio_add_chan_devattr()
-> __iio_device_attr_init()
正在为 sysfs 节点设置文件模式 __iio_device_attr_init():
阅读:dev_attr->attr.mode |= S_IRUGO;
- 所以每个用户都可以读取节点(因为
S_IRUGO
允许R为User,G组和O其他)
写作:dev_attr->attr.mode |= S_IWUSR;
- 所以它只能由 root 写入(因为
S_IWUSR
只允许文件所有者写入,即 root)
这个问题的另一个解决方案是结合使用 libiio 的网络和本地上下文。在这种情况下,将以适当的权限启动 libiio 守护进程以写入 sysfs 文件,然后用户应用程序将使用 libiio 网络上下文连接到该守护进程。
我在为上升和下降阈值注册 IIO 事件时遇到了问题。 我可以在事件子文件夹中看到 sysfs 文件并可以读取它们,但是当我尝试编写一个新的阈值时,它显示 "permission denied".
以下设置:
static const struct iio_event_spec as6200_events[] = {
{
.type = IIO_EV_TYPE_THRESH,
.dir = IIO_EV_DIR_RISING,
.mask_separate = BIT(IIO_EV_INFO_VALUE),
}, {
.type = IIO_EV_TYPE_THRESH,
.dir = IIO_EV_DIR_FALLING,
.mask_separate = BIT(IIO_EV_INFO_VALUE),
}
};
static const struct iio_chan_spec as6200_channels[] = {
{
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_SCALE),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.event_spec = as6200_events,
.num_event_specs = ARRAY_SIZE(as6200_events),
}
};
finding: it works when I change the permissions of the
in_temp_thresh_rising_value
file to666
viasudo
. But why is it not created with this permissions via IIO subsystem?
这是 sysfs 文件的常见做法,因为写入这些文件会改变系统的行为,甚至危及或破坏系统。所以如果你想写入这些文件,你应该从 root 执行,或者将你的用户添加到相应的组,或者更改文件模式(通过 udev 规则或手动)。
这是在 IIO 代码中的实现方式:
- IIO sysfs 节点名称源自 drivers/iio/industrialio-event.c 中的下一个表:
iio_ev_type_text
、iio_ev_dir_text
和iio_ev_info_text
- 接下来是节点创建路径:
iio_device_add_event()
->__iio_add_chan_devattr()
->__iio_device_attr_init()
正在为 sysfs 节点设置文件模式 __iio_device_attr_init():
阅读:
dev_attr->attr.mode |= S_IRUGO;
- 所以每个用户都可以读取节点(因为
S_IRUGO
允许R为User,G组和O其他)
- 所以每个用户都可以读取节点(因为
写作:
dev_attr->attr.mode |= S_IWUSR;
- 所以它只能由 root 写入(因为
S_IWUSR
只允许文件所有者写入,即 root)
- 所以它只能由 root 写入(因为
这个问题的另一个解决方案是结合使用 libiio 的网络和本地上下文。在这种情况下,将以适当的权限启动 libiio 守护进程以写入 sysfs 文件,然后用户应用程序将使用 libiio 网络上下文连接到该守护进程。