The attached patch replaces the current /etc/hotplug.d/block/10-mount and adds a shared shell script 'library' that, with this patch, is used by hotplug automount and fstab, and will be used by the rootfs on external storage package that I am working on as well.
You can turn automount completely off. You can set it to do only mounts from fstab You can set it to do only 'anonymous' mounts (mounted under /mnt/device) Ditto swap (if swap-utils is installed) You can mix and match You can control whether anonymous mounts get their filesystem checked You can control fstab filesystem checks on a per mount point basis (fsck depends on the appropriate package being installed) You can mount via uuid or label if blkid is installed I will document on the wiki if it gets accepted. Regards, Daniel -- And that's my crabbing done for the day. Got it out of the way early, now I have the rest of the afternoon to sniff fragrant tea-roses or strangle cute bunnies or something. -- Michael Devore GnuPG Key Fingerprint 86 F5 81 A5 D4 2E 1F 1C http://gnupg.org The C Shore (Daniel Dickinson's Website) http://cshore.is-a-geek.com
Index: package/base-files/files/lib/functions/mount.sh =================================================================== --- package/base-files/files/lib/functions/mount.sh (revision 0) +++ package/base-files/files/lib/functions/mount.sh (revision 0) @@ -0,0 +1,233 @@ +#!/bin/sh +# Copyright 2010 Vertical Communications + +config_get_mount() { + local cfg="$1" + config_get target "$1" target + config_get mount_device "$1" device + config_get fstype "$1" fstype 'auto' + config_get options "$1" options 'rw' + config_get enabled "$1" enabled '1' + config_get enabled_fsck "$1" enabled_fsck '0' + config_get uuid "$1" uuid + config_get label "$1" label +} + +config_get_swap() { + local cfg="$1" + config_get swap_device "$1" device + config_get enabled "$1" enabled '1' + config_get uuid "$1" uuid + config_get label "$1" label +} + +libmount_fsck() { + local device="$1" + local fstype="$2" + local fsck_enabled="$3" + [ -e "$device" ] && ( [ -z "$fsck_enabled" ] || [ "$fsck_enabled" = "1" ] ) && { + grep "$device" /proc/mounts 2>/dev/null >/dev/null && return 0 + if [ "$fstype" = "ext2" ] || [ "$fstype" = "ext3" ] || [ "$fstype" = "ext4" ]; then + [ -x "$(which e2fsck)" ] || return 0 + e2fsck -p "$device" 2>&1 | tee /proc/self/fd/2 | logger + local status="$?" + case "$status" in + 0|1) ;; #success + 2) reboot;; + 4) echo "e2fsck ($device): Warning! Uncorrected errors."| tee /proc/self/fd/2 | logger + return 1 + ;; + *) echo "e2fsck ($device): Error $status. Check not complete."| tee /proc/self/fd/2 | logger;; + esac + elif [ "$fstype" = "vfat" ] || [ "$fstype"= "msdos" ]; then + [ -x "$(which dosfsck)" ] || return 0 + dosfsck -a "$device" 2>&1 | tee /proc/self/fd/2 | logger + local status="$?" + case "$status" in + 0) ;; #success + 1) echo "dosfsck ($device): Warning! Errors detected."| tee /proc/self/fd/2 | logger + return 1 + ;; + 2) echo "dosfsck ($device): Usage error. Device not checked".| tee /proc/self/fd/2 | logger;; + esac + elif [ "$fstype" = "reiserfs" ]; then + [ -x "$(which reiserfsck)" ] || return 0 + reiserfsck -p "$device" 2>&1 | tee /proc/self/fd/2 | logger + local status="$?" + case "$status" in + 0|1) ;; #success + 2) reboot;; + 4|6) echo "reiserfsck ($device): Warning! Uncorrected errors."|tee /proc/self/fd/2 | logger + return 1 + ;; + *) echo "reiserfsck ($device): Error $status. Check not complete." | tee /proc/self/fd/2 | logger;; + esac + elif [ "$fstype" = "btrfs" ]; then + [ -x "$(which btrfsck)" ] || return 0 + btrfsck -p "$device" 2>&1 | tee /proc/self/fd/2 | logger + local status="$?" + case "$status" in + 0|1) ;; #success + 2) reboot;; + 4) echo "btrfsck ($device): Warning! Uncorrected errors."|tee /proc/self/fd/2 | logger + return 1 + ;; + *) echo "btrfsck ($device): Error $status. Check not complete." | tee /proc/self/fd/2 | logger;; + esac + fi + } + return 0 +} + +create_mount_fstab_entry() { + local device="$1" + local target="$2" + local fstype="$3" + local options="$4" + local enabled="$5" + local fstabnew="$(mktemp)" + options="${options:-rw}" + [ "$enabled" = "0" ] && options="noauto,$options" + [ -n "$target" ] || return 0 + [ -n "$device" ] || return 0 + + # We write to /etc/fstab, but it *should* be a symlink to /tmp/fstab + lock /tmp/.fstab.lck + cat /etc/fstab | grep -E -v "^$device[[:blank:]]" | grep -v "$target" >>"$fstabnew" + echo "$device $target $fstype $options 0 0" >>"$fstabnew" + cat "$fstabnew" >/etc/fstab + lock -u /tmp/.fstab.lck + rm -f $fstabnew +} + +create_swap_fstab_entry() { + local device="$1" + local enabled="$2" + local fstabnew="$(mktemp)" + [ -n "$device" ] || return 0 + + # We write to /etc/fstab, but it *should* be a symlink to /tmp/fstab + lock /tmp/.fstab.lck + cat /etc/fstab | grep -E -v "^$device[[:blank:]]" >>"$fstabnew" + [ "$enabled" != "0" ] && echo "$device none swap sw 0 0" >> "$fstabnew" + cat "$fstabnew" >/etc/fstab + lock -u /tmp/.fstab.lck + rm -f $fstabnew +} + +libmount_check_id() { + local search_device="$1" + local cfg_device="$2" + local found=false + [ -n "$uuid" ] && [ -x "$(which blkid)" ] && { + cfg_uuid="$(blkid -s UUID "$search_device" | cut -f2 -d\ )" + [ "$cfg_uuid" = "UUID=\"$uuid\"" ] && found=true + } + [ "$found" != "true" ] && [ -n "$label" ] && [ -x "$(which blkid)" ] && { + cfg_label="$(blkid -s LABEL "$search_device" | cut -f2 -d\ )" + [ "$cfg_label" = "LABEL=\"$label\"" ] && found=true + } + [ "$search_device" = "$cfg_device" ] && found=true + if [ "$found" = "true" ]; then + return 0 + else + return 1 + fi +} + +libmount_mount_id() { + local cfg="$1" + local search_device="$2" + + config_get_mount "$cfg" + if libmount_check_id "$search_device" "$mount_device"; then + create_mount_fstab_entry "$search_device" "$target" "$fstype" "$options" "$enabled" + if libmount_fsck "$search_device" "$fstype" "$fsck_enabled"; then + MOUNT_TARGET="$target" + else + NO_MOUNT=true + return 1 + fi + [ "$enabled" = "0" ] && NO_MOUNT=true + fi + return 0 +} + +libmount_swap_id() { + local cfg="$1" + local search_device="$2" + + config_get_swap "$cfg" + if libmount_check_id "$search_device" "$swap_device"; then + create_swap_fstab_entry "$search_device" "$enabled" + SWAP_TARGET="$search_device" + [ "$enabled" = "0" ] && NO_SWAP=true + fi + return 0 +} + +libmount_find_token() { + local token="$1" + local value="$2" + local device="$(blkid -l -t token="$value" | cut -f1 -d:)" + echo "$device" +} + +libmount_find_mount_token() { + local token="$1" + local value="$2" + local device="$(libmount_find_token "$token" "$value")" + config_foreach libmount_mount_id mount "$device" +} + +libmount_find_swap_token() { + local token="$1" + local value="$2" + local device="$(libmount_find_token "$token" "$value")" + config_foreach libmount_swap_id swap "$device" +} + +libmount_mount_by_section() { + local cfg="$1" + local device + config_get_mount "$cfg" + if [ -n "$uuid" ]; then + device="$(libmount_find_token "UUID" "$uuid")" + elif [ -n "$label" ]; then + device="$(libmount_find_token "LABEL" "$label")" + else + [ -e "$mount_device" ] && device="$mount_device" + fi + + [ -n "$device" ] && { + create_mount_fstab_entry "$device" "$target" "$fstype" "$options" "$enabled" + libmount_fsck "$device" "$fstype" "$enabled_fsck" || return 1 + [ -z "$enabled" ] || [ "$enabled" = "1" ] && { + return 0 + } + } + return 1 +} + +libmount_swapon_by_section() { + local cfg="$1" + local device + config_get_swap "$cfg" + if [ -n "$uuid" ]; then + device="$(libmount_find_token "UUID" "$uuid")" + elif [ -n "$label" ]; then + device="$(libmount_find_token "LABEL" "$label")" + else + [ -e "$swap_device" ] && device="$swap_device" + fi + + [ -n "$device" ] && { + create_swap_fstab_entry "$device" "$enabled" + [ -z "$enabled" ] || [ "$enabled" = "1" ] && { + target="$device" + return 0 + } + } + return 1 +} + Index: package/base-files/files/etc/init.d/fstab =================================================================== --- package/base-files/files/etc/init.d/fstab (revision 19362) +++ package/base-files/files/etc/init.d/fstab (working copy) @@ -1,30 +1,23 @@ #!/bin/sh /etc/rc.common # Copyright (C) 2007 OpenWrt.org +# Copyright (C) 2010 Vertical Communications START=20 +. /lib/functions/mount.sh + do_mount() { local cfg="$1" - - config_get device "$cfg" device - config_get target "$cfg" target - [ -n "$device" -a -n "$target" ] || return 0 - - mkdir -p $target - config_get fstype "$cfg" fstype 'auto' - config_get options "$cfg" options '-rw' - config_get_bool enabled "$cfg" "enabled" '1' - [ "$enabled" -eq 0 ] && options="noauto,$options" - echo "$device $target $fstype $options 0 0" >> /tmp/fstab + if libmount_mount_by_section "$cfg"; then + mkdir -p "$target" && mount "$target" + fi } do_swapon() { local cfg="$1" - - config_get device "$cfg" device - config_get_bool enabled "$cfg" "enabled" '1' - [ -n "$device" -a "$enabled" -gt 0 ] || return 0 - echo "$device none swap sw 0 0" >> /tmp/fstab + if libmount_swapon_by_section "$cfg"; then + [ -x "$(which swapon)" ] && swapon "$target" + fi } do_unmount() { @@ -47,17 +40,15 @@ start() { config_load fstab - echo '# WARNING: this is an auto generated file, please use uci to set static filesystems' > /tmp/fstab + echo '# WARNING: this is an auto generated file, please use uci to set defined filesystems' > /etc/fstab config_foreach do_mount mount config_foreach do_swapon swap - mount -a - [ -x /sbin/swapon ] && swapon -a } stop() { config_load fstab config_foreach do_unmount mount config_foreach do_swapoff swap - [ -x /sbin/swapoff ] && swapoff -a + [ -x "$(which swapoff)" ] && swapoff -a } Index: package/base-files/files/etc/hotplug.d/block/10-mount =================================================================== --- package/base-files/files/etc/hotplug.d/block/10-mount (revision 19362) +++ package/base-files/files/etc/hotplug.d/block/10-mount (working copy) @@ -1,16 +1,73 @@ #!/bin/sh # Copyright (C) 2009-2010 OpenWrt.org +# Copyright (C) 2010 Vertical Communications +. /lib/functions/mount.sh + blkdev=`dirname $DEVPATH` if [ `basename $blkdev` != "block" ]; then device=`basename $DEVPATH` case "$ACTION" in add) - swapon /dev/$device >/dev/null 2>/dev/null || ( - mkdir -p /mnt/$device - mount /dev/$device /mnt/$device - ) + local from_fstab + local not_in_fstab + local hotplug_swap + local got_swap + local auto_fsck + config_load fstab + config_get from_fstab "automount" from_fstab '1' + config_get anon_mount "automount" anon_mount '1' + config_get anon_swap "automount" anon_swap '0' + config_get anon_fsck "automount" anon_fsck '0' + + MOUNT_TARGET="" + SWAP_TARGET="" + NO_MOUNT=false + NO_SWAP=false + if [ "$from_fstab" = "1" ]; then + config_foreach libmount_mount_id mount "/dev/$device" + fi + if [ -n "$MOUNT_TARGET" ]; then + if [ "$from_fstab" = "1" ] && [ "$NO_MOUNT" = "false" ]; then + mkdir -p "$MOUNT_TARGET" + mount "$MOUNT_TARGET" + fi + else + if [ "$from_fstab" = "1" ]; then + config_foreach libmount_swap_id swap "/dev/$device" + if [ -n "$SWAP_TARGET" ] && [ "$NO_SWAP" = "false" ]; then + [ -x "$(which swapon)" ] && swapon "$SWAP_TARGET" + fi + fi + fi + if [ "$from_fstab" = "0" ] || [ -z "$MOUNT_TARGET" ] && [ -z "$SWAP_TARGET" ]; then + if [ -x "$(which blkid)" ]; then + local TYPE + eval "$(blkid -s TYPE /dev/$device | cut -f2 -d:)" + if [ "$TYPE" = "swap" ]; then + if [ "$anon_swap" = "1" ]; then + [ -x "$(which swapon)" ] && swapon /dev/$device >/dev/null 2>/dev/null && got_swap=true + fi + else + if libmount_fsck "/dev/$device" "$TYPE" "$anon_fsck"; then + if [ "$anon_mount" = "1" ] && [ -n "$TYPE" ]; then + mkdir -p /mnt/$device && mount /dev/$device /mnt/$device + fi + fi + fi + else + got_swap=false + if [ "$anon_swap" = "1" ]; then + [ -x "$(which swapon)" ] && swapon /dev/$device >/dev/null 2>/dev/null && got_swap=true + fi + if [ "$anon_mount" = "1" ] && [ "$got_swap" != "true" ]; then + if libmount_fsck "/dev/$device" "$TYPE" "$anon_fsck"; then + mkdir -p /mnt/$device && mount /dev/$device /mnt/$device + fi + fi + fi + fi ;; remove) umount /dev/$device @@ -18,3 +75,4 @@ esac fi + Index: package/base-files/files/etc/config/fstab =================================================================== --- package/base-files/files/etc/config/fstab (revision 19362) +++ package/base-files/files/etc/config/fstab (working copy) @@ -1,3 +1,9 @@ +config global automount + option from_fstab 1 + option anon_mount 1 + option anon_swap 0 + option anon_fsck 0 + config mount option target /home option device /dev/sda1 @@ -4,7 +10,9 @@ option fstype ext3 option options rw,sync option enabled 0 + option enabled_fsck 0 config swap option device /dev/sda2 option enabled 0 +
signature.asc
Description: This is a digitally signed message part
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel