chiark / gitweb /
core: open /proc/self/mountinfo early to allow mounts over /proc (#5985)
[elogind.git] / src / basic / mount-util.c
index fef9912072e2961914db699f8057060507bc0eb8..aee878e88d125312b72288b2c43ba58419104dc9 100644 (file)
@@ -317,11 +317,16 @@ static int get_mount_flags(const char *path, unsigned long *flags) {
         return 0;
 }
 
-int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
+/* Use this function only if do you have direct access to /proc/self/mountinfo
+ * and need the caller to open it for you. This is the case when /proc is
+ * masked or not mounted. Otherwise, use bind_remount_recursive. */
+int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **blacklist, FILE *proc_self_mountinfo) {
         _cleanup_set_free_free_ Set *done = NULL;
         _cleanup_free_ char *cleaned = NULL;
         int r;
 
+        assert(proc_self_mountinfo);
+
         /* Recursively remount a directory (and all its submounts) read-only or read-write. If the directory is already
          * mounted, we reuse the mount and simply mark it MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
          * operation). If it isn't we first make it one. Afterwards we apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to
@@ -344,7 +349,6 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
                 return -ENOMEM;
 
         for (;;) {
-                _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
                 _cleanup_set_free_free_ Set *todo = NULL;
                 bool top_autofs = false;
                 char *x;
@@ -354,9 +358,7 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
                 if (!todo)
                         return -ENOMEM;
 
-                proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
-                if (!proc_self_mountinfo)
-                        return -errno;
+                rewind(proc_self_mountinfo);
 
                 for (;;) {
                         _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
@@ -495,6 +497,16 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
         }
 }
 
+int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
+        _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+
+        proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+        if (!proc_self_mountinfo)
+                return -errno;
+
+        return bind_remount_recursive_with_mountinfo(prefix, ro, blacklist, proc_self_mountinfo);
+}
+
 int mount_move_root(const char *path) {
         assert(path);