Comment fonctionne systemd-tmpfiles?

15

J'essaie de changer la valeur de /sys/bus/usb/devices/4-3/power/wakeupà chaque démarrage (4-3 selon moi lsusb, c'est l'ID du clavier).

La valeur par défaut est:

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

L'édition classique "en ligne" fonctionne comme prévu:

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

J'utilise une distribution systemd donc j'aimerais utiliser la méthode systemd pour éditer des "fichiers temporaires"

J'ai créé le fichier suivant:

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

mais après chaque démarrage, j'ai toujours la valeur par défaut dans ce fichier (c'est-à-dire activée)

Est-ce que je fais quelque chose de mal?

ÉDITER:

Voici un autre test:

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

et celui-ci fonctionne très bien! Après le démarrage, j'obtiens:

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

(celui par défaut était le planificateur cfq)

Alors, pourquoi celui-ci fonctionne et l'autre non?

  • Car /sys/bus/usb/devices/4-3/power/wakeupest un lien symbolique vers /sys/devices/pci0000:00/0000:00:12.1/usb4/4-3/?
  • Parce qu'il /sys/bus/usb/devices/4-3/power/wakeupne contient qu'un seul mot? (c.-à-d. sans espaces)
eang
la source
1
Excellente question, mais personne n'y répond. Peu importe que ce soit la bonne chose à faire, les questions doivent répondre à l'approche, si je devais le faire, comment serait - je? » En fait , je besoin de la réponse à cette question et a trouvé cela. Quelqu'un voudra- t de réponse sur la réelle question?
Jonathan Komar

Réponses:

5

Je ne crois pas que ce tmpfiles.dsoit la bonne façon d'aller ici. Vous devriez vraiment suivre les udevrègles. Regardez:

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

Et cela continue, en remontant l'arborescence des périphériques parents. Mais considérez que, en utilisant uniquement les informations ci-dessus, vous pouvez faire:

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

Et je crois que cela le fait pour la majorité de votre script. Vous voudrez mettre ce qui précède après la règle 60, je pense. Et vraiment, vous devriez le faire pour le reste - juste le sleepbit dans votre script est une raison suffisante - cela implique une condition de concurrence. udevest celui qui ajoute et définit ces paramètres - c'est celui qui remplit sysfs. Demandez-lui simplement de faire le travail qu'il fait déjà.

Et pour votre clavier, vous devriez certainement faire de même - et le rétro-éclairage. Obtenez simplement les informations dont vous avez besoin sur ces appareils udevadm, écrivez quelques règles et udevadm testcelles - ci.

mikeserv
la source
Sur wiki.archlinux.org/index.php/… il y a un exemple similaire ACTION=="add", SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_policy}="min_power". Pourriez-vous expliquer pourquoi votre règle UDEV n'inclut pas d'instruction ACTION et n'est pas séparée par des virgules?
Pro Backup
@ProBackup - probablement parce que le mien est cassé. Je ne pense pas que le ACTIONbit soit nécessaire cependant.
mikeserv
Pour tester la link_power_management_policy par exemple:udevadm test /devices/pci0000:00/0000:00:1f.2/ata1/host0/scsi_host/host0/
Pro Backup
C'est en effet la bonne façon de procéder. Les gens devraient vraiment utiliser les règles udev dans les cas où la synchronisation avec les événements d'ajout / suppression de périphérique est requise.
intelfx
2

[Mon idée originale que cela pourrait être dû au fait que systemd-tmpfiles utilise les E / S de flux et n'était pas destinée à être utilisée avec proc ou sys est erronée . Ma 2e hypothèse, sur la signification d'une nouvelle ligne, était également fausse ...]

Je viens de regarder /usr/lib/systemd/system/systemd-tmpfiles-setup.serviceet il y a quelques morceaux qui peuvent être intéressants:

