udev 创建了正确的规则,但是当我尝试通过 C++ 访问文件时,权限就会消失

udev 创建了正确的规则,但是当我尝试通过 C++ 访问文件时,权限就会消失

我在使用 udev 时遇到了一个非常奇怪的问题。正如我已经解释过的这里我正在尝试访问一些文件夹/文件无 root 用户 以下是我的 gpio 文件夹的 udev 规则:

KERNEL=="gpio*", SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R dave:users /sys/class/gpio; chmod -R 777 /sys/class/gpio'"
KERNEL=="gpio*", SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R dave:users /sys/class/virtual/gpio; chmod -R 777 /sys/class/virtual/gpio'"
KERNEL=="gpio*", SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R dave:users /sys%p; chmod -R 770 /sys%p'"

其按照预期以正确的方式应用。事实上,重新启动后,我获得了规则中定义的权限:

dave@arm:~$ ls -l /sys/class/gpio/
total 0
-rwxrwxrwx 1 dave users 4096 Jan  9 20:56 export
lrwxrwxrwx 1 dave users    0 Jan  9 20:56 gpiochip0 -> ../../devices/platform/ocp/44e07000.gpio/gpio/gpiochip0
lrwxrwxrwx 1 dave users    0 Jan  9 20:56 gpiochip32 -> ../../devices/platform/ocp/4804c000.gpio/gpio/gpiochip32
lrwxrwxrwx 1 dave users    0 Jan  9 20:56 gpiochip64 -> ../../devices/platform/ocp/481ac000.gpio/gpio/gpiochip64
lrwxrwxrwx 1 dave users    0 Jan  9 20:56 gpiochip96 -> ../../devices/platform/ocp/481ae000.gpio/gpio/gpiochip96
-rwxrwxrwx 1 dave users 4096 Jan  9 20:56 unexport

现在:发生了一些非常奇怪的事情。我编写了简单的 C++ 程序,它使用 boost 库来访问和写入文件。在这里,我发布了我的程序的一部分,其中包含类作为示例:

/*
 * @brief drives the gpio-pin high or low
 * @param the pin number, the state (high or low)
 * @return the success of the operation
 * 
 */
