Poor man switch for the raspberry pi

It has been a long time since someone posted here, so I might as well start off with something.

I have been messing around with my Raspberry Pi 2B for quite some time and I couldn’t find a simple way to turn my headless raspberry pi off. I had multiple options:

  1. remote into the pi and execute the shutdown command
  2. Wire up a switch using the gpio provided and execute the shutdown command upon pressed.

I didn’t like number 1 since it is cumbersome. I would need a ssh client to remote in. I didn’t like number 2 either, since I would need to buy additional hardware and a ton of soldering. I chanced upon udev recently while researching for auto-mounting USB drives on headless machines. In this article, we will be looking at how to uitilize USB drives to execute the shutdown command. Since USB drives are dirt cheap and I have tons of them lying them around, why not use it?

 

Basically, udev is a kernel API to handle USB peripherals. We will be using it to write rules and change the behavior when a specific USB drive is plugged in.

 

Alright, this guide assumes you have a Debian based distribution. It may work on Arch and Fedora family. On Gentoo family, good luck compiling your system first.

 

Gathering of Info

Firstly, plug your USB drive in and find the mount point of your USB drive.

sudo fdisk -l

Your thumbdrive should be /dev/mmcblkX, where X is a “variable”. For my case, it is /dev/mmcblk0p2.

 

udevadm info -a -p $(udevadm info -q path -n /dev/mmcblk0p2)

There will be a huge output. We need to find the USB drive, in my case it is /dev/mmcblk0p2. We will need to find your USB drive specific identifiers to differentiate this drive from others.

looking at device ‘/devices/platform/soc/3f202000.sdhost/mmc_host/mmc0/mmc0:59b4/block/mmcblk0/mmcblk0p2’:
KERNEL==”mmcblk0p2″
SUBSYSTEM==”block”
DRIVER==””
ATTR{ro}==”0″
ATTR{size}==”30760960″
ATTR{stat}==” 7952 47 209472 26210 64 962 29024 24660 0 13010 50850″
ATTR{partition}==”2″
ATTR{start}==”137216″
ATTR{discard_alignment}==”1048576″
ATTR{alignment_offset}==”0″
ATTR{inflight}==” 0 0″

looking at parent device ‘/devices/platform/soc/3f202000.sdhost/mmc_host/mmc0/mmc0:59b4/block/mmcblk0’:
KERNELS==”mmcblk0″
SUBSYSTEMS==”block”
DRIVERS==””
ATTRS{ro}==”0″
ATTRS{size}==”30898176″
ATTRS{stat}==” 8074 77 211961 26550 65 962 29025 24680 0 13110 51210″
ATTRS{range}==”32″
ATTRS{discard_alignment}==”0″
ATTRS{force_ro}==”0″
ATTRS{ext_range}==”32″
ATTRS{alignment_offset}==”0″
ATTRS{inflight}==” 0 0″
ATTRS{removable}==”0″
ATTRS{capability}==”10″

looking at parent device ‘/devices/platform/soc/3f202000.sdhost/mmc_host/mmc0/mmc0:59b4’:
KERNELS==”mmc0:59b4″
SUBSYSTEMS==”mmc”
DRIVERS==”mmcblk”
ATTRS{cid}==”1b534d303030303010c425046000e58f”
ATTRS{csd}==”400e00325b59000075dd7f800a4000ff”
ATTRS{scr}==”0235800100000000″
ATTRS{date}==”05/2014″
ATTRS{name}==”00000″
ATTRS{type}==”SD”
ATTRS{preferred_erase_size}==”4194304″
ATTRS{fwrev}==”0x0″
ATTRS{hwrev}==”0x1″
ATTRS{oemid}==”0x534d”
ATTRS{manfid}==”0x00001b”
ATTRS{serial}==”0xc4250460″
ATTRS{erase_size}==”512″

looking at parent device ‘/devices/platform/soc/3f202000.sdhost/mmc_host/mmc0’:
KERNELS==”mmc0″
SUBSYSTEMS==”mmc_host”
DRIVERS==””

looking at parent device ‘/devices/platform/soc/3f202000.sdhost’:
KERNELS==”3f202000.sdhost”
SUBSYSTEMS==”platform”
DRIVERS==”sdhost-bcm2835″
ATTRS{driver_override}==”(null)”

looking at parent device ‘/devices/platform/soc’:
KERNELS==”soc”
SUBSYSTEMS==”platform”
DRIVERS==””
ATTRS{driver_override}==”(null)”

looking at parent device ‘/devices/platform’:
KERNELS==”platform”
SUBSYSTEMS==””
DRIVERS==””

We should be interested in this section: KERNEL==”mmcblk0p2″. To ensure that only this USB drive has the “privilege” to shutdown the system, we need to add in it’s ATTRS{idVendor}==”xxx”, ATTRS{idProduct}=”xxxx” and ATTRS{serial}=”xxxx”.

After finding it, navigate to /etc/udev/rules.d/ . Your rule files should be stored here. Note that this directory reads the file from the lowest number to the highest number.(script starting with 1 will run first, script starting with 99 will run last).  We will be using this filename:

98-thumbdrive.rules

Add the following parameters your found just now inside the file. NOTE: everything should be on a single line. This is the content of my file.

ATTRS{idVendor}==”0781″,ATTRS{idProduct}==”556b”,ATTRS{serial}==”20051031830546C16154″, SYMLINK+=”shutdown”, RUN+=”/bin/shutdown-script.sh”

After that navigate to /bin and create the shutdown script:

shutdown-script.sh

The content will be:

#!/bin/sh

 

shutdown -h now

Lastly, as the shutdown command requires sudo privileges, we will need to give the script more permissions. Execute the following command:

 sudo visudo

At the end of the file add

YOUR_USERNAME_HERE ALL= (root) NOPASSWD:/bin/shutdown-script.sh

Replace YOUR_USERNAME_HERE with…well, your username.

Restart udev and we are done!

sudo /etc/init.d/udev restart

No wires, no soldering, nothing needed. Just a bit of System administration skills needed and a USB drive. Test it by plugging your USB drive and check if your pi is still powered on.

The downside of this project is that the specific USB drive cannot be plugged into the system otherwise you will shutdown the pi. This guide can also be used as a dead man’s switch where you will wipe your drives and write 0s to it if law enforcement were to seize your equipment. Though, I WOULD NOT recommend this as this may violate your local laws. This guide was never meant for any malicious purpose.

 

What do you think about this guide? Leave your comments below.

 

 

P.S I have not found a way to turn the pi on yet.

Daniel Quah

18 Year old dude, who loves cat and tech

Latest posts by Daniel Quah (see all)