blob: 0cd51fcde81cdf675c010781cf4676e138e6f06d [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/bin/sh
2#
3# Called from udev
4#
5# Attempt to mount any added block devices and umount any removed devices
6
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08007BASE_INIT="`readlink -f "@base_sbindir@/init"`"
8INIT_SYSTEMD="@systemd_unitdir@/systemd"
Andrew Geissler78b72792022-06-14 06:47:25 -05009MOUNT_BASE="@MOUNT_BASE@"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050010
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080011if [ "x$BASE_INIT" = "x$INIT_SYSTEMD" ];then
12 # systemd as init uses systemd-mount to mount block devices
13 MOUNT="/usr/bin/systemd-mount"
14 UMOUNT="/usr/bin/systemd-umount"
15
16 if [ -x $MOUNT ] && [ -x $UMOUNT ];
17 then
18 logger "Using systemd-mount to finish mount"
19 else
20 logger "Linux init is using systemd, so please install systemd-mount to finish mount"
21 exit 1
22 fi
23else
24 MOUNT="/bin/mount"
25 UMOUNT="/bin/umount"
26fi
27
Patrick Williamsc124f4f2015-09-15 14:41:29 -050028PMOUNT="/usr/bin/pmount"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080029
Andrew Geisslerd5838332022-05-27 11:33:10 -050030for line in `grep -h -v ^# /etc/udev/mount.ignorelist /etc/udev/mount.ignorelist.d/*`
Patrick Williamsc124f4f2015-09-15 14:41:29 -050031do
32 if [ ` expr match "$DEVNAME" "$line" ` -gt 0 ];
33 then
Andrew Geisslerd5838332022-05-27 11:33:10 -050034 logger "udev/mount.sh" "[$DEVNAME] is marked to ignore"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050035 exit 0
36 fi
37done
38
Patrick Williamsac13d5f2023-11-24 18:59:46 -060039is_filesystem_supported() {
40 while read -r fs; do
41 if [ "${fs#nodev}" = "$1" ];
42 then
43 return 0
44 fi
45 done < "/proc/filesystems"
46 return 1
47}
48
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080049automount_systemd() {
50 name="`basename "$DEVNAME"`"
51
Brad Bishopa34c0302019-09-23 22:34:48 -040052 # Skip already mounted partitions
Andrew Geissler615f2f12022-07-15 14:00:58 -050053 if [ -f /run/systemd/transient/$(echo $MOUNT_BASE | cut -d '/' -f 2- | sed 's#/#-#g')-*$name.mount ]; then
Andrew Geissler78b72792022-06-14 06:47:25 -050054 logger "mount.sh/automount" "$MOUNT_BASE/$name already mounted"
Brad Bishopa34c0302019-09-23 22:34:48 -040055 return
56 fi
57
Andrew Geissler615f2f12022-07-15 14:00:58 -050058 # Get the unique name for mount point
59 get_label_name "${DEVNAME}"
60
61 # Only go for auto-mounting when the device has been cleaned up in remove
62 # or has not been identified yet
63 if [ -e "/tmp/.automount-$name" ]; then
64 logger "mount.sh/automount" "[$MOUNT_BASE/$name] is already cached"
65 return
66 fi
67
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080068 # Skip the partition which are already in /etc/fstab
69 grep "^[[:space:]]*$DEVNAME" /etc/fstab && return
70 for n in LABEL PARTLABEL UUID PARTUUID; do
71 tmp="$(lsblk -o $n $DEVNAME | sed -e '1d')"
72 test -z "$tmp" && continue
73 tmp="$n=$tmp"
74 grep "^[[:space:]]*$tmp" /etc/fstab && return
75 done
76
Patrick Williamsac13d5f2023-11-24 18:59:46 -060077 if ! is_filesystem_supported $ID_FS_TYPE; then
78 logger "mount.sh/automount" "Filesystem '$ID_FS_TYPE' on '${DEVNAME}' is unsupported"
79 return
80 fi
81
Andrew Geissler78b72792022-06-14 06:47:25 -050082 [ -d "$MOUNT_BASE/$name" ] || mkdir -p "$MOUNT_BASE/$name"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080083
84 MOUNT="$MOUNT -o silent"
85
86 # If filesystemtype is vfat, change the ownership group to 'disk', and
87 # grant it with w/r/x permissions.
88 case $ID_FS_TYPE in
89 vfat|fat)
90 MOUNT="$MOUNT -o umask=007,gid=`awk -F':' '/^disk/{print $3}' /etc/group`"
91 ;;
Brad Bishop96ff1982019-08-19 13:50:42 -040092 swap)
93 return ;;
Andrew Geissler615f2f12022-07-15 14:00:58 -050094 lvm*|LVM*)
95 return ;;
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080096 # TODO
97 *)
98 ;;
99 esac
100
Andrew Geissler78b72792022-06-14 06:47:25 -0500101 if ! $MOUNT --no-block -t auto $DEVNAME "$MOUNT_BASE/$name"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800102 then
Andrew Geissler78b72792022-06-14 06:47:25 -0500103 #logger "mount.sh/automount" "$MOUNT -t auto $DEVNAME \"$MOUNT_BASE/$name\" failed!"
104 rm_dir "$MOUNT_BASE/$name"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800105 else
Andrew Geissler78b72792022-06-14 06:47:25 -0500106 logger "mount.sh/automount" "Auto-mount of [$MOUNT_BASE/$name] successful"
Patrick Williamsdb4c27e2022-08-05 08:10:29 -0500107 echo "$name" > "/tmp/.automount-$name"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800108 fi
109}
110
111automount() {
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500112 name="`basename "$DEVNAME"`"
113
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800114 if [ -x "$PMOUNT" ]; then
115 $PMOUNT $DEVNAME 2> /dev/null
116 elif [ -x $MOUNT ]; then
117 $MOUNT $DEVNAME 2> /dev/null
118 fi
119
120 # If the device isn't mounted at this point, it isn't
121 # configured in fstab
122 grep -q "^$DEVNAME " /proc/mounts && return
123
Andrew Geissler615f2f12022-07-15 14:00:58 -0500124 # Get the unique name for mount point
125 get_label_name "${DEVNAME}"
126
127 # Only go for auto-mounting when the device has been cleaned up in remove
128 # or has not been identified yet
129 if [ -e "/tmp/.automount-$name" ]; then
130 logger "mount.sh/automount" "[$MOUNT_BASE/$name] is already cached"
131 return
132 fi
133
Andrew Geissler78b72792022-06-14 06:47:25 -0500134 ! test -d "$MOUNT_BASE/$name" && mkdir -p "$MOUNT_BASE/$name"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500135 # Silent util-linux's version of mounting auto
136 if [ "x`readlink $MOUNT`" = "x/bin/mount.util-linux" ] ;
137 then
138 MOUNT="$MOUNT -o silent"
139 fi
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800140
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500141 # If filesystem type is vfat, change the ownership group to 'disk', and
142 # grant it with w/r/x permissions.
143 case $ID_FS_TYPE in
144 vfat|fat)
145 MOUNT="$MOUNT -o umask=007,gid=`awk -F':' '/^disk/{print $3}' /etc/group`"
146 ;;
Brad Bishop96ff1982019-08-19 13:50:42 -0400147 swap)
148 return ;;
Andrew Geissler615f2f12022-07-15 14:00:58 -0500149 lvm*|LVM*)
150 return ;;
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500151 # TODO
152 *)
153 ;;
154 esac
155
Andrew Geissler78b72792022-06-14 06:47:25 -0500156 if ! $MOUNT -t auto $DEVNAME "$MOUNT_BASE/$name"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500157 then
Andrew Geissler78b72792022-06-14 06:47:25 -0500158 #logger "mount.sh/automount" "$MOUNT -t auto $DEVNAME \"$MOUNT_BASE/$name\" failed!"
159 rm_dir "$MOUNT_BASE/$name"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500160 else
Andrew Geissler78b72792022-06-14 06:47:25 -0500161 logger "mount.sh/automount" "Auto-mount of [$MOUNT_BASE/$name] successful"
Andrew Geissler615f2f12022-07-15 14:00:58 -0500162 # The actual device might not be present in the remove event so blkid cannot
163 # be used to calculate what name was generated here. Simply save the mount
164 # name in our tmp file.
165 echo "$name" > "/tmp/.automount-$name"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500166 fi
167}
168
169rm_dir() {
170 # We do not want to rm -r populated directories
171 if test "`find "$1" | wc -l | tr -d " "`" -lt 2 -a -d "$1"
172 then
173 ! test -z "$1" && rm -r "$1"
174 else
175 logger "mount.sh/automount" "Not removing non-empty directory [$1]"
176 fi
177}
178
Andrew Geissler615f2f12022-07-15 14:00:58 -0500179get_label_name() {
180 # Get the LABEL or PARTLABEL
181 LABEL=`/sbin/blkid | grep "$1:" | grep -o 'LABEL=".*"' | cut -d '"' -f2`
182 # If the $DEVNAME has a LABEL or a PARTLABEL
183 if [ -n "$LABEL" ]; then
184 # Set the mount location dir name to LABEL appended
185 # with $name e.g. label-sda. That would avoid overlapping
186 # mounts in case two devices have same LABEL
187 name="${LABEL}-${name}"
188 fi
189}
190
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500191# No ID_FS_TYPE for cdrom device, yet it should be mounted
192name="`basename "$DEVNAME"`"
193[ -e /sys/block/$name/device/media ] && media_type=`cat /sys/block/$name/device/media`
194
195if [ "$ACTION" = "add" ] && [ -n "$DEVNAME" ] && [ -n "$ID_FS_TYPE" -o "$media_type" = "cdrom" ]; then
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800196 # Note the root filesystem can show up as /dev/root in /proc/mounts,
197 # so check the device number too
198 if expr $MAJOR "*" 256 + $MINOR != `stat -c %d /`; then
199 if [ "`basename $MOUNT`" = "systemd-mount" ];then
200 automount_systemd
201 else
202 automount
203 fi
204 fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500205fi
206
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500207if [ "$ACTION" = "remove" ] || [ "$ACTION" = "change" ] && [ -x "$UMOUNT" ] && [ -n "$DEVNAME" ]; then
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800208 name="`basename "$DEVNAME"`"
Andrew Geissler615f2f12022-07-15 14:00:58 -0500209 tmpfile=`find /tmp | grep "\.automount-.*${name}$"`
210 if [ ! -e "/sys/$DEVPATH" -a -e "$tmpfile" ]; then
211 logger "mount.sh/remove" "cleaning up $DEVNAME, was mounted by the auto-mounter"
212 for mnt in `cat /proc/mounts | grep "$DEVNAME" | cut -f 2 -d " " `
213 do
214 $UMOUNT $mnt
215 done
216 # Remove mount directory created by the auto-mounter
217 # and clean up our tmp cache file
218 mntdir=`cat "$tmpfile"`
219 rm_dir "$MOUNT_BASE/$mntdir"
220 rm "$tmpfile"
221 fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500222fi