rebuildfstab ignores "nofstab" or "forensic" if not last boot param
Dear Klaus,
I did some work on rebuildfstab and would like to propose some additional
changes (see diff below). I only worked on the udev section of the code
because, as far as I can tell, the legacy ("mode B") section is not being
run by any other programs. (Is it?)
(@@ -29,19 +29,21 @@)
1. Checks for boot parameters "nofstab" and "forensic" fail when the
parameter is not at the end of /proc/cmdline.
Using more complicated patterns only reveals two further problems:
1a. Boot parameter "nofstab" is ignored if "forensic" is present.
1b. Boot parameter "forensic" is ignored if "nofstab" is present and
overridden with $force.
Instead, I adopted the method from checkbootparam() in /init: looping
through /proc/cmdline checking each parameter.
(@@ -88,9 +90,9 @@)
2. When $forensic is set, all partitions lose all other options, in
particular, "noauto".
I assume 'options="ro"' is supposed to be 'options="ro,$options"', of
course, I may be mistaken.
(@@ -105,8 +107,23 @@)
3. The present check for a manual fstab entry by device name is good, but
device names vary depending on where you plug it in. I propose the
function check_manual_entry_present(), which additionally checks for LABEL
and UUID entries matching the variables provided by udev.
(@@ -131,25 +148,31 @@)
4. I think the script should not chown the $MOUNTPOINT directory if it
already exists.
5. I suggest using check_manual_entry_present() to check DEVNAME LABEL
UUID (vs. DEVNAME only) before calling add_fstab_entry()
6. I think that when there is a manual entry, the script should not
attempt to rmdir $MOUNTPOINT when a device is removed, because it will not
replace it when the device is added again.
Looking forward to the next revision...
Best regards,
Andrew
--- rebuildfstab-0.6-4/rebuildfstab 2011-07-24 23:54:40.000000000 +0000
+++ rebuildfstab-props/rebuildfstab 2011-08-12 17:10:38.000000000 +0000 @@
-29,19 +29,21 @@
shift
arg="$1"
done
-case "$(cat /proc/cmdline)" in
- *\ nofstab)
+for i in $(cat /proc/cmdline); do
+ case "$i" in
+ nofstab)
if [ -z "$force" ]; then
[ -n "$verbose" ] && echo "$0: nofstab bootoption detected, exiting."
>&2
exit 0
fi
;;
- *\ forensic)
+ forensic)
forensic="true"
;;
-esac
+ esac
+done
[ ! -r /proc/partitions ] && { echo "$0: /proc not mounted, exiting" >&2;
exit 1; }
MYPID="$$"
@@ -88,9 +90,9 @@
# Add or replace udev-generated entry to/in /etc/fstab
# add_fstab_entry device [mountpoint]
add_fstab_entry(){
local device="$1" mountpoint="$2" fstype="$ID_FS_TYPE"
options="noauto,users,exec"
- [ -n "$forensic" ] && options="ro"
+ [ -n "$forensic" ] && options="ro,$options"
[ -n "$fstype" ] || fstype="auto"
[ -n "$mountpoint" ] || { mountpoint="${device#/dev/}";
mountpoint="/media/${mountpoint}"; }
case "$fstype" in
ntfs*|vfat|msdos) options="${options},umask=000"
@@ -105,8 +107,23 @@
$device $mountpoint $fstype $options 0 0
.
}
+# check_manual_entry_present device label uuid
+check_manual_entry_present() {
+ local device=$1 label=$2 uuid=$3
+ # udev uses these hex escapes, but only octal escapes are legal in fstab
+ label=${label//\\x20/\\040}; uuid=${uuid//\\x20/\\040};
+ label=${label//\\x09/\\011}; uuid=${uuid//\\x09/\\011};
+ label=${label//\\x0a/\\012}; uuid=${uuid//\\x0a/\\012};
+ label=${label//\\x5c/\\134}; uuid=${uuid//\\x5c/\\134}; # (\134, not
\0134)
+ local pattern="^($device"
+ [ -n "$label" ] && pattern="$pattern|LABEL=$label"
+ [ -n "$uuid" ] && pattern="$pattern|UUID=$uuid"
+ pattern="$pattern)[[:space:]]"
+ grep -qE "$pattern" /etc/fstab
+}
+
### MAIN
###
### We now have two operation modes:
### A) do what udev tells us (add/remove partition entries) if DEVNAME
and ACTION is set
@@ -131,25 +148,31 @@
[ -n "$forensic" ] && blockdev --setro "$DEVNAME" >/dev/null 2>&1 if [
"$ID_FS_TYPE" = "swap" ]; then
MOUNTPOINT="none"
else
- [ -d "$MOUNTPOINT" ] || mkdir -m 755 -p "$MOUNTPOINT"
- chown "$mpowner"."$mpgroup" "$MOUNTPOINT" 2>/dev/null
+ if ! [ -d "$MOUNTPOINT" ]; then
+ mkdir -m 755 -p "$MOUNTPOINT"
+ chown "$mpowner"."$mpgroup" "$MOUNTPOINT" 2>/dev/null
+ fi
compat="/mnt/${MOUNTPOINT##*/}"
[ -d "$compat" -o -L "$compat" ] || ln -sf "$mountpoint" "$compat"
2>/dev/null
fi
# Remove auto-generated entry
remove_fstab_entry "$DEVNAME"
# Add new entry (if no manually generated is present)
- grep -q "^$DEVNAME" /etc/fstab || add_fstab_entry "$DEVNAME"
"$MOUNTPOINT"
+ check_manual_entry_present "$DEVNAME" "$ID_FS_LABEL_ENC"
"$ID_FS_UUID_ENC" \
+ || add_fstab_entry "$DEVNAME" "$MOUNTPOINT"
;;
remove)
if grep -q "^$DEVNAME " /proc/mounts; then
umount -drf "$DEVNAME" >/dev/null 2>&1
umount -l "$DEVNAME" >/dev/null 2>&1
fi
- [ -d "$MOUNTPOINT" ] && rmdir "$MOUNTPOINT" >/dev/null 2>&1
+ # Remove auto-generated entry
remove_fstab_entry "$DEVNAME" "$MOUNTPOINT"
+ # Only remove directory if we are in charge for this device
+ check_manual_entry_present "$DEVNAME" \
+ || { [ -d "$MOUNTPOINT" ] && rmdir "$MOUNTPOINT" >/dev/null 2>&1; }
;;
esac
else # Non-udev behaviour
[ -n "$verbose" ] && echo "Scanning for new harddisks/partitions..." >&2
Reply to: