udev cria as regras corretas, mas os direitos desaparecem assim que tento acessar arquivos via C ++

1

Estou enfrentando um problema muito estranho usando o udev. Como eu já expliquei aqui Estou tentando acessar algumas pastas / arquivos como um usuário sem raiz Aqui estão as minhas regras do udev para a pasta gpio:

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'"

que se aplicam da maneira correta, como esperado. De fato, depois de uma reinicialização, recebo os direitos que defini nas regras:

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

Agora: acontece algo realmente estranho. Eu escrevi o programa C ++ simples que usa as bibliotecas de reforço para acessar e gravar em arquivos. Aqui eu coloco um resumo do meu programa que consiste em classes apenas como um exemplo:

/*
 * @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;
}

O mais estranho é que eu não consigo acessar o pin requerido, porque na pasta exportada eu encontrei apenas um link e não os arquivos e pastas usuais para rodar o gpio. O que eu encontro é a única entrada:

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

Mas indo para o diretório, posso ver mais arquivos e pastas do que acima:

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

parece que existem algumas regras de visibilidade ou algo parecido. Por que obtenho dois resultados diferentes se eu examinar a pasta de fora ou se eu olhar de dentro da pasta ?

Começar o mesmo programa usando o sudo funciona perfeitamente.

UPDATE: Eu fiz exatamente o que sugeri na resposta abaixo. A resposta está certa, mas não consigo usar o gpio exportado como um usuário normal. Então estou procurando uma nova regra que me permita alterar o grupo e o proprietário da pasta vinculada:

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

como sugerido na resposta.

O problema é que estou tentando escrever uma nova regra que faz exatamente isso. Depois de recuperar as seguintes informações:

@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==""

Eu adicionei as seguintes regras à minha regra do udev existente:

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'"

Funcionando como um usuário normal, ainda recebo o seguinte erro:

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

do meu programa C ++ acima.

Eu realmente não entendo porque os direitos estão definidos corretamente:

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

e o problema com o link parece estar corrigido agora:

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

o que estou fazendo de errado?

ATUALIZAÇÃO: estou realmente tendo dificuldades para tentar entender o que está acontecendo nessa distribuição. Eu vim com este exemplo mínimo (sob este link você pode encontrar os cmakelists para compilá-lo) para abrir e escrever nas pastas exportadas para cada pin. Agora estou usando um beaglebone (com o Ubuntu). As regras do uder são definidas acima. Eu não os mudei.

Tentando executar o programa com meu usuário "bbb", recebo os seguintes erros:

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
...

Eu adicionei o usuário "bbb" a todos os grupos que pertencem ao usuário padrão "ubuntu".

O que posso fazer?

    
por Dave 09.01.2016 / 21:18

1 resposta

2

/sys/class/gpio/gpio60 é um link simbólico . Esse é um tipo especial de arquivo que aponta para outro arquivo. Ao acessar o conteúdo do arquivo, os links simbólicos são transparentes: eles agem como seu destino (o arquivo para o qual eles apontam). Mas ao listar diretórios, os links simbólicos aparecem como eles mesmos; ls -l mostra-os com l na coluna mais à esquerda e mostra o alvo depois de -> à direita. Ao acessar metadados, isso depende.

chmod -R … /sys/class/gpio afeta a árvore de diretórios que começa em /sys/class/gpio . Isso inclui entradas como /sys/class/gpio/gpio60 . Mas /sys/class/gpio/gpio60 é um link simbólico, apontando para outro lugar na árvore de diretórios; o comando chmod não afeta o destino do link simbólico.

Quando você tenta acessar arquivos em /sys/class/gpio/gpio60 , ou quando você executa cd /sys/class/gpio/gpio60 , isso acessa o diretório para o qual o link simbólico aponta (acesso ao conteúdo do diretório). Isso funciona como raiz, mas não como não-raiz, porque esse diretório é acessível somente para raiz.

Para tornar esse diretório acessível para outros usuários, você precisaria executar chmod … /sys/devices/platform/ocp/4804c000.gpio/gpio/gpio60 .

No entanto, em vez de alterar a propriedade, seria mais simples adicionar seu usuário ao grupo gpio :

adduser dave gpio
    
por 09.01.2016 / 21:55