Skip to content

Mounting a UBIFS partition using systemd

Systemd is becoming the defacto system and service manager for Linux, replacing the SysV init scripts.  The Angstrom distribution has supported systemd for some time now. Recently, I needed to mount a UBIFS filesystem in one of my projects.  The main application is being started with systemd, so it seemed like a good fit to also use systemd to mount a data partition needed by the application. Systemd can use entries from /etc/fstab, but one additional wrinkle in this system is that I also wanted to run the UBI attach in a controlled way. This can be done with a kernel command line argument, but there are times in this system where we will want to format the data partition, so this requires a detach/attach operation.

The resulting systemd units are:

data.mount

[Unit]
Description=Mount data partition
Requires=data-attach.service
After=data-attach.service
[Mount]
What=ubi1:data
Where=/data
Type=ubifs

data-attach.service

[Unit]
Description=Attach data ubi partition

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/ubiattach /dev/ubi_ctrl -m 6
ExecStop=/usr/sbin/ubidetach /dev/ubi_ctrl -m 6

add the following to my-application.service

Wants=data.mount

The only real problem I ran into is the “After” statement in the data.mount unit.  It turns out that the mount will run before the attach operation is finished unless this is included.

The RemainAfterExit seems to be required so that ExecStop can be run when the unit is stopped.

(There may be a better ways to do all this, so comments are welcome!)

One of the benefits of systemd is that everything is very controlled.  If the dependencies are specified properly, there are no race conditions.  Additionally, if you need to manage units (services, mounts, etc) from a program, it is much easier to check the states as everything is very consistent.  For example, if you want to query the state of a unit, the systemctl show <unit>command will return easily parsed output (as shown below):

...
Before=umount.target
After=data-attach.service systemd-journald.socket -.mount
Description=Mount data partition
LoadState=loaded
ActiveState=active
SubState=mounted
FragmentPath=/lib/systemd/system/data.mount
UnitFileState=static
InactiveExitTimestamp=Thu, 01 Jan 1970 00:00:17 +0000
...

If the data-attach service is stopped, systemd automatically unmounts the data partition first — very nice!

Hopefully this example illustrates how to do simple tasks in systemd.  It appears that instead of having a complex script or program to initialize a system, the systemd “way” is to create a number of small units that get connected with dependencies.  This seems like a much more controlled and flexible approach.