diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index b7f3616a1d..c97a7c3188 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -43,7 +43,7 @@ #include "tmpfile-util.h" #include "user-util.h" -int umount_recursive(const char *prefix, int flags) { +int umount_recursive_full(const char *prefix, int flags, char **keep) { _cleanup_fclose_ FILE *f = NULL; int n = 0, r; @@ -64,6 +64,7 @@ int umount_recursive(const char *prefix, int flags) { return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m"); for (;;) { + bool shall_keep = false; struct libmnt_fs *fs; const char *path; @@ -80,6 +81,17 @@ int umount_recursive(const char *prefix, int flags) { if (!path_startswith(path, prefix)) continue; + STRV_FOREACH(k, keep) + /* Match against anything in the path to the dirs to keep, or below the dirs to keep */ + if (path_startswith(path, *k) || path_startswith(*k, path)) { + shall_keep = true; + break; + } + if (shall_keep) { + log_debug("Not unmounting %s, referenced by keep list.", path); + continue; + } + if (umount2(path, flags | UMOUNT_NOFOLLOW) < 0) { log_debug_errno(errno, "Failed to umount %s, ignoring: %m", path); continue; diff --git a/src/shared/mount-util.h b/src/shared/mount-util.h index 8a84d61622..b33e739b42 100644 --- a/src/shared/mount-util.h +++ b/src/shared/mount-util.h @@ -12,7 +12,12 @@ #include "macro.h" int repeat_unmount(const char *path, int flags); -int umount_recursive(const char *target, int flags); + +int umount_recursive_full(const char *target, int flags, char **keep); + +static inline int umount_recursive(const char *target, int flags) { + return umount_recursive_full(target, flags, NULL); +} int bind_remount_recursive_with_mountinfo(const char *prefix, unsigned long new_flags, unsigned long flags_mask, char **deny_list, FILE *proc_self_mountinfo); static inline int bind_remount_recursive(const char *prefix, unsigned long new_flags, unsigned long flags_mask, char **deny_list) {