5c5e8d593aa1782261e2fa8d2063cd10d31e605b
[grml-udev-config.git] / scripts / grml-udev-rebuildfstab
1 #!/bin/bash
2 # Filename:      scripts/grml-udev-rebuildfstab
3 # Purpose:       udev script to update /etc/fstab
4 # Authors:       grml-team (grml.org)
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2+.
7 ################################################################################
8
9 PATH="/bin:/sbin:/usr/bin:/usr/sbin"
10 TMP=$(mktemp 2>/dev/null)
11 TMPFILE=$(mktemp 2>/dev/null)
12 ADDEDBYGRML="# Added by GRML"
13 MOUNTPOINT_PREFIX=/mnt
14 MNTFILE="$MOUNTPOINT_PREFIX/.grml-auto-created_do-not-delete-this-file"
15
16
17 logit() {
18   if [ -x /usr/bin/logger ] ; then
19      /usr/bin/logger -i -t rebuildfstab "$*"
20   fi
21 }
22
23 bailout() {
24    [ -n "$1" ] && EXITCODE="$1" || EXITCODE=1
25    rm -f $TMP $TMPFILE /var/run/rebuildfstab.pid
26    exit $EXITCODE
27 }
28
29 echo "$$" > /var/run/rebuildfstab.pid
30
31
32 umask 022
33
34
35 [ -e /etc/grml/autconfig ] && . /etc/grml/autoconfig
36
37 if ! [ -w "$(dirname $MNTFILE)" ] ; then
38    echo "$0: can not write to $MNTFILE">&2
39    logit "can not write to $MNTFILE"
40    bailout 10
41 fi
42
43 if [ -z "$TMP" -o -z "$TMPFILE" ] ; then
44    echo "$0: could not create tmpfile (is / mounted read-only?), exiting" >&2
45    logit 'fatal - could not create tmpfile (is / mounted read-only?), exiting'
46    bailout 3
47 fi
48
49 # trap "rm -f $TMP $TMPFILE" 2 3 11
50
51
52 if grep -q " nofstab" /proc/cmdline ; then
53    bailout 0
54 fi
55
56 grep -q 'nolabel' /proc/cmdline && NOLABEL='TRUE' || LABEL='TRUE'
57
58
59
60 if [ "$CONFIG_FSTAB" = "no" ] ; then
61     bailout 0
62 fi
63
64
65 if grep -q ' $MOUNTPOINT_PREFIX ' /proc/mounts ; then
66    logit '$MOUNTPOINT_PREFIX is a mounted directory, exiting.'
67    bailout 1
68 fi
69
70 # make sure we have the $MNTFILE before reading/writing into it
71 if [ -z "$NO_AUTO_FILE" ] ; then
72    [ -r $MNTFILE ] || touch $MNTFILE
73 fi
74
75
76 # make sure we have a /etc/fstab at all
77 (
78     flock -x 200
79 if ! [ -f /etc/fstab ] ; then
80   cat > /etc/fstab << EOF
81 # /etc/fstab - static file system information
82 # <filesystem> <mountpoint>   <type> <options>                             <dump> <pass>
83 proc           /proc          proc   rw,nosuid,nodev,noexec                 0      0
84 none           /proc/bus/usb  usbfs  defaults,noauto                        0      0
85 sysfs          /sys           sysfs  rw,nosuid,nodev,noexec                 0      0
86 devpts         /dev/pts       devpts noauto,mode=0622                       0      0
87 /dev/external  $MOUNTPOINT_PREFIX/external  auto   user,noauto,exec,rw,uid=grml,gid=grml  0      0
88 /dev/external1 $MOUNTPOINT_PREFIX/external1 auto   user,noauto,exec,rw,uid=grml,gid=grml  0      0
89 /dev/cdrom     $MOUNTPOINT_PREFIX/cdrom     auto   user,noauto,exec,ro                    0      0
90 /dev/dvd       $MOUNTPOINT_PREFIX/dvd       auto   user,noauto,exec,ro                    0      0
91 # some other examples:
92 # /dev/sda1      /Grml         ext3    dev,suid,user,noauto 0  2
93 # //1.2.3.4/pub  /smb/pub      smbfs   defaults,user,noauto,uid=grml,gid=grml 0 0
94 # linux:/pub     /beer         nfs     defaults             0  0
95 # tmpfs          /tmp          tmpfs   size=300M            0  0
96 # none           /proc/bus/usb usbfs   defaults,nodev,noexec,nosuid,noauto,devgid=1001,devmode=664 0 0
97 # 192.168.1.101:/backups /mnt/nfs nfs  defaults,user,wsize=8192,rsize=8192 0 0
98 #
99 # Warning! Please do *not* change any lines below because they are auto-generated.
100 # If you want to disable rebuildfstab set CONFIG_FSTAB='no' in /etc/grml/autoconfig!
101 # See 'man grml-udev-rebuildfstab' for more details about the following entries.
102 EOF
103 fi
104 ) 200>/var/run/rebuildfstab.lock
105
106 [ ! -w /etc/fstab ] && {
107   logit "fatal - /etc/fstab not writeable, exiting"
108   bailout 0
109 }
110
111 # Simple shell grep, searches for lines STARTING with string
112 stringinfile () {
113   while read line ;do
114     case "$line" in
115             ($1*) return 0 ;;
116     esac
117   done < "$2"
118   return 1
119 }
120
121 # Remove comment line $1 and the following line from file $2
122 # sed '/^# Added by GRML/{N;d;}'
123 removeentries () {
124         entry="$1"
125         entry=$(echo $1 |  sed "s#/#\\\/#g")
126         (
127                 flock -x 200
128                 sed -i -e "/$entry/{N;d}" /etc/fstab
129         ) 200>/var/run/rebuildfstab.lock
130 }
131
132
133 get_device_name() {
134 case $ID_FS_TYPE in
135 # dont use labels for some filesystem
136 iso9660)
137 break;
138 ;;
139 *)
140 if [ -n "$LABEL" ]  && [ -n "$ID_FS_LABEL_ENC" ] ; then
141   # see check_for_label() in scanpartitions for details
142   case $ID_FS_LABEL_ENC in
143     *\x*)
144       addinfo=" # special char in label ($ID_FS_LABEL_ENC) not supported"
145       break ;;
146     *)
147       echo "LABEL=$ID_FS_LABEL_ENC"
148       return
149       break;
150   esac
151 fi
152 ;;
153 esac
154 [ -n "$DM_NAME" ] && echo /dev/mapper/$DM_NAME && return
155
156 NAME="$DEVNAME"
157 for name in $DEVLINKS ; do
158     case $name in
159         *usb-sd*|*cdrom*|*dvd*)
160             NAME="$name"
161             break;
162         ;;
163 esac
164 done
165 echo "$NAME"
166 }
167
168 get_mount_point() {
169     device="$1"
170     mountpoint="${device##*/}"
171     mountpoint="${mountpoint#*=}"
172     echo "$MOUNTPOINT_PREFIX/$mountpoint"
173 }
174
175 append_fstab() {
176         (
177                 flock -x 200
178                 echo $ADDEDBYGRML $1 >> /etc/fstab
179                 echo "$2" >> /etc/fstab
180         ) 200>/var/run/rebuildfstab.lock
181
182 }
183
184
185 if [ -n "$CONFIG_FSTAB_USER" ] ; then
186     user="$CONFIG_FSTAB_USER"
187 else
188     user='1000' # take default
189 fi
190 if [ -n "$CONFIG_FSTAB_GROUP" ] ; then
191     group="$CONFIG_FSTAB_GROUP"
192 else
193     group='users' # take default
194 fi
195
196 if [ -z "$ACTION" ] ; then
197     logit "Seems that $0 is not run in a udev environment, exiting." >&2
198     bailout 1
199 fi
200
201 # ignore loop devices for now.
202 case $DEVNAME in
203 /dev/loop*)
204         bailout 0
205         ;;
206 esac
207
208 removeentries "$ADDEDBYGRML $DEVNAME" /etc/fstab
209
210 device=$(get_device_name)
211 mountpoint=$(get_mount_point $device)
212
213 # if entry is already present in /etc/fstab ignore the current event
214 (
215     flock -x 200
216     grep -v '^#' /etc/fstab > $TMPFILE
217 ) 200>/var/run/rebuildfstab.lock
218
219 for devicelink in $DEVLINKS ; do
220     # ignore external
221     case "$devicelink" in *external*) continue ;; esac
222     stringinfile $devicelink $TMPFILE && bailout 0
223 done
224
225 # if entry is already present ignore it
226 stringinfile $device $TMPFILE && bailout 0
227
228 if [ "$ID_FS_USAGE" != "filesystem" -a "$ID_FS_TYPE" != "swap" ]; then
229     # blockdevice in question won't be mountable in this case
230     bailout 0
231 fi
232
233 options=noauto,user,dev,suid,exec
234 case $ID_FS_TYPE in
235 ntfs)
236         options=$options,ro,umask=000
237         ;;
238 vfat|msdos)
239         options=$options,umask=000
240         ;;
241 ufs)
242         options=$options,ro
243         ;;
244 swap)
245         options=defaults
246         ;;
247 esac
248 case $ID_FS_TYPE in
249 ntfs|vfat|msdos)
250         test -n "$user" && options=$options,uid=$user
251         test -n "$group" && options=$options,gid=$group
252         ;;
253 esac
254
255 case $ACTION in
256 add|change)
257 (
258     flock -x 200
259     echo "$ADDEDBYGRML $DEVNAME" >> /etc/fstab
260     echo "$device $mountpoint $ID_FS_TYPE $options 0 0 $addinfo # $DEVNAME" >> /etc/fstab
261 ) 200>/var/run/rebuildfstab.lock
262
263
264 ;;
265 esac
266
267 # Clean /mnt/... according to info $MNTFILE
268 if [ -r "$MNTFILE" ] ; then
269    for directory in $(cat $MNTFILE) ; do
270      rmdir $directory 2>/dev/null && sed -i "s#$directory##" $MNTFILE
271    done
272    grep '^/.*$' $MNTFILE | sort -u > $TMPFILE
273    cat $TMPFILE > $MNTFILE
274 fi
275
276 # Make sure we have all /mnt/* directories
277 while read p m f relax; do
278   case "$m" in *none*|*proc*|*sys*|'') continue ;; esac
279   if ! grep -q "$m" /proc/mounts ; then
280      if ! [ -d "$m" ] ; then
281         if mkdir -m 755 -p "$m" ; then
282           [ -r "$MNTFILE" ] && grep -q "$m" $MNTFILE || echo "$m" >> $MNTFILE
283         fi
284      fi
285   fi
286 done <<EOT
287 $(cat /etc/fstab | grep -v '^#')
288 EOT
289
290 # sort the file again...
291 if [ -r "$MNTFILE" ] ; then
292    grep '^/.*$' $MNTFILE | sort -u > $TMPFILE
293    cat $TMPFILE > $MNTFILE
294 fi
295
296 bailout 0
297
298 ## END OF FILE #################################################################