Re: [PATCH] kvm tools: Use overlayfs when mounting rootfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Aug 9, 2011 at 5:57 PM, Sasha Levin <levinsasha928@xxxxxxxxx> wrote:
> This patch uses (the not yet merged) overlayfs to allow booting complex distribution rootfs and provide
> a COW layer within the rootfs.
>
> We use overlayfs for two reasons:
>  - Overwrite the /etc/fstab file so that the mounter will use the virtio-9p device as root instead of
> /dev/vda.
>  - Provide a COW space so that changes aren't written back to the rootfs. This allows easy testing and
> work without ruining your rootfs.
>
> Usage:
> '--overlayfs [root_dir]' - Use root_dir to boot the guest, COW is provided automatically.
>
> Please note that host kernel support needs to have overlayfs support. This feature is not yet available
> as part of the mainline kernel, therefore if you'd like to try out this patch you should pull overlayfs
> into your kernel tree.
>
> Latest version of overlayfs can be found here:
> git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git overlayfs.v11
>
> Cc: Miklos Szeredi <miklos@xxxxxxxxxx>
> Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx>
> ---
>  tools/kvm/Makefile                  |    2 +-
>  tools/kvm/builtin-run.c             |   87 +++++++++++++++++++++++++++++++++--
>  tools/kvm/include/kvm/builtin-run.h |    5 ++
>  tools/kvm/kvm-cpu.c                 |    2 +
>  4 files changed, 91 insertions(+), 5 deletions(-)
>
> diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
> index 8d45ebf..acb3aca 100644
> --- a/tools/kvm/Makefile
> +++ b/tools/kvm/Makefile
> @@ -130,7 +130,7 @@ DEFINES     += -D_GNU_SOURCE
>  DEFINES        += -DKVMTOOLS_VERSION='"$(KVMTOOLS_VERSION)"'
>
>  KVM_INCLUDE := include
> -CFLAGS += $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -Os -g
> +CFLAGS += $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -O0 -g

Please drop this :-)

