[libvirt] [sandbox PATCH 4/4] Add host-image format parameter

Cédric Bosdonnat cbosdonnat at suse.com
Mon Jun 15 13:43:46 UTC 2015


Let the user specify the format of the source disk image in host-image
mounts. This will allow us to mount other image types than raw ones.
---
 .../libvirt-sandbox-builder-container.c            |  4 +
 libvirt-sandbox/libvirt-sandbox-builder-machine.c  |  9 +++
 .../libvirt-sandbox-config-mount-host-image.c      | 91 +++++++++++++++++++++-
 .../libvirt-sandbox-config-mount-host-image.h      |  5 +-
 libvirt-sandbox/libvirt-sandbox-config.c           | 68 +++++++++++++++-
 libvirt-sandbox/libvirt-sandbox.sym                |  5 ++
 libvirt-sandbox/tests/test-config.c                |  1 +
 7 files changed, 175 insertions(+), 8 deletions(-)

diff --git a/libvirt-sandbox/libvirt-sandbox-builder-container.c b/libvirt-sandbox/libvirt-sandbox-builder-container.c
index c3a58b2..383c956 100644
--- a/libvirt-sandbox/libvirt-sandbox-builder-container.c
+++ b/libvirt-sandbox/libvirt-sandbox-builder-container.c
@@ -273,6 +273,8 @@ static gboolean gvir_sandbox_builder_container_construct_devices(GVirSandboxBuil
             g_object_unref(fs);
         } else if (GVIR_SANDBOX_IS_CONFIG_MOUNT_HOST_IMAGE(mconfig)) {
             GVirSandboxConfigMountFile *mfile = GVIR_SANDBOX_CONFIG_MOUNT_FILE(mconfig);
+            GVirSandboxConfigMountHostImage *mimage = GVIR_SANDBOX_CONFIG_MOUNT_HOST_IMAGE(mconfig);
+            GVirConfigDomainDiskFormat format;
 
             fs = gvir_config_domain_filesys_new();
             gvir_config_domain_filesys_set_type(fs, GVIR_CONFIG_DOMAIN_FILESYS_FILE);
@@ -281,6 +283,8 @@ static gboolean gvir_sandbox_builder_container_construct_devices(GVirSandboxBuil
                                                   gvir_sandbox_config_mount_file_get_source(mfile));
             gvir_config_domain_filesys_set_target(fs,
                                                   gvir_sandbox_config_mount_get_target(mconfig));
+            format = gvir_sandbox_config_mount_host_image_get_format(mimage);
+            gvir_config_domain_filesys_set_driver_format(fs, format);
 
             gvir_config_domain_add_device(domain,
                                           GVIR_CONFIG_DOMAIN_DEVICE(fs));
diff --git a/libvirt-sandbox/libvirt-sandbox-builder-machine.c b/libvirt-sandbox/libvirt-sandbox-builder-machine.c
index e342ba1..5e6bf72 100644
--- a/libvirt-sandbox/libvirt-sandbox-builder-machine.c
+++ b/libvirt-sandbox/libvirt-sandbox-builder-machine.c
@@ -497,6 +497,7 @@ static gboolean gvir_sandbox_builder_machine_construct_devices(GVirSandboxBuilde
 {
     GVirConfigDomainFilesys *fs;
     GVirConfigDomainDisk *disk;
+    GVirConfigDomainDiskDriver *diskDriver;
     GVirConfigDomainInterface *iface;
     GVirConfigDomainMemballoon *ball;
     GVirConfigDomainConsole *con;
@@ -560,6 +561,8 @@ static gboolean gvir_sandbox_builder_machine_construct_devices(GVirSandboxBuilde
 
         } else if (GVIR_SANDBOX_IS_CONFIG_MOUNT_HOST_IMAGE(mconfig)) {
             GVirSandboxConfigMountFile *mfile = GVIR_SANDBOX_CONFIG_MOUNT_FILE(mconfig);
+            GVirSandboxConfigMountHostImage *mimage = GVIR_SANDBOX_CONFIG_MOUNT_HOST_IMAGE(mconfig);
+            GVirConfigDomainDiskFormat format;
             gchar *target = g_strdup_printf("vd%c", (char)('a' + nHostImage++));
 
             disk = gvir_config_domain_disk_new();
@@ -568,8 +571,14 @@ static gboolean gvir_sandbox_builder_machine_construct_devices(GVirSandboxBuilde
                                                gvir_sandbox_config_mount_file_get_source(mfile));
             gvir_config_domain_disk_set_target_dev(disk, target);
 
+            diskDriver = gvir_config_domain_disk_driver_new();
+            format = gvir_sandbox_config_mount_host_image_get_format(mimage);
+            gvir_config_domain_disk_driver_set_format(diskDriver, format);
+            gvir_config_domain_disk_set_driver(disk, diskDriver);
+
             gvir_config_domain_add_device(domain,
                                           GVIR_CONFIG_DOMAIN_DEVICE(disk));
+            g_object_unref(diskDriver);
             g_object_unref(disk);
             g_free(target);
         }
diff --git a/libvirt-sandbox/libvirt-sandbox-config-mount-host-image.c b/libvirt-sandbox/libvirt-sandbox-config-mount-host-image.c
index 61e8f42..37573ef 100644
--- a/libvirt-sandbox/libvirt-sandbox-config-mount-host-image.c
+++ b/libvirt-sandbox/libvirt-sandbox-config-mount-host-image.c
@@ -45,21 +45,90 @@
 
 struct _GVirSandboxConfigMountHostImagePrivate
 {
-    gboolean unused;
+    GVirConfigDomainDiskFormat format;
 };
 
 G_DEFINE_TYPE(GVirSandboxConfigMountHostImage, gvir_sandbox_config_mount_host_image, GVIR_SANDBOX_TYPE_CONFIG_MOUNT_FILE);
 
+enum {
+    PROP_0,
+    PROP_FORMAT,
+};
+
+enum {
+    LAST_SIGNAL
+};
+
+//static gint signals[LAST_SIGNAL];
+
+
+static void gvir_sandbox_config_mount_host_image_get_property(GObject *object,
+                                                              guint prop_id,
+                                                              GValue *value,
+                                                              GParamSpec *pspec)
+{
+    GVirSandboxConfigMountHostImage *config = GVIR_SANDBOX_CONFIG_MOUNT_HOST_IMAGE(object);
+    GVirSandboxConfigMountHostImagePrivate *priv = config->priv;
+
+    switch (prop_id) {
+    case PROP_FORMAT:
+        g_value_set_enum(value, priv->format);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    }
+}
+
+
+static void gvir_sandbox_config_mount_host_image_set_property(GObject *object,
+                                                              guint prop_id,
+                                                              const GValue *value,
+                                                              GParamSpec *pspec)
+{
+    GVirSandboxConfigMountHostImage *config = GVIR_SANDBOX_CONFIG_MOUNT_HOST_IMAGE(object);
+    GVirSandboxConfigMountHostImagePrivate *priv = config->priv;
+
+    switch (prop_id) {
+    case PROP_FORMAT:
+        priv->format = g_value_get_enum(value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    }
+}
+
 
 static void gvir_sandbox_config_mount_host_image_class_init(GVirSandboxConfigMountHostImageClass *klass)
 {
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+    object_class->get_property = gvir_sandbox_config_mount_host_image_get_property;
+    object_class->set_property = gvir_sandbox_config_mount_host_image_set_property;
+
+    g_object_class_install_property(object_class,
+                                    PROP_FORMAT,
+                                    g_param_spec_enum("format",
+                                                      "Disk format",
+                                                      "The disk format",
+                                                      GVIR_CONFIG_TYPE_DOMAIN_DISK_FORMAT,
+                                                      GVIR_CONFIG_DOMAIN_DISK_FORMAT_RAW,
+                                                      G_PARAM_READABLE |
+                                                      G_PARAM_WRITABLE |
+                                                      G_PARAM_CONSTRUCT_ONLY |
+                                                      G_PARAM_STATIC_NAME |
+                                                      G_PARAM_STATIC_NICK |
+                                                      G_PARAM_STATIC_BLURB));
+
     g_type_class_add_private(klass, sizeof(GVirSandboxConfigMountHostImagePrivate));
 }
 
 
 static void gvir_sandbox_config_mount_host_image_init(GVirSandboxConfigMountHostImage *config)
 {
-    config->priv = GVIR_SANDBOX_CONFIG_MOUNT_HOST_IMAGE_GET_PRIVATE(config);
+    GVirSandboxConfigMountHostImagePrivate *priv = config->priv;
+    priv = config->priv = GVIR_SANDBOX_CONFIG_MOUNT_HOST_IMAGE_GET_PRIVATE(config);
+
+    priv->format = GVIR_CONFIG_DOMAIN_DISK_FORMAT_RAW;
 }
 
 
@@ -72,14 +141,30 @@ static void gvir_sandbox_config_mount_host_image_init(GVirSandboxConfigMountHost
  * Returns: (transfer full): a new sandbox mount object
  */
 GVirSandboxConfigMountHostImage *gvir_sandbox_config_mount_host_image_new(const gchar *source,
-                                                                          const gchar *targetdir)
+                                                                          const gchar *targetdir,
+                                                                          GVirConfigDomainDiskFormat format)
 {
     return GVIR_SANDBOX_CONFIG_MOUNT_HOST_IMAGE(g_object_new(GVIR_SANDBOX_TYPE_CONFIG_MOUNT_HOST_IMAGE,
                                                              "source", source,
                                                              "target", targetdir,
+                                                             "format", format,
                                                              NULL));
 }
 
+/**
+ * gvir_sandbox_config_mount_host_image_get_format:
+ * @config: (transfer none): the sandbox mount config
+ *
+ * Retrieves the image format of the host-image filesystem.
+ *
+ * Returns: (transfer none): the imave format
+ */
+GVirConfigDomainDiskFormat gvir_sandbox_config_mount_host_image_get_format(GVirSandboxConfigMountHostImage *config)
+{
+    GVirSandboxConfigMountHostImagePrivate *priv = config->priv;
+    return priv->format;
+}
+
 /*
  * Local variables:
  *  c-indent-level: 4
diff --git a/libvirt-sandbox/libvirt-sandbox-config-mount-host-image.h b/libvirt-sandbox/libvirt-sandbox-config-mount-host-image.h
index 228c459..95ec05e 100644
--- a/libvirt-sandbox/libvirt-sandbox-config-mount-host-image.h
+++ b/libvirt-sandbox/libvirt-sandbox-config-mount-host-image.h
@@ -59,7 +59,10 @@ struct _GVirSandboxConfigMountHostImageClass
 GType gvir_sandbox_config_mount_host_image_get_type(void);
 
 GVirSandboxConfigMountHostImage *gvir_sandbox_config_mount_host_image_new(const gchar *source,
-                                                                          const gchar *targetdir);
+                                                                          const gchar *targetdir,
+                                                                          GVirConfigDomainDiskFormat format);
+
+GVirConfigDomainDiskFormat gvir_sandbox_config_mount_host_image_get_format(GVirSandboxConfigMountHostImage *config);
 
 G_END_DECLS
 
diff --git a/libvirt-sandbox/libvirt-sandbox-config.c b/libvirt-sandbox/libvirt-sandbox-config.c
index 8991043..fbc65a6 100644
--- a/libvirt-sandbox/libvirt-sandbox-config.c
+++ b/libvirt-sandbox/libvirt-sandbox-config.c
@@ -1266,6 +1266,7 @@ gboolean gvir_sandbox_config_add_mount_strv(GVirSandboxConfig *config,
  *
  * - host-bind:/tmp=/var/lib/sandbox/demo/tmp
  * - host-image:/=/var/lib/sandbox/demo.img
+ * - host-image:/=/var/lib/sandbox/demo.qcow2,format=qcow2
  * - guest-bind:/home=/tmp/home
  * - ram:/tmp=500M
  */
@@ -1327,6 +1328,33 @@ gboolean gvir_sandbox_config_add_mount_opts(GVirSandboxConfig *config,
         }
         mnt = GVIR_SANDBOX_CONFIG_MOUNT(gvir_sandbox_config_mount_ram_new(target,
                                                                           size));
+    } else if (type == GVIR_SANDBOX_TYPE_CONFIG_MOUNT_HOST_IMAGE) {
+        const gchar *formatStr = NULL;
+        gint format = GVIR_CONFIG_DOMAIN_DISK_FORMAT_RAW;
+
+        if ((tmp = strchr(source, ',')) != NULL) {
+            GEnumClass *enum_class = g_type_class_ref(GVIR_CONFIG_TYPE_DOMAIN_DISK_FORMAT);
+            GEnumValue *enum_value = NULL;
+
+            *tmp = '\0';
+            formatStr = tmp + 1;
+
+            if ((strncmp(formatStr, "format=", 7) == 0) &&
+                !(enum_value = g_enum_get_value_by_nick(enum_class, formatStr + 7))) {
+                g_type_class_unref(enum_class);
+                g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0,
+                            _("Unknown disk image format: '%s'"), formatStr + 7);
+                return FALSE;
+            }
+            g_type_class_unref(enum_class);
+            format = enum_value->value;
+        }
+
+        mnt = GVIR_SANDBOX_CONFIG_MOUNT(g_object_new(type,
+                                                     "target", target,
+                                                     "source", source,
+                                                     "format", format,
+                                                     NULL));
     } else {
         mnt = GVIR_SANDBOX_CONFIG_MOUNT(g_object_new(type,
                                                      "target", target,
@@ -1615,6 +1643,7 @@ static GVirSandboxConfigMount *gvir_sandbox_config_load_config_mount(GKeyFile *f
     gchar *target = NULL;
     gchar *source = NULL;
     gchar *type = NULL;
+    gchar *formatStr = NULL;
     guint j;
     GError *e = NULL;
     GType mountType;
@@ -1664,10 +1693,33 @@ static GVirSandboxConfigMount *gvir_sandbox_config_load_config_mount(GKeyFile *f
             goto error;
         }
 
-        config = GVIR_SANDBOX_CONFIG_MOUNT(g_object_new(mountType,
-                                                        "target", target,
-                                                        "source", source,
-                                                        NULL));
+        if (mountType == GVIR_SANDBOX_TYPE_CONFIG_MOUNT_HOST_IMAGE) {
+            GEnumClass *enum_class = g_type_class_ref(GVIR_CONFIG_TYPE_DOMAIN_DISK_FORMAT);
+            GEnumValue *enum_value;
+
+            if ((formatStr = g_key_file_get_string(file, key, "format", NULL)) == NULL) {
+                g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0,
+                            "%s", _("Missing image format in config file"));
+                goto error;
+            }
+
+            if (!(enum_value = g_enum_get_value_by_nick(enum_class, formatStr))) {
+                g_type_class_unref(enum_class);
+                g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0,
+                            _("Unknown image format %s in config file"), formatStr);
+                goto error;
+            }
+            g_type_class_unref(enum_class);
+
+            config = GVIR_SANDBOX_CONFIG_MOUNT(gvir_sandbox_config_mount_host_image_new(source,
+                                                                                        target,
+                                                                                        enum_value->value));
+        } else {
+            config = GVIR_SANDBOX_CONFIG_MOUNT(g_object_new(mountType,
+                                                            "target", target,
+                                                            "source", source,
+                                                            NULL));
+        }
     }
 
     for (j = 0 ; j < 1024 ; j++) {
@@ -1964,6 +2016,14 @@ static void gvir_sandbox_config_save_config_mount(GVirSandboxConfigMount *config
         g_key_file_set_string(file, key, "usage", tmp);
         g_free(tmp);
     } else {
+        if (GVIR_SANDBOX_IS_CONFIG_MOUNT_HOST_IMAGE(config)) {
+            GVirSandboxConfigMountHostImage *mimage = GVIR_SANDBOX_CONFIG_MOUNT_HOST_IMAGE(config);
+            GVirConfigDomainDiskFormat format = gvir_sandbox_config_mount_host_image_get_format(mimage);
+            GEnumClass *klass = g_type_class_ref(GVIR_CONFIG_TYPE_DOMAIN_DISK_FORMAT);
+            GEnumValue *value = g_enum_get_value(klass, format);
+            g_type_class_unref(klass);
+            g_key_file_set_string(file, key, "format", value->value_nick);
+        }
         g_key_file_set_string(file, key, "source",
                               gvir_sandbox_config_mount_file_get_source(
                                                                         GVIR_SANDBOX_CONFIG_MOUNT_FILE(config)));
diff --git a/libvirt-sandbox/libvirt-sandbox.sym b/libvirt-sandbox/libvirt-sandbox.sym
index 7afef53..532fb63 100644
--- a/libvirt-sandbox/libvirt-sandbox.sym
+++ b/libvirt-sandbox/libvirt-sandbox.sym
@@ -209,3 +209,8 @@ LIBVIRT_SANDBOX_0.2.1 {
     local:
         *;
 };
+
+LIBVIRT_SANDBOX_0.5.1 {
+   global:
+	gvir_sandbox_config_mount_guest_bind_get_format;
+} LIBVIRT_SANDBOX_0.2.1;
diff --git a/libvirt-sandbox/tests/test-config.c b/libvirt-sandbox/tests/test-config.c
index 1afec83..dcbe5c1 100644
--- a/libvirt-sandbox/tests/test-config.c
+++ b/libvirt-sandbox/tests/test-config.c
@@ -54,6 +54,7 @@ int main(int argc, char **argv)
     const gchar *mounts[] = {
         "host-bind:/var/run/hell=/tmp/home",
         "host-image:/etc=/tmp/home",
+        "host-image:/etc=/tmp/home,format=qcow2",
         "host-bind:/tmp=",
         NULL
     };
-- 
2.1.4




More information about the libvir-list mailing list