Bash: Dynamic Volume Group Mounter

Bash: Dynamic Volume Group Mounter

This is similar, but an enhanced version of my custom_mount.sh previously published here: Bash: Automatically Mount File Systems on Volume Group if Present. This previous version was just a simple init script.  This updated version is designed for newer Linux distributions that use Systemd instead of Init.

The Code

The majority of the work is done by dvgmounter.sh.  It will check if the Volume Group is present, if it is it will parse the /etc/fstab file looking for entries that are marked noauto, then it will test if that file system is already mounted, if it is not it will mount it.

#!/bin/bash
# description: Will automatically mount a removable device if present.
#
#: Script Name : dvgmounter.sh
#: Version : 1.0.4.1
#: Author : Matthew Mattoon - http://blog.allanglesit.com
#: Date Created : August 15, 2012
#: Date Updated : September 14, 2015
#: Description : Automount Removable Logical Volumes Script.
#: Examples : dvgmounter.sh ACTION VGNAME
#: : dvgmounter.sh start data_vg

vgtest=$2
vgs=`vgs | grep $vgtest`

start() {
if [ -n "$vgs" ]; then
echo "Logical Volume Group: $vgtest present."
mounts=`cat /etc/fstab | grep $vgtest | grep noauto | tr '\t' ' ' | tr -s ' ' | cut -d " " -f 2`
for mount in $mounts
do
if [ -z "`mount | grep $mount`" ]; then
echo "Mounting $mount file system..."
mount $mount
else
echo "File system $mount is already mounted..."
fi
done
else
echo "Logical Volume Group: $vgtest not present."
exit 1
fi
}

stop() {
if [ -n "$vgs" ]; then
echo "Logical Volume Group: $vgtest present."
mounts=`cat /etc/fstab | grep $vgtest | grep noauto | tr '\t' ' ' | tr -s ' ' | cut -d " " -f 2`
for mount in $mounts
do
if [ -n "`mount | grep $mount`" ]; then
echo "Unmounting $mount file system..."
umount $mount
else
echo "File system $mount is already unmounted..."
fi
done
else
echo "Logical Volume Group: $vgtest not present."
exit 1
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 2
start
;;
*)
echo "Usage: $0 start|stop|restart"
exit 1
esac

Here is what I have for LVM.

# vgs
VG #PV #LV #SN Attr VSize VFree
laptop_vg 1 4 0 wz--n- 237.98g 26.44g
data_vg 1 4 0 wz--n- 298.09g 18.09g
# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
home laptop_vg -wi-ao---- 97.66g
localvm_lv laptop_vg -wi-ao---- 60.00g
root laptop_vg -wi-ao---- 50.00g
swap laptop_vg -wi-ao---- 3.89g
disk_lv data_vg -wi-ao---- 60.00g
downloads_lv data_vg -wi-ao---- 50.00g
iso_lv data_vg -wi-ao---- 20.00g
movies_lv data_vg -wi-ao---- 150.00g

Here is the snipped contents of my /etc/fstab.

# cat /etc/fstab
...
/dev/mapper/data_vg-iso_lv /vbox/iso ext4 noauto 1 2
/dev/mapper/data_vg-disk_lv /vbox/disk ext4 noauto 1 2
/dev/mapper/data_vg-movies_lv /home/matthew/movies ext4 noauto 1 2
/dev/mapper/data_vg-downloads_lv /home/matthew/Downloads ext4 noauto 1 2
...

Creating the Service

We just need to put some details into a service file, since this particular script is a one time run then we need to tell Systemd that this is a “oneshot” and that we want it to “RemainAfterExit” so that it doesn’t put the service into a failed state when it completes its work and stops running.

# cat /lib/systemd/system/dvgmount.service
[Unit]
Description=Dynamic Volume Group Mounter

[Service]
Type=oneshot
ExecStart=/opt/dvgmounter/dvgmounter.sh start data_vg
ExecStop=/opt/dvgmounter/dvgmounter.sh stop data_vg
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Then we need to link that service file into Systemd’s configuration, so that it can transact with it.

# pwd
/etc/systemd/system
# ln -s /lib/systemd/system/dvgmount.service

Whenever you make changes to services you will need to reload the daemons into Systemd.

# systemctl daemon-reload

Then starting the service is simple enough.

# systemctl start dvgmount.service

Lets check status and make sure that this worked properly before making the changes permanent.

# systemctl status dvgmount.service
● dvgmount.service - Dynamic Volume Group Mounter
Loaded: loaded (/lib/systemd/system/dvgmount.service; enabled; vendor preset: disabled)
Active: active (exited) since Mon 2015-09-14 15:50:57 CDT; 10min ago
Main PID: 24178 (code=exited, status=0/SUCCESS)
CGroup: /system.slice/dvgmount.service

Sep 14 15:50:57 laptop systemd[1]: Starting Dynamic Volume Group Mounter...
Sep 14 15:50:57 laptop dvgmounter.sh[24178]: Logical Volume Group: mattoondata_vg present.
Sep 14 15:50:57 laptop dvgmounter.sh[24178]: Mounting /vbox/iso file system...
Sep 14 15:50:57 laptop dvgmounter.sh[24178]: Mounting /vbox/disk file system...
Sep 14 15:50:57 laptop dvgmounter.sh[24178]: Mounting /home/matthew/movies file system...
Sep 14 15:50:57 laptop dvgmounter.sh[24178]: Mounting /home/matthew/Downloads file system...
Sep 14 15:50:57 laptop systemd[1]: Started Dynamic Volume Group Mounter.

Finally lets tell Systemd that this should be evaluated as part of its system startup.  This will make the changes permanent.

# systemctl enable dvgmount.service
Created symlink from /etc/systemd/system/multi-user.target.wants/dvgmount.service to /usr/lib/systemd/system/dvgmount.service.

That does it.  This should solve this one for some time!