>
>  ifneq ($(WERROR),0)
>        WARNINGS += -Werror
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index c8539cc..19f7d6b 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -76,6 +76,7 @@ static const char *guest_mac;
>  static const char *host_mac;
>  static const char *script;
>  static const char *guest_name;
> +static const char *overlayfs;
>  static bool single_step;
>  static bool readonly_image[MAX_DISK_IMAGES];
>  static bool vnc;
> @@ -91,6 +92,13 @@ bool do_debug_print = false;
>  static int nrcpus;
>  static int vidmode = -1;
>
> +/* Apperantly <linux/fs.h> and <sys/mount.h> don't work well together */
> +int mount(const char *source, const char *target,
> +         const char *filesystemtype, unsigned long mountflags,
> +         const void *data);
> +int umount(const char *target);
> +
> +
>  static const char * const run_usage[] = {
>        "kvm run [<options>] [<kernel image>]",
>        NULL
> @@ -169,6 +177,7 @@ static const struct option options[] = {
>        OPT_BOOLEAN('\0', "balloon", &balloon, "Enable virtio balloon"),
>        OPT_BOOLEAN('\0', "vnc", &vnc, "Enable VNC framebuffer"),
>        OPT_BOOLEAN('\0', "sdl", &sdl, "Enable SDL framebuffer"),
> +       OPT_STRING('\0', "overlayfs", &overlayfs, "overlayfs", "Root FS"),
>
>        OPT_GROUP("Kernel options:"),
>        OPT_STRING('k', "kernel", &kernel_filename, "kernel",
> @@ -491,6 +500,71 @@ void kvm_run_help(void)
>        usage_with_options(run_usage, options);
>  }
>
> +int kvm_create_overlayfs(struct kvm* kvm)
> +{
> +       char tmp[PATH_MAX];
> +       char cow[PATH_MAX], overlay[PATH_MAX], rootfs[PATH_MAX];
> +
> +       /*
> +        * Create 3 directories for building our mount.
> +        * Read rootfs -> modification layer -> cow layer -> new root
> +        */
> +
> +       sprintf(cow, "%s-cow", guest_name);
> +       sprintf(rootfs, "%s-rootfs", guest_name);
> +       sprintf(overlay, "%s-overlay", guest_name);
> +
> +       if (mkdir(cow, 0777) < 0) {
> +               /* If the COW dir is already there it's ok - just use it */
> +               if (errno != EEXIST)
> +                       goto cleanup;
> +       }
> +
> +       if (mkdir(rootfs, 0777) < 0)
> +               goto cleanup;
> +
> +       if (mkdir(overlay, 0777) < 0)
> +               goto cleanup;
> +
> +       sprintf(tmp, "lowerdir=%s,upperdir=virt", overlayfs);
> +       if (mount("overlayfs", overlay, "overlayfs", MS_MGC_VAL, tmp) < 0) {
> +               printf("%d\n", errno);
> +               goto cleanup;
> +
> +       }
> +
> +       sprintf(tmp, "lowerdir=%s,upperdir=%s", overlay, cow);
> +       if (mount("overlayfs", rootfs, "overlayfs", MS_MGC_VAL, tmp) < 0)
> +               goto cleanup;
> +
> +       if (realpath(rootfs, tmp) == 0 ||
> +           virtio_9p__init(kvm, tmp, "/dev/root") < 0)
> +               die("Unable to initialize virtio 9p");
> +       using_rootfs = 1;
> +
> +       return 0;
> +
> +cleanup:
> +       kvm_remove_overlayfs();
> +
> +       return -1;
> +}
> +
> +void kvm_remove_overlayfs(void)
> +{
> +       char cow[PATH_MAX], overlay[PATH_MAX], rootfs[PATH_MAX];
> +
> +       sprintf(cow, "%s-cow", guest_name);
> +       sprintf(rootfs, "%s-rootfs", guest_name);
> +       sprintf(overlay, "%s-overlay", guest_name);
> +
> +       umount(rootfs);
> +       umount(overlay);
> +       rmdir(cow);
> +       rmdir(overlay);
> +       rmdir(rootfs);
> +}

I guess this is OK for this patch but for the long-term I think we
should make the guests persistent so that

  kvm run

picks up the previous copy-on-write overlayfs automatically. That'd
probably mean that 'kvm run' will always attempt to use a guest named
'default' that's automatically created upon the first time 'kvm run'
is invoked.

We should also make 'kvm list' print out something like

  default [powered off]

Ingo probably has some ideas on this as well.

> +
>  int kvm_cmd_run(int argc, const char **argv, const char *prefix)
>  {
>        struct virtio_net_parameters net_params;
> @@ -634,7 +708,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
>                strlcat(real_cmdline, kernel_cmdline, sizeof(real_cmdline));
>
>        hi = NULL;
> -       if (!using_rootfs && !image_filename[0]) {
> +       if (!overlayfs && !using_rootfs && !image_filename[0]) {
>                hi = host_image(real_cmdline, sizeof(real_cmdline));
>                if (hi) {
>                        image_filename[0] = hi;
> @@ -643,12 +717,17 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
>                }
>        }
>
> -       if (!strstr(real_cmdline, "root="))
> -               strlcat(real_cmdline, " root=/dev/vda rw ", sizeof(real_cmdline));
> +       if (overlayfs) {
> +               if (kvm_create_overlayfs(kvm) < 0)
> +                       die("Failed creating overlayfs - did you remember to apply the overlayfs patches?");
> +       }
>
> -       if (using_rootfs)
> +       if (using_rootfs || overlayfs)
>                strcat(real_cmdline, " root=/dev/root rootflags=rw,trans=virtio,version=9p2000.u rootfstype=9p");
>
> +       if (!strstr(real_cmdline, "root="))
> +               strlcat(real_cmdline, " root=/dev/vda rw ", sizeof(real_cmdline));
> +
>        if (image_count) {
>                kvm->nr_disks = image_count;
>                kvm->disks    = disk_image__open_all(image_filename, readonly_image, image_count);
> diff --git a/tools/kvm/include/kvm/builtin-run.h b/tools/kvm/include/kvm/builtin-run.h
> index d056ad4..aa12a42 100644
> --- a/tools/kvm/include/kvm/builtin-run.h
> +++ b/tools/kvm/include/kvm/builtin-run.h
> @@ -1,6 +1,11 @@
>  #ifndef __KVM_RUN_H__
>  #define __KVM_RUN_H__
>
> +struct kvm;
> +
> +void kvm_remove_overlayfs(void);
> +int kvm_create_overlayfs(struct kvm* kvm);
> +
>  int kvm_cmd_run(int argc, const char **argv, const char *prefix);
>  void kvm_run_help(void);
>
> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
> index 2f5d23c..6f60138 100644
> --- a/tools/kvm/kvm-cpu.c
> +++ b/tools/kvm/kvm-cpu.c
> @@ -3,6 +3,7 @@
>  #include "kvm/symbol.h"
>  #include "kvm/util.h"
>  #include "kvm/kvm.h"
> +#include "kvm/builtin-run.h"
>
>  #include <asm/msr-index.h>
>
> @@ -422,6 +423,7 @@ static void kvm_cpu__handle_coalesced_mmio(struct kvm_cpu *cpu)
>  void kvm_cpu__reboot(void)
>  {
>        pthread_kill(kvm_cpus[0]->thread, SIGKVMEXIT);
> +       kvm_remove_overlayfs();
>  }
>
>  int kvm_cpu__start(struct kvm_cpu *cpu)
> --
> 1.7.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux