Sorting Out the Harder Soft Bits
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 hot plug 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 file system 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 mount point 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
file system so that manual ejections don’t cause a stuck dev entry. I also added
a bit of code to mount the USB read-only 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 hot plug 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.