#!/bin/bash # Filename: scripts/grml-udev-rebuildfstab # Purpose: udev script to update /etc/fstab # Authors: grml-team (grml.org) # Bug-Reports: see http://grml.org/bugs/ # License: This file is licensed under the GPL v2+. ################################################################################ PATH="/bin:/sbin:/usr/bin:/usr/sbin" TMP=$(mktemp 2>/dev/null) TMPFILE=$(mktemp 2>/dev/null) ADDEDBYGRML="# Added by GRML" MOUNTPOINT_PREFIX=/media MNTFILE="$MOUNTPOINT_PREFIX/.grml-auto-created_do-not-delete-this-file" logit() { if [ -x /usr/bin/logger ] ; then /usr/bin/logger -i -t rebuildfstab "$*" fi } bailout() { [ -n "$1" ] && EXITCODE="$1" || EXITCODE=1 rm -f $TMP $TMPFILE /var/run/rebuildfstab.pid exit $EXITCODE } echo "$$" > /var/run/rebuildfstab.pid umask 022 [ -e /etc/grml/autconfig ] && . /etc/grml/autoconfig if ! [ -w "$(dirname $MNTFILE)" ] ; then echo "$0: can not write to $MNTFILE">&2 logit "can not write to $MNTFILE" bailout 10 fi if [ -z "$TMP" -o -z "$TMPFILE" ] ; then echo "$0: could not create tmpfile (is / mounted read-only?), exiting" >&2 logit 'fatal - could not create tmpfile (is / mounted read-only?), exiting' bailout 3 fi # trap "rm -f $TMP $TMPFILE" 2 3 11 if grep -q " nofstab" /proc/cmdline ; then bailout 0 fi if [ "$CONFIG_FSTAB" = "no" ] ; then bailout 0 fi if grep -q ' $MOUNTPOINT_PREFIX ' /proc/mounts ; then logit '$MOUNTPOINT_PREFIX is a mounted directory, exiting.' bailout 1 fi LABEL=true # by default use labels if [ -r /etc/grml/rebuildfstab.conf ] ; then logit 'Reading /etc/grml/rebuildfstab.conf' . /etc/grml/rebuildfstab.conf if [ "$LABEL" = "false" ] ; then logit 'Disabling LABEL=... in /etc/fstab as requested via LABEL=false' fi fi # support overriding via boot option if grep -q ' nolabel' /proc/cmdline ; then LABEL=false fi if grep -q ' label' /proc/cmdline ; then LABEL=true fi # default directories {{{ if [ -d "$MOUNTPOINT_PREFIX" ] ; then [ -d "$MOUNTPOINT_PREFIX/floppy" ] || mkdir "$MOUNTPOINT_PREFIX/floppy" [ -d "$MOUNTPOINT_PREFIX/cdrom" ] || mkdir "$MOUNTPOINT_PREFIX/cdrom" [ -d "$MOUNTPOINT_PREFIX/test" ] || mkdir "$MOUNTPOINT_PREFIX/test" fi # }}} # make sure we have the $MNTFILE before reading/writing into it if [ -z "$NO_AUTO_FILE" ] ; then [ -r $MNTFILE ] || touch $MNTFILE fi # make sure we have a /etc/fstab at all ( flock -x 200 if ! [ -f /etc/fstab ] ; then cat > /etc/fstab << EOF # /etc/fstab - static file system information # proc /proc proc rw,nosuid,nodev,noexec 0 0 none /proc/bus/usb usbfs defaults,noauto 0 0 sysfs /sys sysfs rw,nosuid,nodev,noexec 0 0 devpts /dev/pts devpts noauto,mode=0622 0 0 /dev/external ${MOUNTPOINT_PREFIX}/external auto user,noauto,exec,rw,uid=grml,gid=grml 0 0 /dev/external1 ${MOUNTPOINT_PREFIX}/external1 auto user,noauto,exec,rw,uid=grml,gid=grml 0 0 /dev/cdrom ${MOUNTPOINT_PREFIX}/cdrom auto user,noauto,exec,ro 0 0 /dev/dvd ${MOUNTPOINT_PREFIX}/dvd auto user,noauto,exec,ro 0 0 # some other examples: # /dev/sda1 /Grml ext3 dev,suid,user,noauto 0 2 # //1.2.3.4/pub /smb/pub smbfs defaults,user,noauto,uid=grml,gid=grml 0 0 # linux:/pub /beer nfs defaults 0 0 # tmpfs /tmp tmpfs size=300M 0 0 # none /proc/bus/usb usbfs defaults,nodev,noexec,nosuid,noauto,devgid=1001,devmode=664 0 0 # 192.168.1.101:/backups ${MOUNTPOINT_PREFIX}/nfs nfs defaults,user,wsize=8192,rsize=8192 0 0 # # Warning! Please do *not* change any lines below because they are auto-generated. # If you want to disable rebuildfstab set CONFIG_FSTAB='no' in /etc/grml/autoconfig! # See 'man grml-udev-rebuildfstab' for more details about the following entries. EOF fi ) 200>/var/run/rebuildfstab.lock [ ! -w /etc/fstab ] && { logit "fatal - /etc/fstab not writeable, exiting" bailout 0 } # Simple shell grep, searches for lines STARTING with string stringinfile () { while read line ;do case "$line" in ($1*) return 0 ;; esac done < "$2" return 1 } # Remove comment line $1 and the following line from file $2 # sed '/^# Added by GRML/{N;d;}' removeentries () { entry="$1" entry=$(echo $1 | sed "s#/#\\\/#g") ( flock -x 200 sed -i -e "/$entry/{N;d}" /etc/fstab ) 200>/var/run/rebuildfstab.lock } get_device_name() { case $ID_FS_TYPE in # dont use labels for some filesystem iso9660) break; ;; *) if "$LABEL" && [ -n "$ID_FS_LABEL_ENC" ] ; then # see check_for_label() in scanpartitions for details case $ID_FS_LABEL_ENC in *\x*) logit "special char in label ($ID_FS_LABEL_ENC) not supported, skipping label for $DEVNAME" break ;; *) echo "LABEL=$ID_FS_LABEL_ENC" return break; esac fi ;; esac [ -n "$DM_NAME" ] && echo /dev/mapper/$DM_NAME && return NAME="$DEVNAME" for name in $DEVLINKS ; do case $name in *usb-sd*|*cdrom*|*dvd*) NAME="$name" break; ;; esac done echo "$NAME" } get_mount_point() { device="$1" mountpoint="${device##*/}" mountpoint="${mountpoint#*=}" echo "$MOUNTPOINT_PREFIX/$mountpoint" } append_fstab() { ( flock -x 200 echo $ADDEDBYGRML $1 >> /etc/fstab echo "$2" >> /etc/fstab ) 200>/var/run/rebuildfstab.lock } if [ -n "$CONFIG_FSTAB_USER" ] ; then user="$CONFIG_FSTAB_USER" else user='1000' # take default fi if [ -n "$CONFIG_FSTAB_GROUP" ] ; then group="$CONFIG_FSTAB_GROUP" else group='users' # take default fi if [ -z "$ACTION" ] ; then logit "Seems that $0 is not run in a udev environment, exiting." >&2 bailout 1 fi # ignore loop devices for now. case $DEVNAME in /dev/loop*) bailout 0 ;; esac removeentries "$ADDEDBYGRML $DEVNAME" /etc/fstab device=$(get_device_name) mountpoint=$(get_mount_point $device) # if entry is already present in /etc/fstab ignore the current event ( flock -x 200 grep -v '^#' /etc/fstab > $TMPFILE ) 200>/var/run/rebuildfstab.lock for devicelink in $DEVLINKS ; do # ignore external case "$devicelink" in *external*) continue ;; esac stringinfile $devicelink $TMPFILE && bailout 0 done # if entry is already present ignore it stringinfile $device $TMPFILE && bailout 0 if [ "$ID_FS_USAGE" != "filesystem" -a "$ID_FS_TYPE" != "swap" ]; then # blockdevice in question won't be mountable in this case bailout 0 fi options=noauto,user,dev,suid,exec case $ID_FS_TYPE in ntfs) options=$options,dmask=000,fmask=111 ;; vfat|msdos) options=$options,dmask=000,fmask=111 ;; ufs) options=$options,ro ;; swap) options=defaults ;; esac case $ID_FS_TYPE in ntfs|vfat|msdos) test -n "$user" && options=$options,uid=$user test -n "$group" && options=$options,gid=$group ;; esac # when we don't use labels then write the label information into the comment if ! "$LABEL" && [ -n "$ID_FS_LABEL_ENC" ] ; then addinfo="# LABEL=$ID_FS_LABEL_ENC" devinfo="" else # otherwise (when using labels) write the device name into the comment devinfo="# $DEVNAME" fi case $ACTION in add|change) ( flock -x 200 echo "$ADDEDBYGRML $DEVNAME" >> /etc/fstab echo "$device $mountpoint $ID_FS_TYPE $options 0 0 ${addinfo}${devinfo}" >> /etc/fstab ) 200>/var/run/rebuildfstab.lock ;; esac # Clean $MOUNTPOINT_PREFIX according to info $MNTFILE if [ -r "$MNTFILE" ] ; then for directory in $(cat $MNTFILE) ; do rmdir $directory 2>/dev/null && sed -i "s#$directory##" $MNTFILE done grep '^/.*$' $MNTFILE | sort -u > $TMPFILE cat $TMPFILE > $MNTFILE fi # Make sure we have all directories in $MOUNTPOINT_PREFIX while read p m f relax; do case "$m" in *none*|*proc*|*sys*|'') continue ;; esac if ! grep -q "$m" /proc/mounts ; then if ! [ -d "$m" ] ; then if mkdir -m 755 -p "$m" ; then [ -r "$MNTFILE" ] && grep -q "$m" $MNTFILE || echo "$m" >> $MNTFILE fi fi fi done < $TMPFILE cat $TMPFILE > $MNTFILE fi bailout 0 ## END OF FILE #################################################################