6

I have a Lenovo G570 laptop with a little key called onekey recovery next to the power button, and since coming to Linux it has became useless.

Is there a way to make this key into a reset button for example? Or to add an entry in Grub to make it load recovery options?

I've seen similar posts in here but I don't have windows or a dual boot, my disk is a single disk partition with Ubuntu Gnome installed, I don't even have SWAP space.

  • 1
    From what I can tell, after boot, the OneKey key becomes another keyboard key. Hold on, I figured out the scancode a few weeks ago. –  Apr 19 '17 at 10:57
  • 1
    What model of Lenovo laptop do you have? I have a Lenovo Ideapad Z510, and I run Ubuntu on it, and the OneKey works as a way to boot into a BIOS menu (I think it goes to boot devices first). You might want to confirm this functionality, as I use it pretty regularly when booting into different media. – richbl Feb 01 '18 at 03:40
  • @richbl It's a G570, and no it doesn't do anything, it would boot the computer if off, but when it's running, nothing at all. – Muaad ElSharif Feb 01 '18 at 07:06
  • 1
    @Muaad See my updated answer. I think it will help. –  Feb 01 '18 at 12:04

2 Answers2

5

I do not have an idea how to use this button with GRUB, but there are at least two approaches how to make it usable within Ubuntu. For example if you want to bind the reboot command to that button you could: (1) create acpi event or (2) create custom shortcut.


Create acpi event and bind the reboot command to it

First you need to use acpi_listen and catch the event when the button is pressed. Just execute the command acpi_listen and press the button:

$ acpi_listen 
button/prog1 PROG1 00000080 00000000 K
  • In the above example button/prog1 PROG1 00000080 00000000 K is the event on my system when I press the discussed button.

Then you should crate a file that will handle this event. The file must be located in the directory /etc/acpi/events/. Call it for example reboot. The content of /etc/acpi/events/reboot should be similar as:

# /etc/acpi/events/reboot
# This will reboot the system
event=button/prog1 PROG1 00000080 00000000 K
action=systemctl reboot

Save the file and restart the acpi daemon:

sudo systemctl restart acpid.service

IMO this is the most simple method. This should work also when the user is not logged in. Here are few references where you can find additional information and examples:


Create acpi event and bind a script to it

We can add an insurance in case you press the button accidentally. Here we will create a script that will use a tmp file as flag and counter as it is described here. Thus the system reboot will be performed when you press the button three times.

  1. Modify /etc/acpi/events/reboot in this way:

    # /etc/acpi/events/reboot
    # This will reboot the system
    event=button/prog1 PROG1 00000080 00000000 K
    action=/etc/acpi/reboot.sh
    

    Restart the acpi daemon:

    sudo systemctl restart acpid.service
    
  2. Create the script /etc/acpi/reboot.sh and put the following lines as its content:

    #!/bin/bash  
    FLAG_FILE="/tmp/sysyem_reboot_flag"
    
    # If the file exists and it is older than 30 seconds, then reset the counter 
    # Else If the file doesn't exist or its 'value' is less than 2, then increment
    # Else (when the file exists, its value is equal or greater than 2, and its age is less than 30 seconds) reboot the system 
    
    if [ -f "${FLAG_FILE}" ] && [[ $(find "${FLAG_FILE}" -newermt '-30 sec') == '' ]]; then
        echo '1' > "$FLAG_FILE"
    elif [ ! -f "${FLAG_FILE}" ] || (( $(cat "$FLAG_FILE") < 2 )); then
        touch "$FLAG_FILE"
        NEW_VALUE=$(( $(cat "$FLAG_FILE") + 1)) && echo "$NEW_VALUE" > "$FLAG_FILE"
    else
        systemctl reboot
    fi
    

    Make it executable:

    sudo chmod +x /etc/acpi/reboot.sh
    

Now the systemctl reboot command will be performed when you press the button three times, within 30 secconds.


Create custom shortcut and bind a script to it

  1. Crate a script /usr/local/bin/my_rbt (it could be named and located whenever you want) and make it executable. Here is a single command line that does that:

    $ echo -e '#!/bin/sh\nsudo systemctl reboot' | sudo tee /usr/local/bin/my_rbt && sudo chmod +x /usr/local/bin/my_rbt
    #!/bin/sh
    systemctl reboot
    
  2. The problem is (within this approach) we must use sudo to execute the script and should allow the users to do that without password - here are provided more details about this step: How do I run specific sudo commands without a password? So we must crate a file located in /etc/sudoers.d/, called for example my_rbt. For this purposes we should use the command visudo -f:

    sudo visudo -f /etc/sudoers.d/my_rbt
    

    The content of the file should be:

    ALL ALL=NOPASSWD: /usr/local/bin/my_rbt
    
  3. Go to System SettingsKeyboardShortcuts (tab) → Custom Shortcuts (section) → Add new +.

    enter image description here

    • In the Custom shortcut window type:

    • Name: reboot

    • Command: sudo /usr/local/bin/my_rbt
    • Click on Apply
  4. Click on Disabled in the right column and press the discussed button.

    enter image description here

That's it.

pa4080
  • 29,831
  • The first solution worked like a charm, I will award you the bounty as soon as the system allows me to. Much appreciated. – Muaad ElSharif Feb 01 '18 at 13:49
  • 1
    I'm glad to help, @MuaadElSharif. I've updated the answer with an additional elaboration of the first approach. – pa4080 Feb 01 '18 at 15:02
2

It appears that for Lenovo laptops (at least my G575) the OneKey Recovery key is another key.

Using the xev command, you can find out the scancode. xev will open a window with a black square, move your mouse inside it and then press the OKR key.

KeyPress event, serial 51, synthetic NO, window 0x1600001,
    root 0x497, subw 0x1600002, time 1092364, (50,41), root:(52,479),
    state 0x0, keycode 156 (keysym 0x1008ff41, XF86Launch1), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 51, synthetic NO, window 0x1600001,
    root 0x497, subw 0x1600002, time 1092364, (50,41), root:(52,479),
    state 0x0, keycode 156 (keysym 0x1008ff41, XF86Launch1), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

You can see the keycode as keycode 156.

After finding the keycode, all you need to look up is how to map a keycode to a specific action. Here's some helpful questions:

  • 2
    could you add how to do that? – Zanna Apr 19 '17 at 11:18
  • @Mark thanks for showing me the way to display keys, and I'd appreciate if you show me how to do it, I asked because I don't know. – Muaad ElSharif Apr 19 '17 at 11:38
  • 3
    @Muaad I'm sorry, but I can't seem to find any references on how to do that, and to be honest I never bothered to map the keys, I only know it is possible. Previous versions of Ubuntu (before 13.04) used the xmodmap command, but as of 13.04, they use xkb instead. I've asked a question about how to use xkb. –  Apr 19 '17 at 22:59
  • 1
    @Muaad Please see my updated answer. –  Feb 01 '18 at 12:03