[libvirt] [sandbox v2 08/11] qemu: use mounts targeting / as root

Cédric Bosdonnat cbosdonnat at suse.com
Mon Jun 29 16:44:16 UTC 2015


So far a mount with / as target doesn't change anything: the host / is
still the one mounted as /. libvirt-sandbox-init-qemu now detects the
presence of a / target in mounts.cfg and mounts it instead of
sandbox:root.
---
 libvirt-sandbox/libvirt-sandbox-init-qemu.c | 79 ++++++++++++++++++++++++++++-
 1 file changed, 77 insertions(+), 2 deletions(-)

diff --git a/libvirt-sandbox/libvirt-sandbox-init-qemu.c b/libvirt-sandbox/libvirt-sandbox-init-qemu.c
index 4a3883d..09580da 100644
--- a/libvirt-sandbox/libvirt-sandbox-init-qemu.c
+++ b/libvirt-sandbox/libvirt-sandbox-init-qemu.c
@@ -52,6 +52,7 @@
 #define ATTR_UNUSED __attribute__((__unused__))
 
 #define STREQ(x,y) (strcmp(x,y) == 0)
+#define STRNEQ(x,y) (strcmp(x,y) != 0)
 
 static void print_uptime (void);
 static void insmod (const char *filename);
@@ -216,6 +217,79 @@ mount_entry(const char *source,
     }
 }
 
+static void
+mount_root(const char *path)
+{
+    int foundRoot = 0;
+
+    /* Loop over mounts.cfg to see if we have a candidate for / */
+    mount_mkdir(SANDBOXCONFIGDIR, 0755);
+    mount_9pfs("sandbox:config", SANDBOXCONFIGDIR, 0755, 1);
+
+    FILE *fp = fopen(SANDBOXCONFIGDIR "/mounts.cfg", "r");
+    while (fgets(line, sizeof line, fp) && !foundRoot) {
+        char *source = line;
+        char *target = strchr(source, '\t');
+        *target = '\0';
+        target++;
+        char *type = strchr(target, '\t');
+        *type = '\0';
+        type++;
+        char *opts = strchr(type, '\t');
+        *opts = '\0';
+        opts++;
+        char *tmp = strchr(opts, '\n');
+        *tmp = '\0';
+
+        if (STREQ(target, "/")) {
+            int needsDev = strncmp(source, "/dev/", 5) == 0;
+
+            if (debug)
+                fprintf(stderr, "libvirt-sandbox-init-qemu: found root from %s\n",
+                        source);
+
+            /* In this case, we need to have a /dev before the chroot */
+            if (needsDev) {
+                mount_other("/proc", "proc", 0755);
+                mount_other("/dev", "devtmpfs", 0755);
+            }
+
+            mount_entry(source, path, type, opts);
+
+            if (needsDev) {
+                if (umount("/dev") < 0) {
+                    fprintf(stderr,
+                            "libvirt-sandbox-init-qemu: %s: "
+                            "cannot unmount temporary /dev: %s\n",
+                            __func__, strerror(errno));
+                    exit_poweroff();
+                }
+                if (umount("/proc") < 0) {
+                    fprintf(stderr,
+                            "libvirt-sandbox-init-qemu: %s: "
+                            "cannot unmount temporary /proc: %s\n",
+                            __func__, strerror(errno));
+                    exit_poweroff();
+                }
+            }
+            foundRoot = 1;
+        }
+    }
+    fclose(fp);
+
+    if (umount(SANDBOXCONFIGDIR) < 0) {
+        fprintf(stderr,
+                "libvirt-sandbox-init-qemu: %s: "
+                "cannot unmount temporary %s: %s\n",
+                __func__, SANDBOXCONFIGDIR, strerror(errno));
+        exit_poweroff();
+    }
+
+    /* If we couldn't get a / in the mounts, then use the host one */
+    if (!foundRoot)
+        mount_9pfs("sandbox:root", path, 0755, 1);
+}
+
 int
 main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED)
 {
@@ -259,7 +333,7 @@ main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED)
     if (debug)
         fprintf(stderr, "libvirt-sandbox-init-qemu: mounting new root on /tmproot\n");
 
-    mount_9pfs("sandbox:root", "/tmproot", 0755, 1);
+    mount_root("/tmproot");
 
     /* Note that pivot_root won't work.  See the note in
      * Documentation/filesystems/ramfs-rootfs-initramfs.txt
@@ -318,7 +392,8 @@ main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED)
             fprintf(stderr, "libvirt-sandbox-init-qemu: %s: %s -> %s (%s, %s)\n",
                     __func__, source, target, type, opts);
 
-        mount_entry(source, target, type, opts);
+        if (STRNEQ(target, "/"))
+            mount_entry(source, target, type, opts);
     }
     fclose(fp);
 
-- 
2.1.4




More information about the libvir-list mailing list