I'm trying to change the value of /sys/bus/usb/devices/4-3/power/wakeup at every boot (4-3 according to my lsusb, it's the keyboard ID).

The default value is:

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

The classic "online" editing works as expected:

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

I'm using a systemd distro so I'd like to use the systemd-way to edit "temp files"

I have created the following file:

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

but after every boot I still have the default value in this file (i.e. enabled)

Am I doing something wrong?


Here another test:

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

and this one works fine! After booting I get:

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

(the default one was the cfq scheduler)

So, why this one works and the other one doesn't?

  • Because /sys/bus/usb/devices/4-3/power/wakeup is a symlink to /sys/devices/pci0000:00/0000:00:12.1/usb4/4-3/ ?
  • Because /sys/bus/usb/devices/4-3/power/wakeup contains only one word? (i.e. no spaces)
  • 1
    Great question, but nobody is answering it. Regardless of whether it is the right thing to do, questions should be answered with the approach, 'if I were to do this, how would I?" I actually needed the answer to this and found this. Anybody care to answer on the actual question? – Jonathan Komar Mar 25 '15 at 6:56

I don't believe tmpfiles.d is the proper way to go here. You really should do the udev rules. Look:

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':

  looking at parent device '/devices/pci0000:00/0000:00:11.0/ata1/host0':

And it goes on, walking up the parent device tree. But consider that, using just the information above, you can do:

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

And I believe that does it for the majority of your script. You'll want to put the above after rule 60, I think. And really, you should do this for the rest - just the sleep bit in your script is reason enough - it implies a race condition. udev is the one adding and setting these parameters - it's the one that populates sysfs. Just ask it to do the work it is already doing.

And for your keyboard you should definitely do the same - and the backlight. Just get the information you need about these devices from udevadm, write some rules and udevadm test them.

  • At wiki.archlinux.org/index.php/… there is a similar example ACTION=="add", SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_policy}="min_power". Would you please explain why your UDEV rule here doesn't include an ACTION statement and isn't comma separated? – Pro Backup Aug 31 '14 at 22:45
  • @ProBackup - probably cause mine is broken. I don't think the ACTION bit is necessary though. – mikeserv Aug 31 '14 at 23:10
  • To test the link_power_management_policy for example: udevadm test /devices/pci0000:00/0000:00:1f.2/ata1/host0/scsi_host/host0/ – Pro Backup Sep 1 '14 at 2:02
  • This is indeed the proper way to go. People should really use udev rules in cases where synchronisation to device addition/removal events is required. – intelfx Dec 15 '14 at 15:24

[ My original idea that this could be because systemd-tmpfiles uses stream I/O and was not intended to be used with proc or sys is wrong. My 2nd hypothesis, about the significance of a newline, was also wrong... ]

I just looked at /usr/lib/systemd/system/systemd-tmpfiles-setup.service and there's a couple of bits in there that may be of interest:

Description=Recreate Volatile Files and Directories
After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
Before=sysinit.target shutdown.target


ExecStart=/usr/bin/systemd-tmpfiles --create --remove

The 'Wants', 'After', and 'Before' give some information about when this happens; I would think your device is registered by this point, but there could be something subsequent that resets the sysfs value.

The most helpful bit is the ExecStart line, because that's the actual command that accounts for this service. This is actually mentioned in man systemd-tmpfiles:

For example, during boot the following command line is executed to ensure that all temporary and volatile directories are removed and created according to the configuration file:

systemd-tmpfiles --remove --create

So, to test this, set the sysfs value to "enabled" and then try running systemd-tmpfiles --create which will process your 'w' directive in /etc/tmpfiles.d. If that works (it should!), then you know that the systemd-tmpfile method is fine, just you have to do it later in the boot process, perhaps with:


Which means writing your own service file; if for some reason it doesn't work, you can always write a service file for a script to do it with echo.

  • I don't think that systemd can't write on virtual file systems. Using tmpfiles on /proc/acpi/wakeup works fine, for example (wiki.archlinux.org/index.php/Systemd#Temporary_files) – eang Jan 14 '13 at 8:49
  • @ital : I was probably wrong about that, but if you are still frustrated try my second hypothesis above. – goldilocks Jan 14 '13 at 12:46
  • Using echo -n disabled > /sys/... works, so probably the newline presence doesn't care in this case. But tmpfiles is still not working, I've tried both disabled\n and "disabled\n" – eang Jan 14 '13 at 16:50
  • I have edited the first post with another test and some hypothesis. – eang Jan 14 '13 at 17:58
  • @ital Sheesh. Okay, pretty sure my 3rd guess is the lucky one, so I edited that in above again, lol. If after that you need the basics for writing and registering a systemd service, ask a new question and maybe reference this one; I can explain it without all this clutter, we will get some input from others, and the question can stand for posterity (I don't see any here yet that address this very well). – goldilocks Jan 14 '13 at 19:07

I learned recently the hard way that /etc/tmpfiles.d is processed before /sys is populated so you have to create the proper udev rules so they are enable whenever the devices shows up or... go the dirty way (but if you ask me, a more flexible one) and create a service that runs an script with the commands to write into /sys.

Take a look here for an example on how to create such script, https://bbs.archlinux.org/viewtopic.php?id=148170 which you can fill with something like:

#### #!/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

  • Could you post a link confirming your statement about tmpfiles & /sys/ population order? Here is another Arch thread where tmpfiles were suggested. – mlt Oct 19 '15 at 18:55

This may be a bit overkill, but in my case both methods mentioned in other answers were failing. The tmpfiles.d makes the changes before the /sys/ entries are populated and the udev method did not find the entry (which was a virtual network device br0). As such, I created a new service file. Just create a new file /etc/systemd/system/disable-usb-wakeup.service and place the following inside:

Description=Set multicast snoop to off

ExecStart=/usr/bin/bash -c "echo disabled >> /sys/bus/usb/devices/4-3/power/wakeup"
ExecStop=/usr/bin/bash -c "echo enabled >> /sys/bus/usb/devices/4-3/power/wakeup"


Now, to make sure this unit is started on every boot just issue:

# systemctl enable disable-usb-wakeup.service

And you should be good to go.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.