Commit 68406aff authored by Cédric Bosdonnat's avatar Cédric Bosdonnat

Add host-image format parameter

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.

Note: sonum has been incremented due to ABI break.
parent 45edc544
......@@ -47,7 +47,7 @@ LIBVIRT_SANDBOX_VERSION=$LIBVIRT_SANDBOX_MAJOR_VERSION.$LIBVIRT_SANDBOX_MINOR_VE
# in the so version'd symlinks, and this is based on AGE.REVISION
#
# Until we declare ABI stability, this can be toggled upon release
LIBVIRT_SANDBOX_SONUM=4
LIBVIRT_SANDBOX_SONUM=5
AGE=`expr $LIBVIRT_SANDBOX_MAJOR_VERSION '*' 1000 + $LIBVIRT_SANDBOX_MINOR_VERSION`
REVISION=$LIBVIRT_SANDBOX_MICRO_VERSION
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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
......
......@@ -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)));
......
......@@ -209,3 +209,8 @@ LIBVIRT_SANDBOX_0.2.1 {
local:
*;
};
LIBVIRT_SANDBOX_0.5.2 {
global:
gvir_sandbox_config_mount_guest_bind_get_format;
} LIBVIRT_SANDBOX_0.2.1;
......@@ -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
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment