systemd-tmpfiles는 어떻게 작동하나요?

systemd-tmpfiles는 어떻게 작동하나요?

부팅할 때마다 변경 하려는 값입니다 /sys/bus/usb/devices/4-3/power/wakeup(4-3에 따르면 lsusb키보드 ID입니다).

기본값은 다음과 같습니다.

# 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

나는 systemd 배포판을 사용하고 있으므로 사용하고 싶습니다."임시 파일"을 편집하는 체계적인 방법

다음 파일을 만들었습니다.

# 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한 단어만 포함되어 있기 때문에 ? (즉, 공백 없음)

답변1

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.

답변2

[내 초기 생각은 systemd-tmpfiles가 스트림 I/O를 사용하고 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 --delete--create

따라서 이를 테스트하려면 sysfs 값을 "enabled"로 설정하고 systemd-tmpfiles --create/etc/tmpfiles.d의 "w" 지시문을 처리하는 실행을 시도하십시오. 이것이 효과가 있다면(해야 합니다!) 그렇다면 systemd-tmpfile 접근 방식이 괜찮다는 것을 알 수 있습니다. 부팅 프로세스 후반에 다음을 사용하여 수행해야 한다는 것입니다.

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

이는 자신만의 서비스 파일을 작성하는 것을 의미합니다. 어떤 이유로든 작동하지 않으면 언제든지 스크립트에서 사용할 서비스 파일을 작성할 수 있습니다 echo.

답변3

나는 최근 /sys가 채워지기 전에 /etc/tmpfiles.d가 처리되는 어려운 방법을 배웠으므로 장치가 나타날 때마다 활성화되도록 올바른 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

...

답변4

이것은 약간 과잉일 수 있지만 제 경우에는 다른 답변에서 언급된 두 가지 방법이 모두 실패했습니다. 이것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

가셔도 좋습니다.

관련 정보