Util-Linux Archive mirror
 help / color / mirror / Atom feed
From: "Krzysztof Olędzki" <ole@ans.pl>
To: Karel Zak <kzak@redhat.com>
Cc: util-linux@vger.kernel.org
Subject: umount -r broken due to "mountinfo unnecessary"
Date: Thu, 18 Apr 2024 01:00:56 -0700	[thread overview]
Message-ID: <315f1f43-013f-48c9-9016-474dc9d53a04@ans.pl> (raw)

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

             reply	other threads:[~2024-04-18  8:06 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-18  8:00 Krzysztof Olędzki [this message]
2024-04-22 11:43 ` umount -r broken due to "mountinfo unnecessary" Karel Zak
2024-04-22 15:06   ` Krzysztof Olędzki
2024-04-23  8:33 ` Karel Zak
2024-04-23 14:35   ` Krzysztof Olędzki
2024-04-24 10:15     ` Karel Zak
2024-05-01  4:31       ` Krzysztof Olędzki
2024-05-01 19:30         ` Karel Zak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=315f1f43-013f-48c9-9016-474dc9d53a04@ans.pl \
    --to=ole@ans.pl \
    --cc=kzak@redhat.com \
    --cc=util-linux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).