Passando variáveis ​​de ambiente do udev para execução do serviço systemd

Passando variáveis ​​de ambiente do udev para execução do serviço systemd

Estou migrando uma regra existente do udev que está vinculada à ação de alteração de um dispositivo de bloco e executa um determinado script.

SUBSYSTEM=="block", ENV{DEVNAME}=="/dev/sr0", ACTION=="change", RUN+="/usr/local/bin/script"

Nesta configuração, o udev passou as variáveis ​​de ambiente associadas ao dispositivo de hardware, como ID_CDROM_MEDIA-0e ID_FS_LABEL. Desde então, atualizei a regra do udev para usar o systemd para iniciar um serviço na mudança de hardware.

SUBSYSTEM=="block", ENV{DEVNAME}=="/dev/sr0", ACTION=="change", TAG+="systemd", ENV{SYSTEMD_WANTS}=="drive-change.service"

O arquivo de serviço systemd:

[Unit]
Description=changes to dvd drive

[Service]
Type=oneshot
ExecStart=/usr/local/bin/script

[Install]
WantedBy=multi-user.target

Neste ponto, o serviço é executado em eventos de mudança, mas as variáveis ​​de ambiente passadas pelo comando RUN no udev não são passadas para a execução do serviço.

É possível passar o ambiente do udev para o ambiente de execução do systemd ou preciso passar parâmetros explicitamente?

Responder1

Embora eu não tenha encontrado uma maneira de passar o ambiente do udev para o systemd, é possível consultar o banco de dados do udev para obter as propriedades do ambiente. Oudevadm info comandopossui os parâmetros --querye --exportque permitem consultar apenas as propriedades de um ambiente e imprimi-las em um formato que pode ser avaliado.

Usei uma combinação de variáveis ​​de instância do systemd e udevadmcomandos para inicializar as variáveis ​​de ambiente.

SUBSYSTEM=="block", ENV{DEVNAME}=="/dev/sr0", ACTION=="change", TAG+="systemd", ENV{SYSTEMD_WANTS}=="drive-change@%E{DEVNAME}.service"

Esta regra do udev executará o seguinte arquivo de serviço e passará a DEVNAMEvariável como uma variável de instância com o serviço.

[Unit]
Description=changes to dvd drive

[Service]
Type=oneshot
ExecStart=/usr/local/bin/script %I

[Install]
WantedBy=multi-user.target

Usei esta variável de instância para avaliar as propriedades de ambiente do elemento udev e resolvi meu problema.

#!/bin/sh

# Systemd passes the DEVNAME as the first parameter to the script
eval $(udevadm info --query=env --export $1)

 # The rest of the script that depends on the udev environment
 ...

Responder2

Para estender o granderesponderpor @Ben Campbell..

Veja como acessar uma propriedade do banco de dados do ambiente do udev depois que um dispositivo acionou a regra do udev. Digamos, por exemplo, que uma unidade USB acabou de ser conectada e você deseja obter sua etiqueta.

No script executado pelo serviço systemd, após a eval $(udevadm info --query=env --export $1)linha, adicione algo como:
echo $ID_FS_LABEL >> "/tmp/file.txt"

Da mesma forma, você pode obter os valores para ID_PART_ENTRY_UUID, ID_VENDORetc.

informação relacionada