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