diff --git a/etc/init.d/zfs-functions.in b/etc/init.d/zfs-functions.in index 372bae8037fe..1d90f9ae676f 100644 --- a/etc/init.d/zfs-functions.in +++ b/etc/init.d/zfs-functions.in @@ -304,17 +304,33 @@ checksystem() return 0 } +# Originated in commit f5ef7150ead1f6234e18eb3bda0299f34209bbb8 by Rudd-O. +# This function is called from zfs-mount when (if!) /etc/mtab is NOT a +# link to /proc/mounts (which it should be). +# The function will update /etc/mtab with any mounts missing in that file, +# but exists in /proc/mounts. reregister_mounts() { - local fs mntpnt fstype opts rest tmpdir + local fs mntpnt fstype opts rest tmpdir mountpoint MNT_CMD tmpdir=removethismountpointhoweverpossible while read -r fs mntpnt fstype opts rest ; do - fs=$(printf '%b\n' "$fs") + mntpnt=$(/bin/echo "$mntpnt" | sed "s,\\\0,\\\00,") mntpnt=$(printf '%b\n' "$mntpnt") + + fs=$(/bin/echo "$fs" | sed "s,\\\0,\\\00,") + fs=$(printf '%b\n' "$fs") + if [ "$fstype" = "zfs" ] ; then + mountpoint=$(zfs get -H -ovalue mountpoint "$fs") if [ "$mntpnt" = "/" ] ; then - mount -f -o zfsutil -t zfs --move / /$tmpdir + if [ "$mountpoint" = "legacy" ]; then + MNT_CMD="mount -f -t zfs" + else + MNT_CMD="mount -f -t zfs -o zfsutil" + fi + + $MNT_CMD --move / /$tmpdir umount --fake /$tmpdir else umount --fake "$mntpnt" @@ -327,13 +343,23 @@ reregister_mounts() umount --fake "$mntpnt" fi fi - done < /proc/mounts + done < /etc/mtab while read -r fs mntpnt fstype opts rest ; do - fs=$(printf '%b\n' "$fs") + mntpnt=$(/bin/echo "$mntpnt" | sed "s,\\\0,\\\00,") mntpnt=$(printf '%b\n' "$mntpnt") + + fs=$(/bin/echo "$fs" | sed "s,\\\0,\\\00,") + fs=$(printf '%b\n' "$fs") if [ "$fstype" = "zfs" ] ; then - mount -f -t zfs -o zfsutil "$fs" "$mntpnt" + mountpoint=$(zfs get -H -ovalue mountpoint "$fs") + if [ "$mountpoint" = "legacy" ]; then + MNT_CMD="mount -f -t zfs" + else + MNT_CMD="mount -f -t zfs -o zfsutil" + fi + + $MNT_CMD "$fs" "$mntpnt" elif echo "$fs" | grep -q "^/dev/zd" ; then mount -f -t "$fstype" -o "$opts" "$fs" "$mntpnt" fi @@ -373,9 +399,23 @@ read_mtab() while read -r fs mntpnt fstype opts rest; do if echo "$fs $mntpnt $fstype $opts" | grep -qE "$match"; then + # * Fix problems (!?) in the mounts file. It will record + # 'rpool 1' as 'rpool\0401' instead of 'rpool\00401' + # which seems to be the correct (at least as far as + # 'printf' is concerned). + # * We need to use the external echo, because the + # internal one would interpret the backslash code + # (incorrectly), giving us a  instead. + mntpnt=$(/bin/echo "$mntpnt" | sed "s,\\\0,\\\00,") + fs=$(/bin/echo "$fs" | sed "s,\\\0,\\\00,") + + # Replace 'unwanted' characters with underscore. mntpnt=$(printf '%b\n' "$mntpnt" | sed -e 's,/,_,g' \ - -e 's,-,_,g' -e 's,\.,_,g') - eval export MTAB_$mntpnt="$fs" + -e 's,-,_,g' -e 's,\.,_,g' -e 's, ,_,g') + fs=$(printf '%b\n' "$fs") + + # Set the variable. + eval export MTAB_$mntpnt=\"$fs\" fi done < /proc/mounts }