Como o systemd-tmpfiles funciona?

15

Estou tentando alterar o valor de /sys/bus/usb/devices/4-3/power/wakeup em cada inicialização (4-3 de acordo com meu lsusb , é o ID do teclado).

O valor padrão é:

# cat /sys/bus/usb/devices/4-3/power/wakeup
enabled

A edição clássica "online" funciona como esperado:

# echo disabled > /sys/bus/usb/devices/4-3/power/wakeup
# cat /sys/bus/usb/devices/4-3/power/wakeup
disabled

Estou usando uma distribuição do systemd, por isso gostaria de usar a maneira do systemd editar "arquivos temporários"

Eu criei o seguinte arquivo:

# cat /etc/tmpfiles.d/disable-usb-wakeup.conf 
w /sys/bus/usb/devices/4-3/power/wakeup - - - - disabled

mas após cada inicialização ainda tenho o valor padrão neste arquivo (ou seja, ativado)

Estou fazendo algo errado?

EDITAR:

Aqui outro teste:

# cat /etc/tmpfiles.d/scheduler.conf 
w /sys/block/sda/queue/scheduler - - - - deadline

e este aqui funciona bem! Após a inicialização, recebo:

# cat /sys/block/sda/queue/scheduler 
noop [deadline] cfq 

(o padrão era o planejador cfq)

Então, por que esse aqui funciona e o outro não?

  • Porque /sys/bus/usb/devices/4-3/power/wakeup é um link simbólico para /sys/devices/pci0000:00/0000:00:12.1/usb4/4-3/ ?
  • Porque /sys/bus/usb/devices/4-3/power/wakeup contém apenas uma palavra? (isto é, sem espaços)
por eang 13.01.2013 / 19:57

4 respostas

5

Eu não acredito que tmpfiles.d seja o caminho certo para ir até aqui. Você realmente deve fazer as regras udev . Olhe:

udevadm info -a -p /sys/class/scsi_host/host*

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:11.0/ata1/host0/scsi_host/host0':
    KERNEL=="host0"
    SUBSYSTEM=="scsi_host"
    DRIVER==""
    ATTR{unchecked_isa_dma}=="0"
    ATTR{state}=="running"
    ATTR{cmd_per_lun}=="1"
...
    ATTR{ahci_host_version}=="10200"
    ATTR{prot_guard_type}=="0"
    ATTR{eh_deadline}=="off"
    ATTR{link_power_management_policy}=="max_performance"
    ATTR{host_busy}=="0"

  looking at parent device '/devices/pci0000:00/0000:00:11.0/ata1/host0':
    KERNELS=="host0"
    SUBSYSTEMS=="scsi"
    DRIVERS==""
...

E continua, subindo a árvore de dispositivos pai. Mas considere que, usando apenas as informações acima, você pode fazer:

KERNEL=="host[0-5]", SUBSYSTEM=="scsi_host", ATTR{link_power_management_policy}="min_power"

E eu acredito que isso é para a maioria do seu roteiro. Você vai querer colocar o acima após a regra 60, eu acho. E realmente, você deve fazer isso para o resto - só o sleep bit no seu script é motivo suficiente - isso implica em uma condição de corrida. udev é o único que adiciona e define esses parâmetros - é o que preenche sysfs . Basta pedir para fazer o trabalho que já está fazendo.

E para o seu teclado, você definitivamente deveria fazer o mesmo - e a luz de fundo. Basta obter as informações necessárias sobre esses dispositivos em udevadm , escrever algumas regras e udevadm test delas.

    
por 19.08.2014 / 12:41
2

[Minha idéia original de que isto poderia ser porque o systemd-tmpfiles usa fluxo de E / S e não foi planejado para ser usado com proc ou sys é errado . Minha segunda hipótese, sobre o significado de uma nova linha, também estava errada ...]