int GPIOclass::digitalWrite( unsigned int pin_label, unsigned int state ) 
{
    /* Check whether the Pin state has been correctly set or not */
    if( ( state != HIGH ) && ( state != LOW ) ) {
        std::cerr << "WARNING: Check again the value you want to write. It must be HIGH or LOW!" << std::endl;
        return EXIT_FAILURE;
    }

    /* Write the desired Pin value */
    boost::filesystem::fstream fs;

    boost::filesystem::path path_pin = "/sys/class/gpio";
    path_pin /= "/gpio" + std::to_string( pin_label );
    path_pin /= "/value";

    fs.open( path_pin, std::fstream::out );
    if( fs.is_open() ) {
        fs << state;
        fs.close();
    } else {
        std::cerr << "ERROR: I couldn't open " << path_pin << " file" << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

奇怪的是,我无法访问所需的引脚,因为在导出的文件夹中我只找到一个链接,而不是驱动 GPIO 的常用文件和文件夹。我发现的是唯一的条目:

dave@arm:~$ ls -l /sys/class/gpio/gpio60
lrwxrwxrwx 1 dave users 0 Jan  9 20:58 /sys/class/gpio/gpio60 -> ../../devices/platform/ocp/4804c000.gpio/gpio/gpio60

进入目录我可以看到比上面更多的文件和文件夹:

dave@arm:/sys/class/gpio/gpio60$ ls -l
total 0
-rwxrwx--- 1 dave users 4096 Jan  9 21:11 active_low
lrwxrwxrwx 1 dave users    0 Jan  9 21:11 device -> ../../../4804c000.gpio
-rwxrwx--- 1 dave users 4096 Jan  9 21:11 direction
-rwxrwx--- 1 dave users 4096 Jan  9 21:11 edge
drwxrwx--- 2 dave users    0 Jan  9 21:11 power
lrwxrwxrwx 1 dave users    0 Jan  9 21:11 subsystem -> ../../../../../../class/gpio
-rwxrwx--- 1 dave users 4096 Jan  9 21:11 uevent
-rwxrwx--- 1 dave users 4096 Jan  9 21:11 value

所以似乎有一些可见性规则或类似的东西。为什么我会得到 2 个不同的结果我从外面查看文件夹或者如果我从文件夹里面看

使用 sudo 启动同一个程序效果很好。


更新:我完全按照下面答案中的建议做了。答案是正确的,但我无法以普通用户身份使用导出的gpio。所以我正在寻找一个新规则,它可以让我更改链接文件夹的组和所有者:

/sys/devices/platform/ocp/4804c000.gpio 

正如答案中所建议的。

现在的问题是我正在尝试编写一条新规则来实现这一点。一旦我检索到以下信息:

@arm:~/workspace/auto/build$ udevadm info --path=/sys/devices/platform/ocp/4804c000.gpio --attribute-walk

Udevadm i...

  looking at device '/devices/platform/ocp/4804c000.gpio':
    KERNEL=="4804c000.gpio"
    SUBSYSTEM=="platform"
    DRIVER=="omap_gpio"
    ATTR{driver_override}=="(null)"

  looking at parent device '/devices/platform/ocp':
    KERNELS=="ocp"
    SUBSYSTEMS=="platform"
    DRIVERS==""
    ATTRS{driver_override}=="(null)"

  looking at parent device '/devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""

我将以下规则添加到现有的 udev 规则中:

KERNEL=="gpio*", SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R bbb:gpio /sys/class/gpio; chmod -R 777 /sys/class/gpio'"
KERNEL=="gpio*", SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R bbb:gpio /sys/class/virtual/gpio; chmod -R 777 /sys/class/virtual/gpio'"
KERNEL=="gpio*", SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R bbb:gpio /sys%p; chmod -R 776 /sys%p'"
KERNEL=="4804c000.gpio", SUBSYSTEM=="platform", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R bbb:gpio /sys/devices/platform/ocp/4804c000.gpio; chmod -R 777 /sys/devices/platform/ocp/4804c000.gpio'"
KERNEL=="481ae000.gpio", SUBSYSTEM=="platform", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R bbb:gpio /sys/devices/platform/ocp/481ae000.gpio; chmod -R 777 /sys/devices/platform/ocp/481ae000.gpio'"
KERNEL=="481ac000.gpio", SUBSYSTEM=="platform", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R bbb:gpio /sys/devices/platform/ocp/481ac000.gpio; chmod -R 777 /sys/devices/platform/ocp/481ac000.gpio'"
KERNEL=="44e07000.gpio", SUBSYSTEM=="platform", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R bbb:gpio /sys/devices/platform/ocp/44e07000.gpio; chmod -R 777 /sys/devices/platform/ocp/44e07000.gpio'"

作为普通用户运行我仍然收到以下错误:

ERROR: I couldn't open "/sys/class/gpio/gpio67/value" file
ERROR: I couldn't open "/sys/class/gpio/gpio69/value" file
ERROR: I couldn't open "/sys/class/gpio/gpio66/value" file
ERROR: I couldn't open "/sys/class/gpio/gpio69/value" file

来自我上面的 C++ 程序。

我真的无法理解,因为权限设置正确:

bbb@arm:~/workspace/build$ ls -l /sys/class/gpio/gpio60/
total 0
-rwxrwxrw- 1 bbb gpio 4096 Jan 11 17:50 active_low
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:50 device -> ../../../4804c000.gpio
-rwxrwxrw- 1 bbb gpio 4096 Jan 11 17:50 direction
-rwxrwxrw- 1 bbb gpio 4096 Jan 11 17:50 edge
drwxrwxrw- 2 bbb gpio    0 Jan 11 17:50 power
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:50 subsystem -> ../../../../../../class/gpio
-rwxrwxrw- 1 bbb gpio 4096 Jan 11 17:50 uevent
-rwxrwxrw- 1 bb gpio 4096 Jan 11 17:50 value

链接的问题现在似乎已经解决:

bbb@arm:~/workspace/build$ ls -l /sys/class/gpio
total 0
-rwxrwxrwx 1 bbb gpio 4096 Jan 11 17:50 export
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:50 gpio48 -> ../../devices/platform/ocp/4804c000.gpio/gpio/gpio48
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:50 gpio60 -> ../../devices/platform/ocp/4804c000.gpio/gpio/gpio60
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:50 gpio66 -> ../../devices/platform/ocp/481ac000.gpio/gpio/gpio66
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:50 gpio67 -> ../../devices/platform/ocp/481ac000.gpio/gpio/gpio67
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:50 gpio68 -> ../../devices/platform/ocp/481ac000.gpio/gpio/gpio68
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:50 gpio69 -> ../../devices/platform/ocp/481ac000.gpio/gpio/gpio69
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:49 gpiochip0 -> ../../devices/platform/ocp/44e07000.gpio/gpio/gpiochip0
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:49 gpiochip32 -> ../../devices/platform/ocp/4804c000.gpio/gpio/gpiochip32
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:49 gpiochip64 -> ../../devices/platform/ocp/481ac000.gpio/gpio/gpiochip64
lrwxrwxrwx 1 bbb gpio    0 Jan 11 17:49 gpiochip96 -> ../../devices/platform/ocp/481ae000.gpio/gpio/gpiochip96
-rwxrwxrwx 1 bbb gpio 4096 Jan 11 17:49 unexport

我做错了什么?


更新:我真的很难尝试理解这个发行版中发生的事情。我想出了这个最小的例子(在此下关联您可以找到 cmakelists 来编译它)以打开并写入每个引脚的导出文件夹。我现在正在使用 beaglebone (带有 ubuntu)。 uder 规则在上面定义。我没有改变它们。

尝试使用我的用户“bbb”运行该程序,出现以下错误:

bbb@arm:~/workspace/auto/test/build$ ./myprog 
ERROR: the direction of pin "/sys/class/gpio/gpio67/direction" cannot be set.
Reason: Permission denied
ERROR: the value of the "/sys/class/gpio/gpio67/value" cannot be defined.
Reason: Permission denied
...

我将用户“bbb”添加到属于默认用户“ubuntu”的所有组。

我能做些什么?

答案1

/sys/class/gpio/gpio60是一个符号链接。这是一种特殊类型的文件,指向另一个文件。当访问文件内容时,符号链接是透明的:它们的作用就像它们的目标(它们指向的文件)。但是当列出目录时,符号链接会显示为它们本身;在最左边的列中ls -l显示他们,并在右边显示他们的目标。访问元数据时,这取决于情况。l->

chmod -R … /sys/class/gpio影响从 开始的目录树/sys/class/gpio。这包括诸如 之类的条目/sys/class/gpio/gpio60。但是/sys/class/gpio/gpio60是一个符号链接,指向目录树中的其他位置;该chmod命令不会影响符号链接的目标。

当您尝试访问 下的文件/sys/class/gpio/gpio60或运行 时cd /sys/class/gpio/gpio60,这将访问符号链接指向的目录(访问目录的内容)。这可以作为 root 运行,但不能作为非 root 运行,因为该目录只能由 root 访问。

要使其他用户可以访问该目录,您需要运行chmod … /sys/devices/platform/ocp/4804c000.gpio/gpio/gpio60.

但是,将用户添加到组中比更改所有权更简单gpio

adduser dave gpio

相关内容