-
Notifications
You must be signed in to change notification settings - Fork 29
/
ps-mount
executable file
·219 lines (190 loc) · 7.65 KB
/
ps-mount
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#!/bin/bash -e
# Weird things can happen if some output goes to console
exec 1>/dev/null 2>&1
# Fork in order not to stall udev on this and related devices
if [ fork != "$1" ]; then
# Use of auto.media is exclusive via file lock
lock=/var/lock/ps-mount.lock
(flock 20; "$0" fork "$@") 20>>${lock} &
else
shift
# Files and scripts
prefix=/media
autofspid=/var/run/autofs.pid
mountsorg=/etc/autofs/auto.media
mounts=/var/run/auto.media
# Mount options (permissions: rw------- / rwx------)
supported=" ext2 ext3 ext4 vfat msdos exfat ntfs ntfs-3g iso9660 udf hfs hfsplus vmhgfs vboxsf "
luser=anon
lgroup=legion
opts_common=noatime,nosuid,nodev,noexec
opts_vfat=${opts_common},flush,iocharset=iso8859-1,utf8,showexec,uid=${luser},gid=${lgroup},umask=0177,dmask=077
opts_exfat=${opts_common},uid=${luser},gid=${lgroup},umask=0177,dmask=077
opts_ntfs=${opts_common},compression,uid=${luser},gid=${lgroup},fmask=0177,dmask=077
opts_ntfs_ro=${opts_common},ro,compression,uid=${luser},gid=${lgroup},fmask=0377,dmask=0277
opts_iso9660=${opts_common},ro,iocharset=iso8859-1,utf8,uid=${luser},gid=${lgroup},mode=0400,dmode=0500
opts_udf=${opts_common},unhide,undelete,iocharset=iso8859-1,uid=${luser},uid=ignore,uid=forget,gid=${lgroup},gid=ignore,gid=forget,umask=077
opts_ext2=${opts_common},acl,user_xattr
opts_ext3=${opts_ext2}
opts_ext4=${opts_ext2}
opts_hfs=${opts_common},uid=${luser},gid=${lgroup},file_umask=0177,dir_umask=077
opts_hfsplus=${opts_common},ro,uid=${luser},gid=${lgroup},umask=0277
opts_vmhgfs=${opts_common},uid=${luser},gid=${lgroup},fmask=0177,dmask=077
opts_vboxsf=nosuid,nodev,noexec,uid=${luser},gid=${lgroup},umask=0177,dmask=077
opts_auto=${opts_vfat}
# Ensure that ${mounts} exists
if [ ! -e ${mounts} ]; then
cp ${mountsorg} ${mounts}
fi
# Checking whether device is in fstab (except root fs), or is mounted
DEVLINKS=" ${DEVLINKS} "
fstab_check() {
if [ -n "${FSTAB_NAME}" ]; then
echo fstab
else
local rootdevs=`awk '/^\// { print $1 }' /etc/fstab`
local mdev
for mdev in ${rootdevs}; do
if [ ${mdev} = "${DEVNAME}" -o -z "${DEVLINKS/* ${mdev} */}" ]; then
echo fstab
return
fi
done
# /proc/mounts contains only device names
# (no UUID or LABEL, but may contain symlinks)
rootdevs=`awk '/^\// { print $1 }' /proc/mounts`
for mdev in ${rootdevs}; do
if [ ${mdev} = "${DEVNAME}" -o -z "${DEVLINKS/* ${mdev} */}" ]; then
echo mtab
return
fi
done
echo none
fi
}
# Nothing to do if the device is handled by fstab
fscheck=`fstab_check`
if [ "${fscheck}" = fstab ]; then
exit
fi
# Exit if fs type is available, but is not supported
if [ -n "${ID_FS_TYPE}" -a -n "${supported/* ${ID_FS_TYPE} */}" ]; then
exit
fi
# Assign volume label if unavailable
if [ -z "${ID_FS_LABEL}" ]; then
if [ -n "${ID_MODEL}" ]; then
ID_FS_LABEL="${ID_VENDOR:+${ID_VENDOR/%/_}}${ID_MODEL}"
elif [ "${DEVNAME/[0-9]/X}" = /dev/fdX ]; then
ID_FS_LABEL="floppy${DEVNAME/\/dev\/fd/}"
ID_FS_LABEL="${ID_FS_LABEL/floppy0/floppy}"
elif [ "${ID_CDROM}" = 1 ]; then
ID_FS_LABEL="cdrom"
if [ "${ID_CDROM_DVD}" = 1 ]; then
ID_FS_LABEL="dvdrom"
fi
elif env | grep -q '^ID_CDROM_MEDIA_CD.*=1$'; then
ID_FS_LABEL=unnamed-cd
elif env | grep -q '^ID_CDROM_MEDIA_DVD.*=1$'; then
ID_FS_LABEL=unnamed-dvd
else
ID_FS_LABEL=unnamed-disk
fi
fi
# Get current autofs devices and keys (space-separated)
autodevs=`awk '/^[^#]/ { printf " " substr($3, 2) }' ${mounts}; echo -n ' '`
autokeys=`awk '/^[^#]/ { printf " " substr($1,2,length($1)-2) }' ${mounts}; echo -n ' '`
# Fixing volume label in case of collision
fixlabel() {
if [ -z "${autokeys/* ${ID_FS_LABEL} */}" ]; then
local suffix=2
while [ -z "${autokeys/* ${ID_FS_LABEL}-${suffix} */}" ]; do
let suffix=suffix+1
done
ID_FS_LABEL="${ID_FS_LABEL}-${suffix}"
fi
}
# Reloading autofs if it is running
reload_autofs() {
if [ -r ${autofspid} ]; then
kill -HUP `cat ${autofspid}`
fi
}
# Adding new auto.media entry
# (also update autokeys)
add_entry() {
case "${ID_FS_TYPE}" in
auto|ext2|ext3|ext4|vfat|exfat|iso9660|udf|hfs|hfsplus|vmhgfs|vboxsf)
eval type=${ID_FS_TYPE},\${opts_${ID_FS_TYPE}}
;;
msdos)
type="vfat,${opts_vfat}"
;;
ntfs|ntfs-3g)
type="ntfs-3g,${opts_ntfs}"
# Possibly make mount point read-only for NTFS (e.g., hibernated Windows)
if ! ntfs-3g.probe -w "${DEVNAME}"; then
type="ntfs-3g,${opts_ntfs_ro}"
fi
;;
*)
# Fallback, shouldn't happen
logger -p 4 -t auto.media "unknown filesystem type: ${ID_FS_TYPE}"
return
;;
esac
fixlabel
echo "\"${ID_FS_LABEL}\" -fstype=${type} :${DEVNAME}" >> ${mounts}
autokeys="${autokeys}${ID_FS_LABEL} "
}
# Unmount and remove existing auto.media entry (or entries)
# (also update autokeys for fixlabel after ACTION=change)
remove_entry() {
# Unmount mount points, not devices (since there can be several per device)
local keys=`awk '/^[^#]/ && $3 == ":'"${DEVNAME}"'" { print substr($1,2,length($1)-2) }' ${mounts}`
local key
local kl="$1"
for key in ${keys}; do
# NOTE: lazy unmount
umount -l ${prefix}/"${key}" 2>/dev/null || :
autokeys="${autokeys/ ${key} / }"
if [ "${kl}" = keeplabel ]; then
ID_FS_LABEL="${key}"
kl=
fi
done
# Remove entries (will be removed from dir after autofs reload)
sed -i "\&^[^#].* :${DEVNAME}"'$&d' ${mounts}
}
# For "add" action, a line is added only for non-existing (in autofs or mounted) device
if [ "${ACTION}" = add ]; then
if [ -n "${autodevs/* ${DEVNAME} */}" -a "${fscheck}" != mtab ]; then
# Generate fs type for static floppy/cd directories
if [ "${DEVNAME/[0-9]/X}" = /dev/fdX ]; then
ID_FS_TYPE=auto
elif [ "${ID_CDROM}" = 1 ]; then
ID_FS_TYPE=iso9660
fi
# Add an entry only if fs type is available
if [ -n "${ID_FS_TYPE}" ]; then
add_entry
reload_autofs
fi
fi
# For "change" action (non-fuse-generated), a line is replaced,
# but label is not changed
elif [ "${ACTION}" = change -a \( "${DISK_MEDIA_CHANGE}" = 1 -o -n "${DM_NAME}" \) ]; then
# Update if present in autofs or is a non-existing device, and is a filesystem
if [ \( -z "${autodevs/* ${DEVNAME} */}" -o "${fscheck}" != mtab \) -a -n "${ID_FS_TYPE}" ]; then
remove_entry keeplabel
add_entry
reload_autofs
fi
# For "remove" action, the line corresponding to the device is removed
elif [ "${ACTION}" = remove ]; then
if [ -z "${autodevs/* ${DEVNAME} */}" ]; then
remove_entry
reload_autofs
fi
fi
fi