Re: [libvirt-glib] [PATCH v4 1/3] libvirt-gobject-domain: Add _fetch_snapshots

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jun 30, 2014 at 07:50:14PM +0200, Timm Bäder wrote:
> This function can be used to fetch the snapshots of a domain (according
> to the given GVirDomainSnapshotListFlags) and save them in a
> domain-internal GHashTable. A function to access them from outside will
> be added in a later patch.
> ---
>  libvirt-gobject/libvirt-gobject-domain.c | 83 ++++++++++++++++++++++++++++++++
>  libvirt-gobject/libvirt-gobject-domain.h | 37 ++++++++++++++
>  libvirt-gobject/libvirt-gobject.sym      |  2 +
>  3 files changed, 122 insertions(+)
> 
> diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
> index c6e30e5..180a206 100644
> --- a/libvirt-gobject/libvirt-gobject-domain.c
> +++ b/libvirt-gobject/libvirt-gobject-domain.c
> @@ -38,6 +38,8 @@ struct _GVirDomainPrivate
>  {
>      virDomainPtr handle;
>      gchar uuid[VIR_UUID_STRING_BUFLEN];
> +    GHashTable *snapshots;
> +    GMutex *lock;
>  };
>  
>  G_DEFINE_TYPE(GVirDomain, gvir_domain, G_TYPE_OBJECT);
> @@ -121,6 +123,11 @@ static void gvir_domain_finalize(GObject *object)
>  
>      g_debug("Finalize GVirDomain=%p", domain);
>  
> +    if (priv->snapshots) {
> +        g_hash_table_unref(priv->snapshots);
> +    }
> +    g_mutex_free(priv->lock);
> +
>      virDomainFree(priv->handle);
>  
>      G_OBJECT_CLASS(gvir_domain_parent_class)->finalize(object);
> @@ -237,6 +244,7 @@ static void gvir_domain_init(GVirDomain *domain)
>      g_debug("Init GVirDomain=%p", domain);
>  
>      domain->priv = GVIR_DOMAIN_GET_PRIVATE(domain);
> +    domain->priv->lock = g_mutex_new();
>  }
>  
>  typedef struct virDomain GVirDomainHandle;
> @@ -1514,3 +1522,78 @@ gvir_domain_create_snapshot(GVirDomain *dom,
>      g_free(custom_xml);
>      return dom_snapshot;
>  }
> +
> +
> +
> +/**
> + * gvir_domain_fetch_snapshots:
> + * @dom: The domain
> + * @list_flags: bitwise-OR of #GVirDomainSnapshotListFlags
> + * @cancellable: (allow-none)(transfer-none): cancellation object
> + * @error: (allow-none): Place-holder for error or NULL
> + *
> + * Returns: TRUE on success, FALSE otherwise.
> + */
> +gboolean gvir_domain_fetch_snapshots(GVirDomain *dom,
> +                                     guint list_flags,
> +                                     GCancellable *cancellable,
> +                                     GError **error)
> +{
> +    GVirDomainPrivate *priv;
> +    virDomainSnapshotPtr *snapshots = NULL;
> +    GVirDomainSnapshot *snap;
> +    GHashTable *snap_table;
> +    int n_snaps = 0;
> +    int i;
> +    gboolean ret = TRUE;
> +
> +    g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
> +    g_return_val_if_fail((error == NULL) || (*error == NULL), FALSE);
> +
> +    priv = dom->priv;
> +
> +    snap_table = g_hash_table_new_full(g_str_hash,
> +                                       g_str_equal,
> +                                       NULL,
> +                                       g_object_unref);
> +
> +
> +    n_snaps = virDomainListAllSnapshots(priv->handle, &snapshots, list_flags);
> +
> +    if (g_cancellable_set_error_if_cancelled(cancellable, error)) {
> +        ret = FALSE;
> +        goto cleanup;
> +    }
> +
> +    if (n_snaps < 0) {
> +        gvir_set_error(error, GVIR_DOMAIN_ERROR, 0,
> +                       "Unable to fetch snapshots of %s",
> +                       gvir_domain_get_name(dom));
> +        ret = FALSE;
> +        goto cleanup;
> +    }
> +
> +    for (i = 0; i < n_snaps; i ++) {
> +        if (g_cancellable_set_error_if_cancelled(cancellable, error)) {
> +            ret = FALSE;
> +            goto cleanup;
> +        }
> +        snap = GVIR_DOMAIN_SNAPSHOT(g_object_new(GVIR_TYPE_DOMAIN_SNAPSHOT,
> +                                                 "handle", snapshots[i],
> +                                                 NULL));
> +        g_hash_table_insert(snap_table,
> +                            (gpointer)gvir_domain_snapshot_get_name(snap),
> +                            snap);
> +    }
> +
> +
> +    g_mutex_lock(priv->lock);
> +    if (priv->snapshots != NULL)
> +        g_hash_table_unref(priv->snapshots);
> +    priv->snapshots = snap_table;
> +    g_mutex_unlock(priv->lock);
> +
> +cleanup:

This is leaking 'snap_table' in error cases. You can have a if
(snap_table != NULL) { g_hash_table_unref (snap_table); } here, and set
snap_table to NULL right before the cleanup: label.


> +    free(snapshots);
> +    return ret;
> +}
> diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h
> index 38d3458..8c1a8e5 100644
> --- a/libvirt-gobject/libvirt-gobject-domain.h
> +++ b/libvirt-gobject/libvirt-gobject-domain.h
> @@ -183,6 +183,39 @@ typedef enum {
>      GVIR_DOMAIN_REBOOT_GUEST_AGENT    = VIR_DOMAIN_REBOOT_GUEST_AGENT,
>  } GVirDomainRebootFlags;
>  
> +/**
> + * GVirDomainSnapshotListFlags:
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_ALL: List all snapshots
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS: List all descendants, not just
> + *                                         children, when listing a snapshot.
> + *                                         For historical reasons, groups do not use contiguous bits.
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_ROOTS: Filter by snapshots with no parents, when listing a domain
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_METADATA: Filter by snapshots which have metadata
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_LEAVES: Filter by snapshots with no children
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES: Filter by snapshots that have children
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA: Filter by snapshots with no metadata
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_INACTIVE: Filter by snapshots taken while guest was shut off
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_ACTIVE: Filter by snapshots taken while guest was active, and with memory state
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY: Filter by snapshots taken while guest was active, but without memory state
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_INTERNAL: Filter by snapshots stored internal to disk images
> + * @GVIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL: Filter by snapshots that use files external to disk images
> + */
> +typedef enum {
> +    GVIR_DOMAIN_SNAPSHOT_LIST_ALL         = 0,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS = VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_ROOTS       = VIR_DOMAIN_SNAPSHOT_LIST_ROOTS,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_METADATA    = VIR_DOMAIN_SNAPSHOT_LIST_METADATA,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_LEAVES      = VIR_DOMAIN_SNAPSHOT_LIST_LEAVES,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES   = VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA = VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_INACTIVE    = VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_ACTIVE      = VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY   = VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_INTERNAL    = VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL,
> +    GVIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL    = VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL
> +} GVirDomainSnapshotListFlags;
> +
> +
>  typedef struct _GVirDomainInfo GVirDomainInfo;
>  struct _GVirDomainInfo
>  {
> @@ -330,6 +363,10 @@ gvir_domain_create_snapshot(GVirDomain *dom,
>                              guint flags,
>                              GError **err);
>  
> +gboolean gvir_domain_fetch_snapshots(GVirDomain *dom,
> +                                     guint list_flags,
> +                                     GCancellable *cancellable,
> +                                     GError **error);
>  G_END_DECLS
>  
>  #endif /* __LIBVIRT_GOBJECT_DOMAIN_H__ */
> diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
> index b781cc6..781310f 100644
> --- a/libvirt-gobject/libvirt-gobject.sym
> +++ b/libvirt-gobject/libvirt-gobject.sym
> @@ -236,7 +236,9 @@ LIBVIRT_GOBJECT_0.1.5 {
>  
>  LIBVIRT_GOBJECT_0.1.9 {
>    global:
> +	gvir_domain_fetch_snapshots;
>  	gvir_domain_snapshot_delete;
> +	gvir_domain_snapshot_list_flags_get_type;
>  } LIBVIRT_GOBJECT_0.1.5;
>  
>  # .... define new API here using predicted next version number ....
> -- 
> 2.0.1
> 
> --
> libvir-list mailing list
> libvir-list@xxxxxxxxxx
> https://www.redhat.com/mailman/listinfo/libvir-list

Attachment: pgpzE6v3P2AhA.pgp
Description: PGP signature

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]