[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

Les «Veut», «Après» et «Avant» donnent des informations sur le moment où cela se produit; Je pense que votre appareil est enregistré à ce stade, mais il pourrait y avoir quelque chose par la suite qui réinitialise la valeur sysfs.

Le bit le plus utile est la ligne ExecStart, car c'est la commande réelle qui représente ce service. Ceci est en fait mentionné dans man systemd-tmpfiles:

Par exemple, lors du démarrage, la ligne de commande suivante est exécutée pour garantir que tous les répertoires temporaires et volatils sont supprimés et créés conformément au fichier de configuration:

systemd-tmpfiles --remove --create

Donc, pour tester cela, définissez la valeur sysfs sur "enabled", puis essayez d'exécuter systemd-tmpfiles --createqui traitera votre directive "w" dans /etc/tmpfiles.d. Si cela fonctionne (cela devrait!), Alors vous savez que la méthode systemd-tmpfile est très bien, il vous suffit de le faire plus tard dans le processus de démarrage, peut-être avec:

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

Ce qui signifie écrire votre propre fichier de service; si pour une raison quelconque cela ne fonctionne pas, vous pouvez toujours écrire un fichier de service pour un script pour le faire echo.

boucle d'or
la source
Je ne pense pas que systemd ne puisse pas écrire sur des systèmes de fichiers virtuels. L'utilisation de tmpfiles sur /proc/acpi/wakeupfonctionne bien, par exemple ( wiki.archlinux.org/index.php/Systemd#Temporary_files )
eang
@ital: J'avais probablement tort à ce sujet, mais si vous êtes toujours frustré, essayez ma deuxième hypothèse ci-dessus.
goldilocks
Utiliser des echo -n disabled > /sys/...œuvres, donc probablement la présence de la nouvelle ligne ne se soucie pas dans ce cas. Mais tmpfiles ne fonctionne toujours pas, j'ai essayé les deux disabled\net"disabled\n"
eang
J'ai édité le premier post avec un autre test et quelques hypothèses.
eang
@ital Sheesh. D'accord, je suis quasiment sûr que ma 3ème supposition est la plus chanceuse, j'ai donc modifié cela plus haut, lol. Si après cela vous avez besoin des bases pour écrire et enregistrer un service systemd, posez une nouvelle question et peut-être référencez-la; Je peux l'expliquer sans tout cet encombrement, nous obtiendrons des commentaires des autres, et la question peut représenter la postérité (je n'en vois pas encore ici qui traite très bien de cela).
goldilocks
0

J'ai récemment appris à la dure comment /etc/tmpfiles.d est traité avant que / sys ne soit rempli, vous devez donc créer les règles udev appropriées pour qu'elles soient activées chaque fois que les périphériques apparaissent ou ... vont dans le mauvais sens (mais si vous demandez-moi, plus flexible) et créez un service qui exécute un script avec les commandes à écrire dans / sys.

Jetez un œil ici pour un exemple sur la façon de créer un tel script, https://bbs.archlinux.org/viewtopic.php?id=148170 que vous pouvez remplir avec quelque chose comme:

#### #!/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
la source
Pourriez-vous poster un lien confirmant votre déclaration sur l'ordre des fichiers tmpfiles & / sys / population? Voici un autre thread Arch où les fichiers tmp ont été suggérés.
mlt
0

Cela peut être un peu exagéré, mais dans mon cas, les deux méthodes mentionnées dans d'autres réponses ont échoué. Le tmpfiles.d effectue les modifications avant que les /sys/entrées ne soient remplies et la udevméthode n'a pas trouvé l'entrée (qui était un périphérique réseau virtuel br0). En tant que tel, j'ai créé un nouveau fichier de service. Créez simplement un nouveau fichier /etc/systemd/system/disable-usb-wakeup.serviceet placez ce qui suit à l'intérieur:

[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

Maintenant, pour vous assurer que cette unité est démarrée à chaque démarrage, lancez simplement:

# systemctl enable disable-usb-wakeup.service

Et vous devriez être prêt à partir.

Cascades
la source