Add the config gobject, functions to store and load the new configuration fragments and test. This will allow creating sandboxes with attached disk with a parameter formatted like file:hda=/source/file.qcow2,format=qcow2 --- libvirt-sandbox/Makefile.am | 2 + libvirt-sandbox/libvirt-sandbox-config-disk.c | 274 ++++++++++++++++++++++++ libvirt-sandbox/libvirt-sandbox-config-disk.h | 82 +++++++ libvirt-sandbox/libvirt-sandbox-config.c | 293 ++++++++++++++++++++++++++ libvirt-sandbox/libvirt-sandbox-config.h | 10 + libvirt-sandbox/libvirt-sandbox.h | 1 + libvirt-sandbox/libvirt-sandbox.sym | 4 + libvirt-sandbox/tests/test-config.c | 11 + 8 files changed, 677 insertions(+) create mode 100644 libvirt-sandbox/libvirt-sandbox-config-disk.c create mode 100644 libvirt-sandbox/libvirt-sandbox-config-disk.h diff --git a/libvirt-sandbox/Makefile.am b/libvirt-sandbox/Makefile.am index 6917f04..8237c50 100644 --- a/libvirt-sandbox/Makefile.am +++ b/libvirt-sandbox/Makefile.am @@ -55,6 +55,7 @@ SANDBOX_HEADER_FILES = \ libvirt-sandbox-main.h \ libvirt-sandbox-util.h \ libvirt-sandbox-config.h \ + libvirt-sandbox-config-disk.h \ libvirt-sandbox-config-network.h \ libvirt-sandbox-config-network-address.h \ libvirt-sandbox-config-network-filterref-parameter.h \ @@ -86,6 +87,7 @@ SANDBOX_SOURCE_FILES = \ libvirt-sandbox-main.c \ libvirt-sandbox-util.c \ libvirt-sandbox-config.c \ + libvirt-sandbox-config-disk.c \ libvirt-sandbox-config-network.c \ libvirt-sandbox-config-network-address.c \ libvirt-sandbox-config-network-filterref.c \ diff --git a/libvirt-sandbox/libvirt-sandbox-config-disk.c b/libvirt-sandbox/libvirt-sandbox-config-disk.c new file mode 100644 index 0000000..04f1cf0 --- /dev/null +++ b/libvirt-sandbox/libvirt-sandbox-config-disk.c @@ -0,0 +1,274 @@ +/* + * libvirt-sandbox-config-disk.c: libvirt sandbox configuration + * + * Copyright (C) 2015 Universitat Politècnica de Catalunya. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Eren Yagdiran <erenyagdiran@xxxxxxxxx> + */ + +#include <config.h> +#include <string.h> + +#include "libvirt-sandbox/libvirt-sandbox.h" + +/** + * SECTION: libvirt-sandbox-config-disk + * @short_description: Disk attachment configuration details + * @include: libvirt-sandbox/libvirt-sandbox.h + * @see_aloso: #GVirSandboxConfig + * + * Provides an object to store information about a disk attachment in the sandbox + * + */ + +#define GVIR_SANDBOX_CONFIG_DISK_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_SANDBOX_TYPE_CONFIG_DISK, GVirSandboxConfigDiskPrivate)) + + +struct _GVirSandboxConfigDiskPrivate +{ + GVirConfigDomainDiskType type; + gchar *target; + gchar *source; + GVirConfigDomainDiskFormat format; +}; + +G_DEFINE_TYPE(GVirSandboxConfigDisk, gvir_sandbox_config_disk, G_TYPE_OBJECT); + + +enum { + PROP_0, + PROP_TYPE, + PROP_TARGET, + PROP_SOURCE, + PROP_FORMAT +}; + +enum { + LAST_SIGNAL +}; + + + +static void gvir_sandbox_config_disk_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GVirSandboxConfigDisk *config = GVIR_SANDBOX_CONFIG_DISK(object); + GVirSandboxConfigDiskPrivate *priv = config->priv; + + switch (prop_id) { + case PROP_TARGET: + g_value_set_string(value, priv->target); + break; + case PROP_SOURCE: + g_value_set_string(value, priv->source); + break; + case PROP_TYPE: + g_value_set_enum(value, priv->type); + break; + 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_disk_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GVirSandboxConfigDisk *config = GVIR_SANDBOX_CONFIG_DISK(object); + GVirSandboxConfigDiskPrivate *priv = config->priv; + + switch (prop_id) { + case PROP_TARGET: + g_free(priv->target); + priv->target = g_value_dup_string(value); + break; + case PROP_SOURCE: + g_free(priv->source); + priv->source = g_value_dup_string(value); + break; + case PROP_TYPE: + priv->type = g_value_get_enum(value); + break; + 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_disk_finalize(GObject *object) +{ + GVirSandboxConfigDisk *config = GVIR_SANDBOX_CONFIG_DISK(object); + GVirSandboxConfigDiskPrivate *priv = config->priv; + + g_free(priv->target); + g_free(priv->source); + + G_OBJECT_CLASS(gvir_sandbox_config_disk_parent_class)->finalize(object); +} + + +static void gvir_sandbox_config_disk_class_init(GVirSandboxConfigDiskClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->finalize = gvir_sandbox_config_disk_finalize; + object_class->get_property = gvir_sandbox_config_disk_get_property; + object_class->set_property = gvir_sandbox_config_disk_set_property; + + g_object_class_install_property(object_class, + PROP_TARGET, + g_param_spec_string("target", + "Target", + "The sandbox target directory", + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_object_class_install_property(object_class, + PROP_SOURCE, + g_param_spec_string("source", + "Source", + "The sandbox source directory", + NULL, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + + g_object_class_install_property(object_class, + PROP_TYPE, + g_param_spec_enum("type", + "Disk type", + "The sandbox disk type", + GVIR_CONFIG_TYPE_DOMAIN_DISK_TYPE, + GVIR_CONFIG_DOMAIN_DISK_FILE, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_object_class_install_property(object_class, + PROP_FORMAT, + g_param_spec_enum("format", + "Disk format", + "The sandbox 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(GVirSandboxConfigDiskPrivate)); +} + + +static void gvir_sandbox_config_disk_init(GVirSandboxConfigDisk *config) +{ + config->priv = GVIR_SANDBOX_CONFIG_DISK_GET_PRIVATE(config); +} + +/** + * gvir_sandbox_config_disk_get_disk_type: + * @config: (transfer none): the sandbox disk config + * + * Retrieves the type property for the custom disk + * + * Returns: (transfer none): the type property of disk + */ +GVirConfigDomainDiskType gvir_sandbox_config_disk_get_disk_type(GVirSandboxConfigDisk *config) +{ + GVirSandboxConfigDiskPrivate *priv = config->priv; + return priv->type; +} + + +/** + * gvir_sandbox_config_disk_get_format: + * @config: (transfer none): the sandbox disk config + * + * Retrieves the format property for the custom disk + * + * Returns: (transfer none): the format property of disk + */ +GVirConfigDomainDiskFormat gvir_sandbox_config_disk_get_format(GVirSandboxConfigDisk *config) +{ + GVirSandboxConfigDiskPrivate *priv = config->priv; + return priv->format; +} + + +/** + * gvir_sandbox_config_disk_get_target: + * @config: (transfer none): the sandbox disk config + * + * Retrieves the target property for the custom disk + * + * Returns: (transfer none): the target property path + */ +const gchar *gvir_sandbox_config_disk_get_target(GVirSandboxConfigDisk *config) +{ + GVirSandboxConfigDiskPrivate *priv = config->priv; + return priv->target; +} + + +/** + * gvir_sandbox_config_disk_get_source: + * @config: (transfer none): the sandbox disk config + * + * Retrieves the source property for the custom disk + * + * Returns: (transfer none): the source property + */ +const gchar *gvir_sandbox_config_disk_get_source(GVirSandboxConfigDisk *config) +{ + GVirSandboxConfigDiskPrivate *priv = config->priv; + return priv->source; +} + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * indent-tabs-mode: nil + * tab-width: 8 + * End: + */ + diff --git a/libvirt-sandbox/libvirt-sandbox-config-disk.h b/libvirt-sandbox/libvirt-sandbox-config-disk.h new file mode 100644 index 0000000..f3667b5 --- /dev/null +++ b/libvirt-sandbox/libvirt-sandbox-config-disk.h @@ -0,0 +1,82 @@ +/* + * libvirt-sandbox-config-diskaccess.h: libvirt sandbox configuration + * + * Copyright (C) 2015 Universitat Politècnica de Catalunya. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Eren Yagdiran <erenyagdiran@xxxxxxxxx> + */ + +#if !defined(__LIBVIRT_SANDBOX_H__) && !defined(LIBVIRT_SANDBOX_BUILD) +#error "Only <libvirt-sandbox/libvirt-sandbox.h> can be included directly." +#endif + +#ifndef __LIBVIRT_SANDBOX_CONFIG_DISK_H__ +#define __LIBVIRT_SANDBOX_CONFIG_DISK_H__ + +G_BEGIN_DECLS + +#define GVIR_SANDBOX_TYPE_CONFIG_DISK (gvir_sandbox_config_disk_get_type ()) +#define GVIR_SANDBOX_CONFIG_DISK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GVIR_SANDBOX_TYPE_CONFIG_DISK, GVirSandboxConfigDisk)) +#define GVIR_SANDBOX_CONFIG_DISK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GVIR_SANDBOX_TYPE_CONFIG_DISK, GVirSandboxConfigDiskClass)) +#define GVIR_SANDBOX_IS_CONFIG_DISK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GVIR_SANDBOX_TYPE_CONFIG_DISK)) +#define GVIR_SANDBOX_IS_CONFIG_DISK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GVIR_SANDBOX_TYPE_CONFIG_DISK)) +#define GVIR_SANDBOX_CONFIG_DISK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GVIR_SANDBOX_TYPE_CONFIG_DISK, GVirSandboxConfigDiskClass)) + +#define GVIR_SANDBOX_TYPE_CONFIG_DISK_HANDLE (gvir_sandbox_config_disk_handle_get_type ()) + +typedef struct _GVirSandboxConfigDisk GVirSandboxConfigDisk; +typedef struct _GVirSandboxConfigDiskPrivate GVirSandboxConfigDiskPrivate; +typedef struct _GVirSandboxConfigDiskClass GVirSandboxConfigDiskClass; + +struct _GVirSandboxConfigDisk +{ + GObject parent; + + GVirSandboxConfigDiskPrivate *priv; + + /* Do not add fields to this struct */ +}; + +struct _GVirSandboxConfigDiskClass +{ + GObjectClass parent_class; + + gpointer padding[LIBVIRT_SANDBOX_CLASS_PADDING]; +}; + +GType gvir_sandbox_config_disk_get_type(void); + +const gchar *gvir_sandbox_config_disk_get_target(GVirSandboxConfigDisk *config); + +const gchar *gvir_sandbox_config_disk_get_source(GVirSandboxConfigDisk *config); + +GVirConfigDomainDiskType gvir_sandbox_config_disk_get_disk_type(GVirSandboxConfigDisk *config); + +GVirConfigDomainDiskFormat gvir_sandbox_config_disk_get_format(GVirSandboxConfigDisk *config); + +G_END_DECLS + +#endif /* __LIBVIRT_SANDBOX_CONFIG_DISK_H__ */ + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * indent-tabs-mode: nil + * tab-width: 8 + * End: + */ diff --git a/libvirt-sandbox/libvirt-sandbox-config.c b/libvirt-sandbox/libvirt-sandbox-config.c index fbc65a6..3342706 100644 --- a/libvirt-sandbox/libvirt-sandbox-config.c +++ b/libvirt-sandbox/libvirt-sandbox-config.c @@ -27,6 +27,7 @@ #include <glib/gi18n.h> #include "libvirt-sandbox/libvirt-sandbox.h" +#include "libvirt-sandbox/libvirt-sandbox-util.h" #include <errno.h> #include <selinux/selinux.h> @@ -62,6 +63,7 @@ struct _GVirSandboxConfigPrivate GList *networks; GList *mounts; + GList *disks; gchar *secLabel; gboolean secDynamic; @@ -274,6 +276,9 @@ static void gvir_sandbox_config_finalize(GObject *object) g_list_foreach(priv->networks, (GFunc)g_object_unref, NULL); g_list_free(priv->networks); + g_list_foreach(priv->disks, (GFunc)g_object_unref, NULL); + g_list_free(priv->disks); + g_free(priv->name); g_free(priv->uuid); @@ -1141,6 +1146,166 @@ gboolean gvir_sandbox_config_has_networks(GVirSandboxConfig *config) /** + * gvir_sandbox_config_add_disk: + * @config: (transfer none): the sandbox config + * @dsk: (transfer none): the disk configuration + * + * Adds a new custom disk to the sandbox + * + */ +void gvir_sandbox_config_add_disk(GVirSandboxConfig *config, + GVirSandboxConfigDisk *dsk) +{ + GVirSandboxConfigPrivate *priv = config->priv; + + g_object_ref(dsk); + + priv->disks = g_list_append(priv->disks, dsk); +} + + +/** + * gvir_sandbox_config_get_disks: + * @config: (transfer none): the sandbox config + * + * Retrieves the list of custom disks in the sandbox + * + * Returns: (transfer full) (element-type GVirSandboxConfigMount): the list of disks + */ +GList *gvir_sandbox_config_get_disks(GVirSandboxConfig *config) +{ + GVirSandboxConfigPrivate *priv = config->priv; + g_list_foreach(priv->disks, (GFunc)g_object_ref, NULL); + return g_list_copy(priv->disks); +} + + +/** + * gvir_sandbox_config_add_disk_strv: + * @config: (transfer none): the sandbox config + * @disks: (transfer none)(array zero-terminated=1): the list of disks + * + * Parses @disks whose elements are in the format TYPE:TARGET=SOURCE,FORMAT=FORMAT + * creating #GVirSandboxConfigMount instances for each element. For + * example + * + * - file:hda=/var/lib/sandbox/demo/tmp.qcow2,format=qcow2 + */ +gboolean gvir_sandbox_config_add_disk_strv(GVirSandboxConfig *config, + gchar **disks, + GError **error) +{ + gsize i = 0; + while (disks && disks[i]) { + if (!gvir_sandbox_config_add_disk_opts(config, + disks[i], + error)) + return FALSE; + i++; + } + return TRUE; +} + + +/** + * gvir_sandbox_config_add_disk_opts: + * @config: (transfer none): the sandbox config + * @disk: (transfer none): the disk config + * + * Parses @disk in the format TYPE:TARGET=SOURCE,FORMAT=FORMAT + * creating #GVirSandboxConfigDisk instances for each element. For + * example + * + * - file:hda=/var/lib/sandbox/demo/tmp.qcow2,format=qcow2 + */ + +gboolean gvir_sandbox_config_add_disk_opts(GVirSandboxConfig *config, + const char *opt, + GError **error) +{ + gchar *typeStr = NULL; + gchar *formatStr = NULL; + gchar *target = NULL; + gchar *source = NULL; + GVirSandboxConfigDisk *diskConfig; + gchar *tmp; + gint type; + gint format = GVIR_CONFIG_DOMAIN_DISK_FORMAT_RAW; + GEnumClass *enum_class = g_type_class_ref(GVIR_CONFIG_TYPE_DOMAIN_DISK_TYPE); + GEnumValue *enum_value; + + if (!(typeStr = g_strdup(opt))) + return FALSE; + + tmp = strchr(typeStr, ':'); + + if (!tmp) { + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + _("No disk type prefix on %s"), opt); + return FALSE; + } + + *tmp = '\0'; + target = tmp + 1; + if (!(enum_value = g_enum_get_value_by_nick(enum_class, typeStr))) { + g_type_class_unref(enum_class); + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + _("Unknown disk type prefix on %s"), opt); + return FALSE; + } + g_type_class_unref(enum_class); + type = enum_value->value; + + if (type != GVIR_CONFIG_DOMAIN_DISK_FILE) { + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + _("Unimplemented disk type prefix on %s"), opt); + return FALSE; + } + + if (!(tmp = strchr(target, '='))) { + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + _("Missing disk source string on %s"), opt); + return FALSE; + } + + *tmp = '\0'; + source = tmp + 1; + + if ((tmp = strchr(source, ',')) != NULL) { + *tmp = '\0'; + formatStr = tmp + 1; + + if ((strncmp(formatStr, "format=", 7) != 0) || + (format = gvir_sandbox_util_disk_format_from_str(formatStr + 7, error)) < 0){ + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + _("Unknown disk image format: '%s'"), formatStr + 7); + return FALSE; + } + } + else { + if ((format = gvir_sandbox_util_guess_image_format(source, error)) < 0) { + format = GVIR_CONFIG_DOMAIN_DISK_FORMAT_RAW; + } + } + + + diskConfig = GVIR_SANDBOX_CONFIG_DISK(g_object_new(GVIR_SANDBOX_TYPE_CONFIG_DISK, + "type", type, + "target", target, + "source", source, + "format", format, + NULL)); + + gvir_sandbox_config_add_disk(config, diskConfig); + + g_object_unref(diskConfig); + g_free(typeStr); + + return TRUE; +} + + +/** * gvir_sandbox_config_add_mount: * @config: (transfer none): the sandbox config * @mnt: (transfer none): the mount configuration @@ -1757,6 +1922,85 @@ static GVirSandboxConfigMount *gvir_sandbox_config_load_config_mount(GKeyFile *f } +static GVirSandboxConfigDisk *gvir_sandbox_config_load_config_disk(GKeyFile *file, + guint i, + GError **error) +{ + GVirSandboxConfigDisk *config = NULL; + gchar *key = NULL; + gchar *target = NULL; + gchar *source = NULL; + gchar *typeStr = NULL; + gchar *formatStr = NULL; + gint type, format; + GError *e = NULL; + GEnumClass *enum_class = g_type_class_ref(GVIR_CONFIG_TYPE_DOMAIN_DISK_TYPE); + GEnumValue *enum_value; + + key = g_strdup_printf("disk.%u", i); + if ((target = g_key_file_get_string(file, key, "target", &e)) == NULL) { + if (e->code == G_KEY_FILE_ERROR_GROUP_NOT_FOUND) { + g_error_free(e); + return NULL; + } + g_error_free(e); + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + "%s", _("Missing disk target in config file")); + goto cleanup; + } + if ((source = g_key_file_get_string(file, key, "source", NULL)) == NULL) { + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + "%s", _("Missing disk source in config file")); + goto cleanup; + } + if ((typeStr = g_key_file_get_string(file, key, "type", NULL)) == NULL) { + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + "%s", _("Missing disk type in config file")); + goto cleanup; + } + + if (!(enum_value = g_enum_get_value_by_nick(enum_class, typeStr))) { + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + _("Unknown disk type %s in config file"), typeStr); + goto error; + } + type = enum_value->value; + + if ((formatStr = g_key_file_get_string(file, key, "format", NULL)) == NULL) { + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + "%s", _("Missing disk format in config file")); + goto cleanup; + } + + if ((format = gvir_sandbox_util_disk_format_from_str(formatStr, error)) < 0) { + g_set_error(error, GVIR_SANDBOX_CONFIG_ERROR, 0, + _("Unknown disk format %s in config file"), formatStr); + goto error; + } + + config = GVIR_SANDBOX_CONFIG_DISK(g_object_new(GVIR_SANDBOX_TYPE_CONFIG_DISK, + "type", type, + "target", target, + "source", source, + "format", format, + NULL)); + + cleanup: + g_type_class_unref(enum_class); + g_free(target); + g_free(source); + g_free(typeStr); + g_free(formatStr); + g_free(key); + return config; + + error: + g_object_unref(config); + config = NULL; + goto cleanup; +} + + static GVirSandboxConfigNetwork *gvir_sandbox_config_load_config_network(GKeyFile *file, guint i, GError **error) @@ -1973,6 +2217,16 @@ static gboolean gvir_sandbox_config_load_config(GVirSandboxConfig *config, } + for (i = 0 ; i < 1024 ; i++) { + GVirSandboxConfigDisk *disk; + if (!(disk = gvir_sandbox_config_load_config_disk(file, i, error)) && + *error) + goto cleanup; + if (disk) + priv->disks = g_list_append(priv->disks, disk); + } + + g_free(priv->secLabel); if ((str = g_key_file_get_string(file, "security", "label", NULL)) != NULL) priv->secLabel = str; @@ -1993,6 +2247,35 @@ static gboolean gvir_sandbox_config_load_config(GVirSandboxConfig *config, } +static void gvir_sandbox_config_save_config_disk(GVirSandboxConfigDisk *config, + GKeyFile *file, + guint i) +{ + gchar *key; + GVirConfigDomainDiskType type = gvir_sandbox_config_disk_get_disk_type(config); + GVirConfigDomainDiskFormat format = gvir_sandbox_config_disk_get_format(config); + GEnumClass *klass = NULL; + GEnumValue *value = NULL; + + key = g_strdup_printf("disk.%u", i); + + klass = g_type_class_ref(GVIR_CONFIG_TYPE_DOMAIN_DISK_TYPE); + value = g_enum_get_value(klass, type); + g_type_class_unref(klass); + g_key_file_set_string(file, key, "type", value->value_nick); + + g_key_file_set_string(file, key, "source", + gvir_sandbox_config_disk_get_source(config)); + g_key_file_set_string(file, key, "target", + gvir_sandbox_config_disk_get_target(config)); + + klass = g_type_class_ref(GVIR_CONFIG_TYPE_DOMAIN_DISK_FORMAT); + value = g_enum_get_value(klass, format); + g_type_class_unref(klass); + g_key_file_set_string(file, key, "format", value->value_nick); + g_free(key); +} + static void gvir_sandbox_config_save_config_mount(GVirSandboxConfigMount *config, GKeyFile *file, guint i) @@ -2174,6 +2457,16 @@ static void gvir_sandbox_config_save_config(GVirSandboxConfig *config, } i = 0; + tmp = priv->disks; + while (tmp) { + gvir_sandbox_config_save_config_disk(tmp->data, + file, + i); + tmp = tmp->next; + i++; + } + + i = 0; tmp = priv->networks; while (tmp) { gvir_sandbox_config_save_config_network(GVIR_SANDBOX_CONFIG_NETWORK(tmp->data), diff --git a/libvirt-sandbox/libvirt-sandbox-config.h b/libvirt-sandbox/libvirt-sandbox-config.h index 1a65e3d..deaea68 100644 --- a/libvirt-sandbox/libvirt-sandbox-config.h +++ b/libvirt-sandbox/libvirt-sandbox-config.h @@ -122,6 +122,16 @@ gboolean gvir_sandbox_config_add_network_strv(GVirSandboxConfig *config, GError **error); gboolean gvir_sandbox_config_has_networks(GVirSandboxConfig *config); +void gvir_sandbox_config_add_disk(GVirSandboxConfig *config, + GVirSandboxConfigDisk *dsk); +GList *gvir_sandbox_config_get_disks(GVirSandboxConfig *config); +gboolean gvir_sandbox_config_add_disk_strv(GVirSandboxConfig *config, + gchar **disks, + GError **error); +gboolean gvir_sandbox_config_add_disk_opts(GVirSandboxConfig *config, + const char *disk, + GError **error); + void gvir_sandbox_config_add_mount(GVirSandboxConfig *config, GVirSandboxConfigMount *mnt); GList *gvir_sandbox_config_get_mounts(GVirSandboxConfig *config); diff --git a/libvirt-sandbox/libvirt-sandbox.h b/libvirt-sandbox/libvirt-sandbox.h index adb21a1..20dc871 100644 --- a/libvirt-sandbox/libvirt-sandbox.h +++ b/libvirt-sandbox/libvirt-sandbox.h @@ -31,6 +31,7 @@ #include <libvirt-sandbox/libvirt-sandbox-main.h> #include <libvirt-sandbox/libvirt-sandbox-util.h> #include <libvirt-sandbox/libvirt-sandbox-enum-types.h> +#include <libvirt-sandbox/libvirt-sandbox-config-disk.h> #include <libvirt-sandbox/libvirt-sandbox-config-mount.h> #include <libvirt-sandbox/libvirt-sandbox-config-mount-file.h> #include <libvirt-sandbox/libvirt-sandbox-config-mount-host-bind.h> diff --git a/libvirt-sandbox/libvirt-sandbox.sym b/libvirt-sandbox/libvirt-sandbox.sym index a17dfed..bb717ed 100644 --- a/libvirt-sandbox/libvirt-sandbox.sym +++ b/libvirt-sandbox/libvirt-sandbox.sym @@ -213,4 +213,8 @@ LIBVIRT_SANDBOX_0.2.1 { LIBVIRT_SANDBOX_0.5.2 { global: gvir_sandbox_config_mount_guest_bind_get_format; + gvir_sandbox_config_add_disk; + gvir_sandbox_config_add_disk_strv; + gvir_sandbox_config_add_disk_opts; + gvir_sandbox_config_disk_get_type; } LIBVIRT_SANDBOX_0.2.1; diff --git a/libvirt-sandbox/tests/test-config.c b/libvirt-sandbox/tests/test-config.c index dcbe5c1..3ea2017 100644 --- a/libvirt-sandbox/tests/test-config.c +++ b/libvirt-sandbox/tests/test-config.c @@ -58,6 +58,14 @@ int main(int argc, char **argv) "host-bind:/tmp=", NULL }; + const gchar *disks[] = { + "file:hda=/tmp/img.blah,format=qcow2", + "file:hda=/tmp/img.qcow2", + "file:hda=/tmp/img.qcow2,format=raw", + "file:hda=/tmp/img.img", + "file:hda=/tmp/imq", + NULL + }; const gchar *includes[] = { "/etc/nswitch.conf", "/etc/resolve.conf", @@ -96,6 +104,9 @@ int main(int argc, char **argv) if (!gvir_sandbox_config_add_mount_strv(cfg1, (gchar**)mounts, &err)) goto cleanup; + if (!gvir_sandbox_config_add_disk_strv(cfg1, (gchar**)disks, &err)) + goto cleanup; + if (!gvir_sandbox_config_add_host_include_strv(cfg1, (gchar**)includes, &err)) goto cleanup; -- 2.1.0
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list