Como o systemd-tmpfiles funciona?

15

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

O valor padrão é:

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

A edição "online" clássica 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, então eu gostaria de usar o systemd-way para 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 está outro teste:

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

e este 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 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/wakeupcontém apenas uma palavra? (ou seja, sem espaços)
eang
fonte
1
Ótima pergunta, mas ninguém está respondendo. Independentemente de saber se é o direito coisa a fazer, as perguntas devem ser respondidas com a abordagem, 'se eu fosse fazer isso, como seria eu?" Na verdade, eu precisava da resposta a esta e encontrei este. Cuidado ninguém a resposta sobre o real pergunta?
Jonathan Komar 25/03

Respostas:

5

Eu não acredito que tmpfiles.dseja o caminho certo a seguir aqui. Você realmente deve fazer as udevregras. Veja:

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 na árvore do dispositivo pai. Mas considere que, usando apenas as informações acima, você pode:

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

E acredito que isso seja feito pela maioria do seu script. Você vai querer colocar o que precede após a regra 60, eu acho. E realmente, você deve fazer isso pelo resto - apenas a parte sleepdo seu script é motivo suficiente - implica uma condição de corrida. udevé quem adiciona e define esses parâmetros - é o que preenche sysfs. Apenas peça para fazer o trabalho que já está fazendo.

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

mikeserv
fonte
No wiki.archlinux.org/index.php/…, há um exemplo semelhante ACTION=="add", SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_policy}="min_power". Você poderia explicar por que sua regra UDEV aqui não inclui uma instrução ACTION e não é separada por vírgula?
Pro Backup
@ ProBackup - provavelmente porque o meu está quebrado. Eu não acho que a parte ACTIONseja necessária.
mikeserv
Para testar o link_power_management_policy, por exemplo:udevadm test /devices/pci0000:00/0000:00:1f.2/ata1/host0/scsi_host/host0/
Pro Backup
Este é realmente o caminho certo a seguir. As pessoas realmente devem usar as regras do udev nos casos em que a sincronização com os eventos de adição / remoção de dispositivos é necessária.
Intelfx
2

[Minha ideia original de que isso poderia ocorrer porque systemd-tmpfiles usa E / S de fluxo e não foi projetada para ser usada com proc ou sys está errada . Minha segunda hipótese, sobre o significado de uma nova linha, também estava errada ...]

Acabei de olhar /usr/lib/systemd/system/systemd-tmpfiles-setup.servicee há alguns bits que podem ser interessantes:

[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 'Quer', 'Depois' e 'Antes' 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 do sysfs.

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

Por exemplo, durante a inicialização, a seguinte linha de comando é executada para garantir que todos os diretórios temporários e voláteis sejam removidos e criados de acordo com o arquivo de configuração:

systemd-tmpfiles --remove --create

Portanto, para testar isso, defina o valor sysfs como "enabled" e tente executar o systemd-tmpfiles --createque processará sua diretiva 'w' em /etc/tmpfiles.d. Se isso funcionar (deveria!), Você saberá que o método systemd-tmpfile está correto, basta fazê-lo posteriormente 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 poderá escrever um arquivo de serviço para um script echo.

Cachinhos Dourados
fonte
Eu não acho que o systemd não possa escrever em sistemas de arquivos virtuais. O uso do tmpfiles no /proc/acpi/wakeupfunciona bem, por exemplo ( wiki.archlinux.org/index.php/Systemd#Temporary_files )
eang
@ital: Eu provavelmente estava errado sobre isso, mas se você ainda está frustrado, tente minha segunda hipótese acima.
Janelas
Usando echo -n disabled > /sys/...obras, provavelmente a presença da nova linha não se importa nesse caso. Mas tmpfiles ainda não está funcionando, eu tentei os dois disabled\ne"disabled\n"
eang
Eu editei o primeiro post com outro teste e algumas hipóteses.
Eang
@ital Sheesh. Ok, tenho certeza que meu terceiro palpite é o sortudo, então eu editei isso acima novamente, lol. Se depois disso você precisar do básico para escrever e registrar um serviço systemd, faça uma nova pergunta e talvez faça referência a esta; Eu posso explicar isso sem toda essa confusão, receberemos algumas opiniões de outras pessoas e a pergunta pode representar uma posteridade (ainda não vejo nenhuma aqui que resolva isso muito bem).
Janelas
0

Eu aprendi recentemente da maneira mais difícil que o /etc/tmpfiles.d é processado antes que o / sys seja preenchido, então você precisa criar as regras udev adequadas para que elas sejam ativadas sempre que os dispositivos aparecerem ou ... sigam o caminho sujo (mas se você pergunte-me, mais flexível) e crie um serviço que execute um script com os comandos para gravar em / sys.

Veja aqui um exemplo de como criar esse script, https://bbs.archlinux.org/viewtopic.php?id=148170 , 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

...
cig0
fonte
Você poderia postar um link confirmando sua declaração sobre a ordem dos arquivos tmpfiles e / sys / população? Aqui está outro tópico do Arch, onde tmpfiles foram sugeridos.
Mlt
0

Isso pode ser um pouco exagerado, mas no meu caso os dois métodos mencionados em outras respostas estavam falhando. Ele tmpfiles.d faz as alterações antes que as /sys/entradas sejam preenchidas e o udevmétodo não encontrou 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.servicee 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 esta unidade seja iniciada em cada problema de inicialização:

# systemctl enable disable-usb-wakeup.service

E você deve estar pronto para ir.

Acrobacias
fonte