diff options
author | Lennart Poettering <lennart@poettering.net> | 2022-08-24 11:23:41 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2022-08-31 22:53:18 +0200 |
commit | f11efcbeb17781a3e03596fe6b1016fbb5c31360 (patch) | |
tree | b4f674bf55ba04c8ce0b18f1e277ef5207f69ac8 /src/shutdown/umount.c | |
parent | c905aaf68607754a2aa131854544f5b44a378874 (diff) | |
download | systemd-f11efcbeb17781a3e03596fe6b1016fbb5c31360.tar.gz |
umount: unmount profcs/sysfs/.. lazily
Alternative for: df48b430a4a85f923eaecb3fadf9c514692d2082
Diffstat (limited to 'src/shutdown/umount.c')
-rw-r--r-- | src/shutdown/umount.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c index 2fd1b464e4..7ddeb67e97 100644 --- a/src/shutdown/umount.c +++ b/src/shutdown/umount.c @@ -80,7 +80,7 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) { struct libmnt_fs *fs; const char *path, *fstype; unsigned long remount_flags = 0u; - bool try_remount_ro; + bool try_remount_ro, is_api_vfs; _cleanup_free_ MountPoint *m = NULL; r = mnt_table_next_fs(table, iter, &fs); @@ -115,6 +115,8 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) { PATH_STARTSWITH_SET(path, "/dev", "/sys", "/proc")) continue; + is_api_vfs = fstype_is_api_vfs(fstype); + /* If we are in a container, don't attempt to read-only mount anything as that brings no real * benefits, but might confuse the host, as we remount the superblock here, not the bind * mount. @@ -124,7 +126,7 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) { * careful and will not hang because of the network being down. */ try_remount_ro = detect_container() <= 0 && !fstype_is_network(fstype) && - !fstype_is_api_vfs(fstype) && + !is_api_vfs && !fstype_is_ro(fstype) && !fstab_test_yes_no_option(options, "ro\0rw\0"); @@ -158,6 +160,10 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) { .remount_options = remount_options, .remount_flags = remount_flags, .try_remount_ro = try_remount_ro, + + /* Unmount sysfs/procfs/… lazily, since syncing doesn't matter there, and it's OK if + * something keeps an fd open to it. */ + .umount_lazily = is_api_vfs, }; m->path = strdup(path); @@ -634,23 +640,14 @@ static int umount_with_timeout(MountPoint *m, bool last_try) { * -EIO rather than blocking indefinitely. If the filesysten is "busy", this may allow * processes to die, thus making the filesystem less busy so the unmount might succeed * (rather than return EBUSY). */ - r = RET_NERRNO(umount2(m->path, MNT_FORCE)); + r = RET_NERRNO(umount2(m->path, + UMOUNT_NOFOLLOW | /* Don't follow symlinks: this should never happen unless our mount list was wrong */ + (m->umount_lazily ? MNT_DETACH : MNT_FORCE))); if (r < 0) { log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Failed to unmount %s: %m", m->path); if (r == -EBUSY && last_try) log_umount_blockers(m->path); - - /* If API filesystems under /oldroot cannot be unmounted we can still lazily unmount - * them to unblock /oldroot. They serve no function to us anymore and should be - * memory-only and hence safe to unmount like this. */ - if (in_initrd() && - PATH_STARTSWITH_SET(m->path, "/oldroot/dev", "/oldroot/proc", "/oldroot/sys")) { - log_info("Lazily unmounting '%s' instead.", m->path); - r = umount2(m->path, MNT_FORCE | MNT_DETACH); - if (r < 0) - log_error_errno(errno, "Failed to lazily unmount %s: %m", m->path); - } } _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); |