Eu olhei apenas para /usr/lib/systemd/system/systemd-tmpfiles-setup.service e há alguns bits que podem ser de interesse:

[Unit]
Description=Recreate Volatile Files and Directories
Documentation=man:tmpfiles.d(5)
DefaultDependencies=no
Wants=local-fs.target
After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
Before=sysinit.target shutdown.target

[...]

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/systemd-tmpfiles --create --remove

O 'Wants', 'After' e 'Before' fornecem algumas informações sobre quando isso acontece; Eu acho que seu dispositivo está registrado por este ponto, mas pode haver algo subseqüente que redefina o valor sysfs.

O bit mais útil é a linha ExecStart, porque esse é o comando real responsável por esse serviço. Isso é realmente mencionado em man systemd-tmpfiles :

For example, during boot the following command line is executed to ensure that all temporary and volatile directories are removed and created according to the configuration file:

systemd-tmpfiles --remove --create

Portanto, para testar isso, defina o valor sysfs como "enabled" e tente executar systemd-tmpfiles --create , que processará sua diretiva 'w' em /etc/tmpfiles.d. Se isso funciona (deve!), então você sabe que o método systemd-tmpfile está bem, só você tem que fazer isso mais tarde no processo de inicialização, talvez com:

Requires=multi-user.target
After=multi-user.target

O que significa escrever seu próprio arquivo de serviço; Se por algum motivo não funcionar, você sempre pode escrever um arquivo de serviço para um script para fazer isso com echo .

    
por 13.01.2013 / 20:49
0

Eu aprendi recentemente da maneira mais difícil que o /etc/tmpfiles.d é processado antes do / sys ser preenchido, então você deve criar as regras apropriadas do udev para que elas sejam ativadas sempre que os dispositivos aparecerem ou ... mas se você me perguntar, um mais flexível) e criar um serviço que execute um script com os comandos para escrever em / sys.

Veja aqui um exemplo de como criar esse script, link que você pode preencher com algo como:

#### #!/bin/sh

sleep 2

#### # Enforce energy tweaks provided by PowerTop
echo min_power > /sys/class/scsi_host/host0/link_power_management_policy;
echo min_power > /sys/class/scsi_host/host1/link_power_management_policy;
echo min_power > /sys/class/scsi_host/host2/link_power_management_policy;
echo min_power > /sys/class/scsi_host/host3/link_power_management_policy;
echo min_power > /sys/class/scsi_host/host4/link_power_management_policy;
echo min_power > /sys/class/scsi_host/host5/link_power_management_policy;
echo 1 > /sys/module/snd_hda_intel/parameters/power_save;
echo auto > /sys/bus/pci/devices/0000:7f:00.1/power/control;
echo auto > /sys/bus/pci/devices/0000:01:00.1/power/control;

...

echo 4880 > /sys/class/backlight/intel_backlight/brightness

...
    
por 19.08.2014 / 10:19
0

Isso pode ser um pouco exagerado, mas no meu caso, os dois métodos mencionados em outras respostas estavam falhando. A tmpfiles.d faz as alterações antes que as entradas /sys/ sejam preenchidas e o método udev tenha sido não encontra a entrada (que era um dispositivo de rede virtual br0 ). Como tal, criei um novo arquivo de serviço. Basta criar um novo arquivo /etc/systemd/system/disable-usb-wakeup.service e colocar o seguinte dentro:

[Unit]
Description=Set multicast snoop to off
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/bash -c "echo disabled >> /sys/bus/usb/devices/4-3/power/wakeup"
RemainAfterExit=true
ExecStop=/usr/bin/bash -c "echo enabled >> /sys/bus/usb/devices/4-3/power/wakeup"
StandardOutput=journal

[Install]
WantedBy=multi-user.target

Agora, para garantir que essa unidade seja iniciada em todos os casos de inicialização:

# systemctl enable disable-usb-wakeup.service

E você deve ser bom para ir.

    
por 01.09.2017 / 01:52