Sunday, July 10, 2016

Native screen lock and suspend on FreeBSD

For some time I've tinkered with FreeBSD. Mainly on my home file server. Sometimes on a Raspberry Pi and most recently on laptops. I had been running FreeBSD 11-current on my old Thinkpad X61 for the last few months while waiting for 11.0 to be released. The X61 being an older laptop, however, made compiling updates a tedious and boring process so I rarely used it. Well, the wait is over! FreeBSD 11.0 Beta-1 was released on July 8th, 2016. I've installed it on the X61 and we're back business! This time around, however, I wanted to challenge myself to minimize my use of non-native packages and see how much I could get done with what FreeBSD provides out of the box.

Right off the bat I'm going to tell you that, unless you want to run FreeBSD without X, you have to install at least a couple of ports. Xorg, at a minimum. I opted to install Xorg and use Fluxbox as my window manager. Everything was wonderful. Outside of those two ports, I had a fully functional laptop. I didn't even have to resort to Google for answers to my questions thanks to FreeBSD's awesome handbook which is included right there in the base installation!

One problem remained. The problem that plagues every Linux and BSD user. Lid triggered suspend/resume. Without this feature, it's a lot harder to use your laptop (or at least more annoying to have to shut it down and start it up constantly). Thankfully, I knew from my past experiences that the X61 had perfect suspend/resume support using the native `hw.acpi.lid_switch_state` setting in sysctl.conf. Set that puppy to "S3" and you're off and running. There is just one problem. This does not lock your screen so anyone who opens your laptop while it's asleep can just jump right on and use the computer as your user. I needed to find a way to lock the screen before suspend kicked in.

In the past, I have installed xfce-power-manager and this has handled everything very neatly for me. This time, however, I was trying to minimize the number of ports installed on the system and see how far I could get with just the native tools. Enter devd.

For those coming from Linux, devd is FreeBSD's udev. You can configure actions based on hardware events. After reading the man pages, guess what!? It supports a "Lid" ACPI subsystem trigger with a 0 and a 1 state. A simple config file added to /etc/devd/ and we're in business. But what should we use to lock the screen? This comes down to personal preference. I've always liked and used xscreensaver. Others may prefer slock or xlock. Whichever you choose is up to you. Heck, there might even be one included in the base system. I just never explored that since I prefer xscreensaver. Install whichever you would like from ports and continue on to the next section.

Once I had xscreensaver installed, I created a file called "lidlock.conf" inside of /etc/devd/. This is a dump of this file:


notify 20 {
    match "system"    "ACPI";
    match "subsystem" "Lid";
    match "notify"    "0x00";
    action "/usr/bin/su [my_user] -c '/usr/local/bin/xscreensaver-command -display :0.0 -lock'";
    action "acpiconf -s3";
};

The only part about that you have to change is the "[my_user]". Set that to your user and you'll be all set. This example also assumes you have a single user system. If there are other users on your system and you don't always want xscreensaver running as your user you might consider creating a special user just for this purpose. You could also just leave off the 'su -c' entirely and run xscreensaver-command directly. I chose to run it as an unprivileged user, however, for security reasons.

Once you have this saved inside /etc/devd you can restart devd and it should work. Note that I had issues doing it this way, however, and had to actually restart my entire system before the config file was picked up. I'm not sure why. You will also want to make sure you have 'hw.acpi.lid_switch_state' inside of /etc/sysctl.conf set to "NONE" or it will trigger before devd can run this custom action and you'll spend hours trying to figure out why (trust me).

Anyway, that's it! Enjoy your FreeBSD laptop!

2 comments:

  1. Perfect! Just what I was looking for. Thanks!!

    ReplyDelete
  2. A small tweak (use the current logged in user to lock):

    action "PID=$(pgrep -o xscreensaver); [ ${#PID} -gt 0 ] && /usr/bin/su $(ps -o user= -p ${PID}) -c '/usr/local/bin/xscreensaver-command -display :0.0 -lock'";

    ReplyDelete