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

ฉันใช้ systemd distro ดังนั้นฉันต้องการใช้systemd-way เพื่อแก้ไข "temp files"

ฉันได้สร้างไฟล์ต่อไปนี้:

# 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 scheduler)

เหตุใดจึงใช้งานได้และอีกอันไม่ทำงาน

  • เพราะ/sys/bus/usb/devices/4-3/power/wakeupsymlink /sys/devices/pci0000:00/0000:00:12.1/usb4/4-3/คืออะไร
  • เพราะ/sys/bus/usb/devices/4-3/power/wakeupมีเพียงคำเดียว? (เช่นไม่มีที่ว่าง)

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พวกเขา


ที่wiki.archlinux.org/index.php/...ACTION=="add", SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_policy}="min_power"มีเป็นตัวอย่างที่คล้ายกัน คุณกรุณาอธิบายว่าทำไมกฎ UDEV ของคุณที่นี่ไม่รวมคำสั่ง ACTION และไม่คั่นด้วยเครื่องหมายจุลภาค?
สำรองข้อมูล Pro

@ProBackup - อาจเป็นสาเหตุให้เหมืองเสียหาย ฉันไม่คิดว่าACTIONจำเป็นต้องใช้บิต
mikeserv

เพื่อทดสอบ link_power_management_policy ตัวอย่างเช่น:udevadm test /devices/pci0000:00/0000:00:1f.2/ata1/host0/scsi_host/host0/
สำรองข้อมูล Pro

นี่เป็นวิธีที่เหมาะสมในการไป ผู้ใช้ควรใช้กฎ udev ในกรณีที่จำเป็นต้องมีการซิงโครไนซ์กับการเพิ่ม / กำจัดเหตุการณ์ของอุปกรณ์
intelfx

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 - ลบ - สร้าง

ดังนั้นในการทดสอบให้ตั้งค่า 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#Temporary_files )
Eang

@ital: ฉันอาจจะผิดเกี่ยวกับเรื่องนี้ แต่ถ้าคุณยังคงผิดหวังลองสมมติฐานที่สองของฉันข้างต้น
goldilocks

การใช้echo -n disabled > /sys/...งานดังนั้นการแสดงตนขึ้นบรรทัดใหม่อาจไม่สนใจในกรณีนี้ แต่ tmpfiles ยังไม่ทำงานฉันได้ลองทั้งสองอย่างdisabled\nแล้ว"disabled\n"
eang

ฉันได้แก้ไขโพสต์แรกด้วยการทดสอบอื่นและสมมติฐานบางอย่าง
eang

@ital Sheesh โอเคค่อนข้างแน่ใจว่าการเดาครั้งที่ 3 ของฉันคือวันที่โชคดีดังนั้นฉันจึงแก้ไขในข้างต้นอีกครั้งฮ่า ๆ หากหลังจากนั้นคุณต้องมีพื้นฐานการเขียนและการลงทะเบียนเซอร์วิส systemd ให้ถามคำถามใหม่และอาจอ้างอิงถึงบริการนี้ ฉันสามารถอธิบายได้โดยไม่มีความยุ่งเหยิงทั้งหมดนี้เราจะได้ข้อมูลจากคนอื่นและคำถามนั้นสามารถยืนหยัดเพื่อลูกหลาน (ฉันไม่เห็นที่นี่เลยที่อยู่นี้ดีมาก)
goldilocks

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

...

คุณสามารถโพสต์ลิงค์เพื่อยืนยันคำสั่งของคุณเกี่ยวกับคำสั่ง tmpfiles & / sys / population ได้หรือไม่ นี่คือหัวข้อ 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

และคุณควรจะไปดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.