Blaine's World

Sorting Out the Harder Soft Bits

Published

At the end of the last log I was pretty happy with the base software I got working on the Pi. I had a way to automatically boot into a system running a MPD and ncmpc (a curses-style media player). What I did not have was an easy way to play music with the system. After a good bit of tweaking settings and writing scripts I now have a working jukebox.

The first thing I did after uploading the last log was attempt to do a sound test. I plugged in a flash drive full of music into the Pi but nothing mounted – not surprising given the minimalism of Alpine that an automounter wouldn’t be available (or at least configured for USB media). I hit up the MPD manual to see if there was anything to leverage there and found udisks2 support via a built-in plugin. I installed udisks2 and dbus and ran udiskctl status to confirm everything was running. Much to my surprise this had no effect on MPD. I dug around the manual some more and realized I needed to enable the “neighbor plugin” for udisks which is how I made the discovery that Alpine’s MPD isn’t compiled with udisks2 support (mpd --version gives a nice list of capabilities). Being the lazy person I am I didn’t want to compile my own version of MPD so I looked into external options for mounting.

Since udisks2 wasn’t an option I ventured into more familiar territory and started looking into udev rules to mount USB devices to a fixed directory. Alpine utilizes OpenRC instead of Systemd so eudev is the route I figured I would have to take. I started to install packages to make eudev work and noticed a service reported by OpenRC called mdev. It turns out busybox ships with its own udev-style daemon called mdev that supports triggering scripts on device hotplug events. Better yet the Gentoo Wiki had a article on USB automounting with mdev and an example script to start from.

My vision for the jukebox automounter was to allow the user to plug in a USB disk at run-time and have it be mounted to a fixed point in the filesystem for MPD to read. I also wanted to allow unplugging of the USB device without any software steps to simplify updating the music library. I only needed a subset of the features used by the example automount script so I started with a minimal skeleton that recycled a couple state checks and built up from there. After a long bout of experimentation I came up with a script that mounts the first partition of the first sdX device (/dev/sda1, /dev/sdb1, etc…) to a fixed mountpoint at /media/removable. At first it seemed to work well, but more testing revealed that replugging the USB disk while playing music in MPD caused the USB device to reenumerate under a different dev file and break the automounting altogether. I fixed this issue by lazy unmounting the filesytem so that manual ejections don’t cause a stuck dev entry. I also added a bit of code to mount the USB readonly to avoid corruption on eject and a call to mpc to reload MPD’s database whenever the device state is changed.

A this point I have a safe and reliable way to hotplug USB devices and have MPD’s database be updated automatically. All that remains on the software side is a theming of ncmpc and possibly a nice bootsplash to make the immersion more complete.