#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;
return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
for (;;) {
+ bool shall_keep = false;
struct libmnt_fs *fs;
const char *path;
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;
#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) {