Как работает systemd-tmpfiles?

15

Я пытаюсь изменить значение /sys/bus/usb/devices/4-3/power/wakeupпри каждой загрузке (4-3 по моему lsusb, это идентификатор клавиатуры).

Значение по умолчанию:

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

Классическое «онлайн» редактирование работает как положено:

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

Я использую системный дистрибутив, поэтому я хотел бы использовать системный способ для редактирования "временных файлов"

Я создал следующий файл:

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

но после каждой загрузки у меня все еще есть значение по умолчанию в этом файле (т.е. включено)

Я делаю что-то неправильно?

РЕДАКТИРОВАТЬ:

Вот еще один тест:

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

и этот работает отлично! После загрузки я получаю:

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

(по умолчанию был планировщик cfq)

Итак, почему этот работает, а другой нет?

  • Потому /sys/bus/usb/devices/4-3/power/wakeupчто символическая ссылка на /sys/devices/pci0000:00/0000:00:12.1/usb4/4-3/?
  • Потому что /sys/bus/usb/devices/4-3/power/wakeupсодержит только одно слово? (т.е. без пробелов)
Eang
источник
1
Отличный вопрос, но никто не отвечает на него. Независимо от того, является ли это право , что нужно сделать, вопросы следует ответить с подходом, «если бы я был сделать это, как бы я?» Я на самом деле нужен ответ на этот вопрос и нашел это. Уход никому ответ на фактическое вопрос?
Джонатан Комар

Ответы:

5

Я не верю, tmpfiles.dчто это правильный путь сюда. Вы действительно должны выполнять udevправила. Посмотрите:

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

И это продолжается, поднимаясь по дереву родительского устройства. Но учтите, что, используя только вышеприведенную информацию, вы можете сделать:

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

И я считаю, что это делает для большинства вашего сценария. Я думаю, вы захотите поставить вышесказанное после правила 60. И действительно, вы должны сделать это для остальных - только sleepбит в вашем сценарии является достаточной причиной - это подразумевает состояние гонки. udevэто тот, кто добавляет и устанавливает эти параметры - это тот, который заполняет sysfs. Просто попросите его сделать работу, которую он уже делает.

И для вашей клавиатуры вы обязательно должны сделать то же самое - и подсветку. Просто получите необходимую информацию об этих устройствах udevadm, напишите некоторые правила и udevadm testих.

mikeserv
источник
На wiki.archlinux.org/index.php/… есть похожий пример ACTION=="add", SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_policy}="min_power". Не могли бы вы объяснить, почему ваше правило UDEV здесь не содержит оператора ACTION и не разделено запятыми?
Pro Backup
@ProBackup - вероятно, причина моя сломана. Я не думаю, что ACTIONнемного необходимо, хотя.
mikeserv
Чтобы проверить link_power_management_policy, например:udevadm test /devices/pci0000:00/0000:00:1f.2/ata1/host0/scsi_host/host0/
Pro Backup
Это действительно правильный путь. Люди действительно должны использовать правила udev в тех случаях, когда требуется синхронизация с событиями добавления / удаления устройства.
intelfx
2

[Моя первоначальная идея, что это может быть потому, что systemd-tmpfiles использует потоковый ввод-вывод и не предназначен для использования с proc или sys, неверна . Моя вторая гипотеза о значении новой строки также была неверной ...]

Я только что посмотрел, /usr/lib/systemd/system/systemd-tmpfiles-setup.serviceи есть пара моментов, которые могут быть интересны:

[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

«Хочет», «После» и «До» дают некоторую информацию о том, когда это произойдет; Я бы подумал, что ваше устройство зарегистрировано к этому моменту, но может быть что-то последующее, которое сбрасывает значение sysfs.

Наиболее полезным битом является строка ExecStart, потому что это фактическая команда, которая отвечает за эту службу. Это на самом деле упоминается в man systemd-tmpfiles:

Например, во время загрузки выполняется следующая командная строка, чтобы гарантировать, что все временные и временные каталоги удалены и созданы в соответствии с файлом конфигурации:

systemd-tmpfiles - удалить - создать

Итак, чтобы проверить это, установите значение sysfs в значение «enabled», а затем попробуйте запустить, systemd-tmpfiles --createчто обработает вашу директиву w в /etc/tmpfiles.d. Если это работает (это должно!), То вы знаете, что метод systemd-tmpfile подходит, просто вы должны сделать это позже в процессе загрузки, возможно, с:

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

Что означает написание вашего собственного служебного файла; если по какой-то причине это не сработает, вы всегда можете написать служебный файл для скрипта, с которым будете это делать echo.

лютик золотистый
источник
Я не думаю, что systemd не может писать в виртуальных файловых системах. Например, использование tmpfiles /proc/acpi/wakeupработает нормально ( wiki.archlinux.org/index.php/Systemd#Teilitary_files )
eang
@ital: Вероятно, я ошибался, но если вы все еще разочарованы, попробуйте мою вторую гипотезу выше.
Златовласка
Использование echo -n disabled > /sys/...работает, так что, вероятно, присутствие новой строки не волнует в этом случае. Но tmpfiles все еще не работает, я попробовал и то disabled\nи другое"disabled\n"
eang
Я отредактировал первый пост с другим тестом и некоторой гипотезой.
2003 г.
@ital Sheesh. Хорошо, я уверен, что мое третье предположение - удачное, поэтому я снова отредактировал это, лол. Если после этого вам понадобятся основы для написания и регистрации службы systemd, задайте новый вопрос и, возможно, обратитесь к нему; Я могу объяснить это без всего этого беспорядка, мы получим некоторую информацию от других, и этот вопрос может означать потомство (я пока не вижу здесь ни одного, который бы очень хорошо решал этот вопрос).
Златовласка
0

Недавно я узнал о сложном способе обработки /etc/tmpfiles.d перед заполнением / sys, поэтому вам нужно создать правильные правила udev, чтобы они включались всякий раз, когда появляются устройства или ... пошли грязным путем (но если вы спросите меня, более гибкий) и создайте сервис, который запускает скрипт с командами для записи в / sys.

Посмотрите здесь пример того, как создать такой скрипт, https://bbs.archlinux.org/viewtopic.php?id=148170, который вы можете заполнить примерно так:

#### #!/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
источник
Не могли бы вы опубликовать ссылку, подтверждающую ваше заявление о порядке tmpfiles & / sys / население? Вот еще одна ветка Arch, где были предложены tmpfiles.
MLT
0

Это может быть немного излишним, но в моем случае оба метода, упомянутые в других ответах, терпели неудачу. tmpfiles.d Делает изменения до того , как /sys/записи заполняются и udevметод не нашел запись (которая была виртуальное сетевое устройство br0). Таким образом, я создал новый файл службы. Просто создайте новый файл /etc/systemd/system/disable-usb-wakeup.serviceи поместите в него следующее:

[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

Теперь, чтобы убедиться, что этот модуль запускается при каждой загрузке, просто выпустите:

# systemctl enable disable-usb-wakeup.service

И тебе должно быть хорошо идти.

Трюки
источник