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 | 10 +++
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, 181 insertions(+), 8 deletions(-)
diff --git a/libvirt-sandbox/libvirt-sandbox-builder-container.c
b/libvirt-sandbox/libvirt-sandbox-builder-container.c
index c3a58b2..59bfee1 100644
--- a/libvirt-sandbox/libvirt-sandbox-builder-container.c
+++ b/libvirt-sandbox/libvirt-sandbox-builder-container.c
@@ -273,6 +273,9 @@ 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;
+ GVirConfigDomainFilesysDriverType type =
GVIR_CONFIG_DOMAIN_FILESYS_DRIVER_LOOP;
fs = gvir_config_domain_filesys_new();
gvir_config_domain_filesys_set_type(fs, GVIR_CONFIG_DOMAIN_FILESYS_FILE);
@@ -282,6 +285,13 @@ static gboolean
gvir_sandbox_builder_container_construct_devices(GVirSandboxBuil
gvir_config_domain_filesys_set_target(fs,
gvir_sandbox_config_mount_get_target(mconfig));
+ format = gvir_sandbox_config_mount_host_image_get_format(mimage);
+ if (format != GVIR_CONFIG_DOMAIN_DISK_FORMAT_RAW)
+ type = GVIR_CONFIG_DOMAIN_FILESYS_DRIVER_NBD;
+
+ gvir_config_domain_filesys_set_driver_type(fs, type);
+ gvir_config_domain_filesys_set_driver_format(fs, format);
+
gvir_config_domain_add_device(domain,
GVIR_CONFIG_DOMAIN_DEVICE(fs));
g_object_unref(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