17

I disabled most of my entries in /proc/acpi/wakeup/ to make sure only the power button and the laptop lid can resume my system, not the mouse or keyboard. The problem is: every time I reboot, the settings are reset for some reason.

Is there a way to make these changes permanent? There are some workaround out there that just put the commands into a script hooked to some wakeup routine, but is there really no other solution?

I'm using a Debian/Gnome Windows 10 dual boot laptop

piegames
  • 797
  • 1
  • 9
  • 21
  • Can you set it in the bios? Or uefi as it probably is now.. – Guy Jan 19 '18 at 12:49
  • Nope I checked all my BIOS settings and found nothing helpful there – piegames Jan 19 '18 at 14:44
  • 1
    old question, but for people looking for a modern solution, you can use systemd-tmpfiles (as explained there : https://wiki.archlinux.org/index.php/systemd#systemd-tmpfiles_-_temporary_files) – tbrugere Apr 29 '21 at 10:15

8 Answers8

20

For a USB mouse or keyboard, you can use a udev rule to make the setting permanent. First, look up the PCI vendor ID of your mouse/keyboard using lsusb. For my mouse, it's 046d:

Bus 001 Device 006: ID 046d:c52b Logitech, Inc. Unifying Receiver

Then create a "rules" file like my /etc/udev/rules.d/logitech.rules, only replace "046d" with the vendor ID of your own device:

ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTR{power/wakeup}="disabled"
John Lindgren
  • 465
  • 4
  • 6
  • 2
    I believe this is the correct answer. And it is preferable for modern systems unlike the `/etc/rc.local` solution suggested below. – scrutari Dec 04 '20 at 19:41
  • 1
    It could help to reload the rule: `udevadm control --reload-rules` – sanmai May 17 '21 at 00:15
  • 2
    I think you should use `ATTRS{idProduct}=="c52b"` there, too, in case there are more than one product from the same vendor. – jarno Nov 02 '21 at 18:04
  • I have [an issue](https://askubuntu.com/q/1373624/21005) with this kind of rule. – jarno Nov 04 '21 at 20:50
3

The preferred way to do this is by creating a service with systemd.
Adding script in rc.local is the deprecated way.

  1. Create a script file wherever you wish. Ex: ~/scripts/disable-devices-as-wakeup.sh.
#!/bin/bash

declare -a devices=(XHC OCH1 USB1 USB2) # <-- Add your entries here
for device in "${devices[@]}"; do
    if grep -qw ^$device.*enabled /proc/acpi/wakeup; then
        sudo sh -c "echo $device > /proc/acpi/wakeup"
    fi
done
  1. Test it by executing it from the terminal.

  2. If everything is okay then let's make a service.

$ touch ~/scripts/disable-devices-as-wakeup.service

~/scripts/disable-devices-as-wakeup.service -

[Unit]
Description=Disable devices as wakeup

[Service]
ExecStart=/home/username/scripts/disable-devices-as-wakeup.sh
Type=oneshot

[Install]
WantedBy=multi-user.target
  1. Copy or move the service to /etc/systemd/system/.
$ sudo cp ~/scripts/disable-devices-as-wakeup.service /etc/systemd/system/
  1. Enable the service.
$ systemctl enable disable-devices-as-wakeup.service
  1. Restart the OS and check the status.
$ systemctl status disable-devices-as-wakeup.service

Detailed explanation found on https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/chap-managing_services_with_systemd

Hrishikesh Kadam
  • 367
  • 3
  • 10
  • If you have a SELinux enabled distro (like fedora) be sure to 1. create the Service directly under `/etc/systemd/system/` and not copy it there 2. create the script not under your home directory, but i.e. under `/usr/local/bin/` Otherwise you will have problems with the SELinux context. Either Systemd will not find your service file or it won't execute the script because Systemd isn't permitted to execute files lying in home directories. – Gero Jul 25 '21 at 10:39
2

acpitool can be used for this apt install acpitool

And then

sudo acpitool -W [some number]

where some number is device id from /proc/acpi/wakeup

maciej@michal:~$ sudo acpitool -W 22
  Changed status for wakeup device #22 (UHC6)

   Device   S-state   Status   Sysfs node
  ---------------------------------------
  1. PCE2     S4    *disabled  pci:0000:00:02.0
  2. PCE3     S4    *disabled
  3. PCE4     S4    *disabled  pci:0000:00:04.0
  4. RLAN     S4    *enabled   pci:0000:02:00.0
  5. PCE5     S4    *disabled
  6. PCE6     S4    *disabled
  7. PCE7     S4    *disabled  pci:0000:00:07.0
  8. PCE9     S4    *disabled
  9. PCEA     S4    *disabled
  10. PCEB    S4    *disabled
  11. PCEC    S4    *disabled
  12. SBAZ    S4    *disabled  pci:0000:00:14.2
  13. PS2K    S4    *disabled
  14. PS2M    S4    *disabled
  15. UAR1    S4    *disabled  pnp:00:03
  16. P0PC    S4    *disabled  pci:0000:00:14.4
  17. UHC1    S4    *disabled  pci:0000:00:12.0
  18. UHC2    S4    *disabled  pci:0000:00:12.1
  19. UHC3    S4    *disabled  pci:0000:00:12.2
  20. USB4    S4    *disabled  pci:0000:00:13.0
  21. UHC5    S4    *disabled  pci:0000:00:13.1
  22. UHC6    S4    *disabled  pci:0000:00:13.2
  23. UHC7    S4    *enabled   pci:0000:00:14.5
Kalle Richter
  • 2,100
  • 4
  • 20
  • 37
matcheek
  • 718
  • 10
  • 17
1

Eric Garrido has a script in /etc/rc.local that echo's those devices that are allowed to wake up his system, to /proc/acpi/wakeup.

for i in `/bin/grep USB /proc/acpi/wakeup | /usr/bin/awk '{print $1}'`; 
do 
    echo $i > /proc/acpi/wakeup; 
done
muru
  • 69,900
  • 13
  • 192
  • 292
Gerard H. Pille
  • 2,350
  • 9
  • 13
1

I decided to create script in /usr/lib/systemd/system-sleep/

according to man page systemd will run it just before suspend.

0

The /proc is a virtual file system containing runtime system info. So its content resets on reboot.

// Edit: Setup a udev rule or create a script echoing the right values to the /proc/acpi/wakeup/ on start up.

Yuri
  • 419
  • 3
  • 14
  • So, how *exactly* do I set `OHC1` to `disabled` in `/proc/acpi/wakeup`? – piegames Jan 18 '18 at 09:34
  • Sorry, @piegames, this seems to require a script triggered on startup (in your case via *systemd*). The script really just needs to `echo` the values to `/proc/acpi/wakeup`. This should give you the idea: https://linuxconfig.org/how-to-automatically-execute-shell-script-at-startup-boot-on-systemd-linux – Yuri Jan 18 '18 at 20:48
  • The systemd service unit running a script did the job for me. Please update your answer so that it also works without the links. – piegames Jan 23 '18 at 22:41
  • Okay it does not work completely: although the script works fine, changes to EHC3 (the one with my mouse on it) does not work when calling the script. I still need to call the command manually as su. – piegames Jan 24 '18 at 13:35
  • @piegames If you have to run it as `su`, you can specify exec time user for the service via `User=root`. It should help to resolve an access rights problem. – Yuri Jan 26 '18 at 18:06
  • 7
    `/proc/acpi/wakeup` is not a child of `/proc/sys`, `sysctl` doesn't work here. – Nova Feb 12 '19 at 19:50
  • 1
    Please update the answer to reflect the @Erik's comment above. Thank you. – scrutari Dec 04 '20 at 19:34
0

You might be able to get away with a crontab on reboot if the entry only reverses on reboot.

On startup, the following crontab will reverse the entry XHC.

@reboot /bin/sh -c '/bin/echo XHC > /proc/acpi/wakeup'

21rw
  • 101
  • 2
0

The script file in Hrishikesh Kadam's answer is good, but rather than incorporating it in a service, I dropped it in a directory that is run by the system as it is entering suspend mode, so the updates to /proc/apci/wakeup are fresh as the system is going into suspend mode and a service isn't necessary. In my case, I named the file disable-some-wake. The format of the file is:

#! /bin/bash
case $1 in
    pre)
        declare -a devices=(RP09 PXSX) # <-- Add your entries here

        for device in "${devices[@]}"; do
            if $(grep -qw ^${device}.*enabled /proc/acpi/wakeup); then
                echo ${device} > /proc/acpi/wakeup
            fi
        done
    ;;
esac

The pre case specifies that this is pre-suspend. Now drop it into the directory:

sudo cp disable-some-wake /usr/lib/systemd/system-sleep

and change the permissions:

sudo chmod 755 /usr/lib/systemd/system-sleep/disable-some-wake

That’s it. No need to start a service or reboot your system.

Toby Speight
  • 8,460
  • 3
  • 26
  • 50