systemd-tmpfiles如何工作?


15

我正在尝试/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发行版,所以我想使用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
很好的问题,但是没有人回答。无论它是否是正确的做事情,问题应与方法来回答,“如果我这样做,怎么我?”我确实需要这个问题的答案,并发现这一点。任何人都可以回答实际问题吗
乔纳森·科玛

Answers:


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 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 2014年

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,它将处理/etc/tmpfiles.d中的“ w”指令。 如果这行得通(应该!),那么您知道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 2013年

使用echo -n disabled > /sys/...Works,因此在这种情况下可能不需要换行。但是tmpfiles仍然无法正常工作,我已经尝试了两者,disabled\n并且"disabled\n"
2013年

我用另一个检验和一些假设编辑了第一篇文章。
2013年

@ital Sheesh。好的,可以肯定的是,我的第3个猜测是幸运的,所以我在上面再次进行了编辑,哈哈。如果之后您需要编写和注册系统服务的基础知识,请提出一个新问题,并可能参考此问题。我可以在没有所有这些混乱情况的情况下进行解释,我们会从其他人那里得到一些意见,这个问题可以代表后代(我在这里看不到任何可以很好解决的问题)。
goldilocks 2013年

0

我最近了解到在/ 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

...

您能否发布一个链接来确认有关tmpfiles和/ sys /填充顺序的声明?这是建议使用tmpfiles的另一个Arch线程
mlt 2015年

0

这可能有点矫kill过正,但就我而言,其他答案中提到的两种方法都失败了。将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

而且您应该很好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.