/etc/init.d/umountroot doesn't umount root, resulting in possible data loss

Bug #29187 reported by Chris Moore
16
Affects Status Importance Assigned to Milestone
sysvinit (Ubuntu)
Fix Released
Medium
Unassigned
util-linux (Ubuntu)
Invalid
Low
Unassigned

Bug Description

For the last few weeks I've been noticing that my root filesystem is having its transaction log replayed every time I boot. This usually indicates that the filesystem wasn't umounted before shutting down.

I found out what is going on.

I run dapper, and have a breezy partition which I chroot to sometimes.

I want the breezy chroot to be able to see my dapper files, so I use a --bind mount to make dapper's root partition available inside the breezy chroot.

The relevant lines in my /etc/fstab are:

    # the root partition
    /dev/hda6 / reiserfs defaults 0 0
    # remount the root partition inside the breezy chroot
    / /mnt/breezy/mnt/dapper none bind 0 0

Now... when /etc/init.d/umountroot comes to try to remount the root filesystem readonly, it runs this:

    mount -n -o remount,ro /

The mount command sees that I only specified one of <mountpoint> and <device> and so tries to "find the other pathname in fstab" (mount/mount.c, line 1700).

It does this as follows:

   if ((mc = getfsspec (spec)) == NULL && /* Find the device SPEC in fstab. */
       (mc = getfsfile (spec)) == NULL && /* Find the dir FILE in fstab. */

ie. it first of all tries to find a line in /etc/fstab with a device of "/", before trying to find a line with a mountpoint of "/", and so it finds the "bind" line, and uses that.

This results in the error message:

    mount: /mnt/breezy/mnt/dapper not mounted already, or bad option

(since everything other than / has been umounted already by /etc/init.d/umountfs).

The end result is that /dev/hda6 is left mounted, and then the power is turned off, resulting in possible data loss.

Switching the order of the calls to getfsspac() and getfsfile() in util-linux-2.12r/mount/mount.c (lines 1702-1703) fix the problem for me, since then it will check for matching mount points in /etc/fstab before checking for matching devices.

An alternative solution would be to work around the problem in /etc/init.d/umountroot and to run "mount -n -o remount,ro /dev/hda6" instead.

The mount(8) man page says:

 (ii) When mounting a file system mentioned in fstab, it
 suffices to give only the device, or only the mount point.

but doesn't say what happens if the argument you give appears in both the device and mount point fields of the fstab.

Revision history for this message
Chris Moore (dooglus) wrote :

Could somebody look at this bug please? It's quite important, and results in my root filesystem never being remounted readonly before a reboot.

To reproduce it, try this:

1. try remounting the root filesystem like /etc/init.d/umountroot does it when you shut down. it can't, because it's busy,but at least it finds the first mount point:

  $ sudo mount -n -o remount,ro /
  mount: / is busy

2. add a "bind" mount of the root filesystem to /etc/fstab:

  $ mkdir /tmp/root
  $ sudo bash -c "echo / /tmp/root none bind 0 0 >> /etc/fstab"

3. repeat step 1. this time mount doesn't find the correct mount point, so even if the filesystem wasn't busy, the command would still fail when you shut down:

  $ sudo mount -n -o remount,ro /
  mount: /tmp/root not mounted already, or bad option

Revision history for this message
Chris Moore (dooglus) wrote : patch to fix the problem

This works around the problem.

It might be better to fix the problem in the 'mount' command itself, but any fix is better than the current situation of switching off with the root filesystem mounted readwrite as currently happens.

Revision history for this message
Chris Moore (dooglus) wrote :

[ I'll try that again... bug 32301 bit my last upload ]

This works around the problem.

It might be better to fix the problem in the 'mount' command itself, but any fix is better than the current situation of switching off with the root filesystem mounted readwrite as currently happens.

Revision history for this message
Chris Moore (dooglus) wrote :

Can I just add that it's not a good idea to leave the

  / /tmp/root none bind 0 0

line in your /etc/fstab when rebooting. Or / will get mounted into /tmp/root, and then /tmp will be cleaned out, in effect deleting all your files.

Ouch! (Anyone know any good file recovery tools? :) )

Revision history for this message
Scott James Remnant (Canonical) (canonical-scott) wrote :

Not a util-linux bug

Changed in util-linux:
status: Unconfirmed → Rejected
Revision history for this message
Scott James Remnant (Canonical) (canonical-scott) wrote :

Confirmed, though not sure of the most appropriate fix -- the one you suggest is "complicated", and besides, requires /usr being mounted at that point (which it won't be)

Changed in sysvinit:
status: Unconfirmed → Confirmed
Revision history for this message
Chris Moore (dooglus) wrote :

Maybe we could use the same fix that debian did?

My /mnt/sid/etc/init.d/umountroot has these lines:

do_stop () {
 [ "$VERBOSE" = no ] || log_action_begin_msg "Mounting root filesystem read-only"
 MOUNT_FORCE_OPT=
 [ "$(uname -s)" = "GNU/kFreeBSD" ] && MOUNT_FORCE_OPT=-f
 # This:
 # mount -n -o remount,ro /
 # will act on a bind mount of / if there is one.
 # See #339023 and the comment in checkroot.sh
 mount $MOUNT_FORCE_OPT -n -o remount,ro -t dummytype dummydev / 2>/dev/null \
 || mount $MOUNT_FORCE_OPT -n -o remount,ro dummydev / 2>/dev/null \
 || mount $MOUNT_FORCE_OPT -n -o remount,ro /
 ES=$?
 [ "$VERBOSE" = no ] || log_action_end_msg $ES
}

Specifying a device, even if it's "dummydev" seems to do the trick.

Revision history for this message
Scott James Remnant (Canonical) (canonical-scott) wrote :

We picked up the fix from Debian during edgy

Changed in sysvinit:
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.