umount -r broken due to "mountinfo unnecessary"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Karel,

I noticed that "umount -r" does not work on my system for filesystems other than root:

# umount -r /usr
umount: /usr: target is busy.

Yes, umount first tries the umount2 syscall, so "target is busy" is very expected, but there is no follow-up attempt to remount fs as read-only:

umount2("/usr", 0)                      = -1 EBUSY (Device or resource busy)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2998, ...}, AT_EMPTY_PATH) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2998
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/util-linux.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/util-linux.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "umount: ", 8umount: )                 = 8
write(2, "/usr: target is busy.", 21/usr: target is busy.)   = 21
write(2, "\n", 1
)                       = 1
dup(1)                                  = 3
close(3)                                = 0
dup(2)                                  = 3
close(3)                                = 0
exit_group(32)                          = ?
+++ exited with 32 +++

Looking at the code, "try remount read-only" section in do_umount() from libmount/src/context_umount.c seems to only be called if all these conditions are met:
 - rc < 0
 - cxt->syscall_status == -EBUSY
 - mnt_context_is_rdonly_umount(cxt)
 - src is not NULL

I added some debug code to do_umount() to see why it fails:
        DBG(CXT, ul_debugobj(cxt, "rc=%d, cxt->syscall_status=%d, mnt_context_is_rdonly_umount=%d, src=%s",
        rc, cxt->syscall_status, mnt_context_is_rdonly_umount(cxt), src));

Result:
17555: libmount:      CXT: [0x5638caf185b0]: rc=-1, cxt->syscall_status=-16, mnt_context_is_rdonly_umount=1, src=(null)

With this, I noticed the additional hint in the log coming from lookup_umount_fs_by_statfs():

17555: libmount:      CXT: [0x5638caf185b0]: umount: lookup FS
17555: libmount:      CXT: [0x5638caf185b0]:  lookup by statfs
17555: libmount:      CXT: [0x5638caf185b0]:   trying fstatfs()
17555: libmount:      CXT: [0x5638caf185b0]:   umount: disabling mountinfo

Adding "DBG(CXT, mnt_fs_print_debug(cxt->fs, stderr));" in do_umount() confirmed my assumptions:

19114: libmount:      CXT: ------ fs:
source: (null)
target: /usr
fstype: ext4

The problem seems to be that lookup_umount_fs() first calls lookup_umount_fs_by_statfs() and when it succeeds, we only get partial information - without the source.

Commenting the following section in lookup_umount_fs():

//      rc = lookup_umount_fs_by_statfs(cxt, tgt);
//      if (rc <= 0)
//              goto done;

... allows this to work and /usr gets re-mounted ro:

23821: libmount:   UPDATE: ------ fs:
source: /dev/mapper/VG0-usr
target: /usr
fstype: ext3
optstr: rw,defaults,data=journal,nodev,remount
VFS-optstr: rw,nodev,remount
FS-opstr: data=journal
user-optstr: defaults

umount2("/usr", 0)                      = -1 EBUSY (Device or resource busy)
mount("/dev/mapper/VG0-usr", "/usr", NULL, MS_RDONLY|MS_REMOUNT, NULL) = 0

Clearly this is not the right fix, but perhaps something like this would be correct:

@@ -275,6 +275,7 @@
      || mnt_context_is_lazy(cxt)
      || mnt_context_is_nocanonicalize(cxt)
      || mnt_context_is_loopdel(cxt)
+     || mnt_context_is_rdonly_umount(cxt)
      || mnt_safe_stat(tgt, &st) != 0 || !S_ISDIR(st.st_mode)
      || has_utab_entry(cxt, tgt))
       return 1; /* not found */

I wonder if we just missed the mnt_context_is_rdonly_umount case in https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/commit/?id=6a52473ecd877227f6f7da2b95da0b51593ffec1?

Thanks,
 Krzysztof




[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux