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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list