¿Cómo funciona systemd-tmpfiles?

15

Estoy tratando de cambiar el valor de /sys/bus/usb/devices/4-3/power/wakeupen cada arranque (4-3 según mi lsusb, es la identificación del teclado).

El valor predeterminado es:

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

La edición clásica "en línea" funciona como se esperaba:

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

Estoy usando una distribución systemd, así que me gustaría usar systemd-way para editar "archivos temporales"

He creado el siguiente archivo:

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

pero después de cada arranque todavía tengo el valor predeterminado en este archivo (es decir, habilitado)

¿Estoy haciendo algo mal?

EDITAR:

Aquí otra prueba:

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

y este funciona bien! Después de arrancar me sale:

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

(el predeterminado era el planificador cfq)

Entonces, ¿por qué este funciona y el otro no?

  • Porque /sys/bus/usb/devices/4-3/power/wakeupes un enlace simbólico a /sys/devices/pci0000:00/0000:00:12.1/usb4/4-3/?
  • Porque /sys/bus/usb/devices/4-3/power/wakeupcontiene solo una palabra? (es decir, sin espacios)
eang
fuente
1
Gran pregunta, pero nadie la responde. Independientemente de si es el derecho que hay que hacer, las preguntas deben ser respondidas con el enfoque, 'si yo tuviera que hacer esto, ¿cómo sería yo?" Realmente necesitaba la respuesta a esto y encontré esto. A alguien de respuesta en el actual pregunta?
Jonathan Komar

Respuestas:

5

No creo que tmpfiles.dsea ​​la forma correcta de ir aquí. Realmente deberías hacer las udevreglas. Mira:

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

Y continúa, subiendo por el árbol del dispositivo principal. Pero considere que, utilizando solo la información anterior, puede hacer:

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

Y creo que eso lo hace para la mayoría de tu guión. Querrás poner lo anterior después de la regla 60, creo. Y realmente, deberías hacer esto por el resto, solo un sleeppoco en tu script es razón suficiente, implica una condición de carrera. udeves el que agrega y establece estos parámetros, es el que se completa sysfs. Solo pídale que haga el trabajo que ya está haciendo.

Y para su teclado definitivamente debe hacer lo mismo, y la luz de fondo. Simplemente obtenga la información que necesita sobre estos dispositivos udevadm, escriba algunas reglas y udevadm testellas.

mikeserv
fuente
En wiki.archlinux.org/index.php/… hay un ejemplo similar ACTION=="add", SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_policy}="min_power". ¿Podría explicar por qué su regla UDEV aquí no incluye una declaración ACTION y no está separada por comas?
Pro Backup
@ProBackup: probablemente porque el mío está roto. Sin ACTIONembargo , no creo que sea ​​necesario.
mikeserv
Para probar link_power_management_policy por ejemplo:udevadm test /devices/pci0000:00/0000:00:1f.2/ata1/host0/scsi_host/host0/
Pro Backup
Este es de hecho el camino correcto a seguir. La gente realmente debería usar las reglas de udev en los casos en que se requiera la sincronización con eventos de adición / eliminación de dispositivos.
intelfx
2

[Mi idea original de que esto podría deberse a que systemd-tmpfiles usa E / S de flujo y no estaba destinado a usarse con proc o sys es incorrecta . Mi segunda hipótesis, sobre la importancia de una nueva línea, también estaba equivocada ...]

Acabo de mirar /usr/lib/systemd/system/systemd-tmpfiles-setup.servicey hay un par de bits allí que pueden ser de interés:

[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

Los 'Deseos', 'Después' y 'Antes' brindan información sobre cuándo sucede esto; Creo que su dispositivo está registrado en este punto, pero podría haber algo posterior que restablezca el valor de sysfs.

El bit más útil es la línea ExecStart, porque ese es el comando real que da cuenta de este servicio. Esto se menciona realmente en man systemd-tmpfiles:

Por ejemplo, durante el arranque, se ejecuta la siguiente línea de comando para garantizar que todos los directorios temporales y volátiles se eliminen y creen de acuerdo con el archivo de configuración:

systemd-tmpfiles --remove --create

Entonces, para probar esto, establezca el valor de sysfs en "habilitado" y luego intente ejecutar systemd-tmpfiles --createlo que procesará su directiva 'w' en /etc/tmpfiles.d. Si eso funciona (¡debería!), Entonces sabes que el método systemd-tmpfile está bien, solo tienes que hacerlo más adelante en el proceso de arranque, quizás con:

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

Lo que significa escribir su propio archivo de servicio; si por alguna razón no funciona, siempre puede escribir un archivo de servicio para que un script lo haga echo.

encerrada dorada
fuente
No creo que systemd no pueda escribir en sistemas de archivos virtuales. Usar tmpfiles en /proc/acpi/wakeuptrabajos funciona bien, por ejemplo ( wiki.archlinux.org/index.php/Systemd#Temporary_files )
eang
@ital: Probablemente me equivoqué al respecto, pero si todavía estás frustrado, prueba mi segunda hipótesis anterior.
Ricitos de oro
Usando echo -n disabled > /sys/...trabajos, por lo que probablemente la presencia de nueva línea no le importe en este caso. Pero tmpfiles todavía no funciona, he intentado ambos disabled\ny"disabled\n"
desde el
He editado la primera publicación con otra prueba y algunas hipótesis.
Eang
@ital Sheesh. De acuerdo, estoy bastante seguro de que mi tercera suposición es la afortunada, así que edité eso arriba otra vez, jajaja. Si después de eso necesita lo básico para escribir y registrar un servicio systemd, haga una nueva pregunta y quizás haga referencia a esta; Puedo explicarlo sin todo este desorden, obtendremos algunos aportes de otros, y la pregunta puede representar la posteridad (todavía no veo ninguna que aborde esto muy bien).
Ricitos de oro
0

Aprendí recientemente de la manera difícil que /etc/tmpfiles.d se procesa antes de que / sys se complete, por lo que debe crear las reglas udev adecuadas para que estén habilitadas cada vez que aparezcan los dispositivos o ... siga el camino sucio (pero si pregúntame, uno más flexible) y crea un servicio que ejecute un script con los comandos para escribir en / sys.

Eche un vistazo aquí para ver un ejemplo sobre cómo crear dicho script, https://bbs.archlinux.org/viewtopic.php?id=148170 que puede llenar con 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
fuente
¿Podría publicar un enlace que confirme su declaración sobre tmpfiles y / sys / orden de población? Aquí hay otro hilo de Arch donde se sugirieron tmpfiles.
mlt
0

Esto puede ser un poco exagerado, pero en mi caso ambos métodos mencionados en otras respuestas estaban fallando. Luego tmpfiles.d realiza los cambios antes de /sys/que se llenen las entradas y el udevmétodo no encontró la entrada (que era un dispositivo de red virtual br0). Como tal, creé un nuevo archivo de servicio. Simplemente cree un nuevo archivo /etc/systemd/system/disable-usb-wakeup.servicey coloque lo siguiente 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

Ahora, para asegurarse de que esta unidad se inicie en cada arranque, solo emita:

# systemctl enable disable-usb-wakeup.service

Y deberías estar listo para irte.

Acrobacias
fuente