[libvirt] [libvirt-designer][PATCH v2 2/4] domain: Introduce disk support
Christophe Fergeau
cfergeau at redhat.com
Wed Sep 12 09:55:26 UTC 2012
On Mon, Sep 10, 2012 at 03:58:26PM +0200, Michal Privoznik wrote:
> +static GList *
> +gvir_designer_domain_get_supported_disk_bus_types(GVirDesignerDomain *design)
> +{
> + GVirDesignerDomainPrivate *priv = design->priv;
> + OsinfoDeviceList *dev_list;
> + GHashTable *bus_hash = g_hash_table_new(g_str_hash, g_str_equal);
> + GList *ret = NULL;
> + int i;
> +
> + dev_list = osinfo_os_get_devices_by_property(priv->os, "class", "block", TRUE);
> + if (!dev_list)
> + goto cleanup;
> +
> + for (i = 0; i < osinfo_list_get_length(OSINFO_LIST(dev_list)); i++) {
> + OsinfoDevice *dev = OSINFO_DEVICE(osinfo_list_get_nth(OSINFO_LIST(dev_list), i));
> + const gchar *bus = osinfo_device_get_bus_type(dev);
> +
> + if (bus)
> + g_hash_table_add(bus_hash, g_strdup(bus));
> + }
> +
> + ret = g_hash_table_get_keys(bus_hash);
> + if (ret)
> + ret = g_list_copy(ret);
NULL is a valid list (empty list), so g_list_copy(NULL); is fine.
> +
> +cleanup:
> + g_hash_table_destroy(bus_hash);
> + return ret;
> +}
> +
> +static OsinfoDeviceLink *
> +gvir_designer_domain_get_preferred_device(GVirDesignerDomain *design,
> + const char *class,
> + GError **error)
> +{
> + GVirDesignerDomainPrivate *priv = design->priv;
> + OsinfoFilter *filter = osinfo_filter_new();
> + OsinfoDeviceLinkFilter *filter_link = NULL;
> + OsinfoDeployment *deployment = priv->deployment;
> + OsinfoDeviceLink *dev_link = NULL;
> +
> + if (!deployment) {
> + priv->deployment = deployment = osinfo_db_find_deployment(osinfo_db,
> + priv->os,
> + priv->platform);
> + if (!deployment) {
> + g_set_error(error, GVIR_DESIGNER_DOMAIN_ERROR, 0,
> + "Unable to find any deployment in libosinfo database");
g_set_error_literal would be slightly better here.
> + goto cleanup;
> + }
> + }
> +
> + osinfo_filter_add_constraint(filter, "class", class);
> + filter_link = osinfo_devicelinkfilter_new(filter);
> + dev_link = osinfo_deployment_get_preferred_device_link(deployment, OSINFO_FILTER(filter_link));
> +
> +cleanup:
> + if (filter_link)
> + g_object_unref(filter_link);
> + if (filter)
> + g_object_unref(filter);
> + return dev_link;
> +}
> +
> +static const gchar *
> +gvir_designer_domain_get_preferred_disk_bus_type(GVirDesignerDomain *design,
> + GError **error)
> +{
> + OsinfoDevice *dev;
> + OsinfoDeviceLink *dev_link = gvir_designer_domain_get_preferred_device(design,
> + "block",
> + error);
> + const gchar *ret = NULL;
> +
> + if (!dev_link)
> + return NULL;
> +
> + dev = osinfo_devicelink_get_target(dev_link);
> + if (dev)
> + ret = osinfo_device_get_bus_type(dev);
> +
> + return ret;
> +}
> +
> +static gchar *
> +gvir_designer_domain_next_disk_target(GVirDesignerDomain *design,
> + GVirConfigDomainDiskBus bus)
> +{
> + gchar *ret = NULL;
> + GVirDesignerDomainPrivate *priv = design->priv;
> +
> + switch (bus) {
> + case GVIR_CONFIG_DOMAIN_DISK_BUS_IDE:
> + ret = g_strdup_printf("hd%c", 'a' + priv->ide++);
> + break;
> + case GVIR_CONFIG_DOMAIN_DISK_BUS_VIRTIO:
> + ret = g_strdup_printf("vd%c", 'a' + priv->virtio++);
> + break;
> + case GVIR_CONFIG_DOMAIN_DISK_BUS_SATA:
> + ret = g_strdup_printf("sd%c", 'a' + priv->sata++);
> + break;
> + case GVIR_CONFIG_DOMAIN_DISK_BUS_FDC:
> + case GVIR_CONFIG_DOMAIN_DISK_BUS_SCSI:
> + case GVIR_CONFIG_DOMAIN_DISK_BUS_XEN:
> + case GVIR_CONFIG_DOMAIN_DISK_BUS_USB:
> + case GVIR_CONFIG_DOMAIN_DISK_BUS_UML:
> + default:
> + /* not supported yet */
> + /* XXX should we fallback to ide/virtio? */
> + break;
> + }
> +
> + return ret;
> +}
> +
> +static GVirConfigDomainDisk *
> +gvir_designer_domain_add_disk_full(GVirDesignerDomain *design,
> + GVirConfigDomainDiskType type,
> + const char *path,
> + const char *format,
> + gchar *target,
> + GError **error)
> +{
> + GVirDesignerDomainPrivate *priv = design->priv;
> + GVirConfigDomainDisk *disk = NULL;
> + GVirConfigDomainDiskBus bus;
> + gchar *target_gen = NULL;
> + const gchar *bus_str = NULL;
> + GList *bus_str_list = NULL, *item = NULL;
> +
> + /* Guess preferred disk bus */
> + bus_str = gvir_designer_domain_get_preferred_disk_bus_type(design, error);
> + if (!bus_str) {
> + /* And fallback if fails */
> + bus_str_list = gvir_designer_domain_get_supported_disk_bus_types(design);
> + if (!bus_str_list) {
> + if (!*error)
I haven't looked at the callers, but in public APIs, passing a NULL
GError** is acceptable, so this test would be better as 'if (error != NULL
&& *error != NULL)' (I always wonder why glib does not provide
g_error_is_set).
> + g_set_error(error, GVIR_DESIGNER_DOMAIN_ERROR, 0,
> + "Unable to find any disk bus type");
> + goto error;
> + }
> +
> + item = g_list_first(bus_str_list);
> + bus_str = item->data;
> + if (!bus_str)
> + goto error;
Looks like 'error' will be leaked in we go to error.
Christophe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20120912/d9554ca8/attachment-0001.sig>
More information about the libvir-list
mailing list