I've sent version 2 of this PATCH. I've changed this one since I saw your comments on gvir_save_to_file_domain.<br><br><br><div class="gmail_quote">On Wed, Jul 11, 2012 at 6:18 PM, Zeeshan Ali (Khattak) <span dir="ltr"><<a href="mailto:zeeshanak@gnome.org" target="_blank">zeeshanak@gnome.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
   Forgot review this one. Mostly its the same things I noticed here<br>
as the last one.<br>
<div class="im"><br>
On Wed, Jul 11, 2012 at 8:28 AM, Jovanka Gulicoska<br>
<<a href="mailto:jovanka.gulicoska@gmail.com">jovanka.gulicoska@gmail.com</a>> wrote:<br>
> ---<br>
>  libvirt-gobject/libvirt-gobject-connection.c |  136 ++++++++++++++++++++++++++<br>
>  libvirt-gobject/libvirt-gobject-connection.h |   19 ++++<br>
>  libvirt-gobject/libvirt-gobject.sym          |    3 +<br>
>  3 files changed, 158 insertions(+)<br>
><br>
> diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c<br>
> index 3a99034..2302328 100644<br>
> --- a/libvirt-gobject/libvirt-gobject-connection.c<br>
> +++ b/libvirt-gobject/libvirt-gobject-connection.c<br>
> @@ -57,6 +57,7 @@ enum {<br>
>      VIR_CONNECTION_CLOSED,<br>
>      VIR_DOMAIN_ADDED,<br>
>      VIR_DOMAIN_REMOVED,<br>
> +    VIR_DOMAIN_RESTORED,<br>
<br>
</div>Same as in previous patch: no additional signal needed.<br>
<div class="im"><br>
>      LAST_SIGNAL<br>
>  };<br>
><br>
> @@ -228,6 +229,15 @@ static void gvir_connection_class_init(GVirConnectionClass *klass)<br>
>                   1,<br>
>                   GVIR_TYPE_DOMAIN);<br>
><br>
> +    signals[VIR_DOMAIN_RESTORED] = g_signal_new("domain-restored",<br>
> +                                                G_OBJECT_CLASS_TYPE(object_class),<br>
> +                                                G_SIGNAL_RUN_FIRST,<br>
> +                                                G_STRUCT_OFFSET(GVirConnectionClass, domain_restored),<br>
> +                                                NULL, NULL,<br>
> +                                                g_cclosure_marshal_VOID__OBJECT,<br>
> +                                                G_TYPE_NONE,<br>
> +                                                0);<br>
> +<br>
>      g_type_class_add_private(klass, sizeof(GVirConnectionPrivate));<br>
>  }<br>
><br>
> @@ -1605,3 +1615,129 @@ gvir_connection_get_capabilities_finish(GVirConnection *conn,<br>
><br>
>      return g_object_ref(caps);<br>
>  }<br>
> +<br>
> +/*<br>
> + * gvir_connection_domain_restore<br>
> + */<br>
> +gboolean gvir_connection_domain_restore(GVirConnection *conn,<br>
> +                                        gchar *filename,<br>
> +                                        GVirConfigDomain *conf,<br>
<br>
</div>Now that I think of it, I think 'custom_conf' would be a better name<br>
for this parameter. Same for the previous patch.<br>
<div class="im"><br>
> +                                        guint flags,<br>
> +                                        GError **err)<br>
> +{<br>
> +    GVirConnectionPrivate *priv;<br>
> +    gchar *custom_xml;<br>
> +    int ret;<br>
> +<br>
> +    g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);<br>
> +    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN (conf), FALSE);<br>
> +    g_return_val_if_fail((err == NULL) || (*err == NULL), FALSE);<br>
> +<br>
> +    priv = conn->priv;<br>
> +    custom_xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf));<br>
> +<br>
> +    g_return_val_if_fail(custom_xml != NULL, FALSE);<br>
> +<br>
> +    if(flags || custom_xml) {<br>
<br>
</div>Same here:<br>
<br>
 if(flags || custom_xml != NULL)<br>
<br>
Oh and now I realize that you are checking for the string extracted<br>
from the parameter for being NULL. You want to check 'conf' itself to<br>
be NULL here and then extract the XML string before using it. You'll<br>
wan to remove one of the g_return_val_if_fail above to allow user to<br>
pass NULL as conf.<br>
<br>
Same goes for the previous patch too.<br>
<div class="im"><br>
> +       ret = virDomainRestoreFlags(priv->conn, filename, custom_xml, flags);<br>
> +       g_free (custom_xml);<br>
> +    }<br>
> +    else {<br>
> +       ret = virDomainRestore(priv->conn, filename);<br>
> +       g_free (custom_xml);<br>
> +    }<br>
> +<br>
> +    if(ret < 0) {<br>
> +       gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,<br>
> +                              0,<br>
> +                              "Unable to restore domain");<br>
> +<br>
> +       return FALSE;<br>
> +    }<br>
> +<br>
> +    return TRUE;<br>
> +}<br>
> +<br>
> +typedef struct {<br>
> +    gchar *filename;<br>
> +    gchar *custom_xml;<br>
> +    guint flags;<br>
> +} DomainRestoreFromFileData;<br>
<br>
</div>Since we are using essentially the same data as for<br>
gvir_connection_domain_save, I think we can simply re-use that:<br>
<br>
#define DomainRestoreFromFileData DomainSaveFromFileData<br>
<div class="im"><br>
> +static void domain_restore_from_file_data_free(DomainRestoreFromFileData *data)<br>
> +{<br>
<br>
</div>Same goes for this function.<br>
<div><div class="h5"><br>
> +    g_slice_free(DomainRestoreFromFileData, data);<br>
> +}<br>
> +<br>
> +static void<br>
> +gvir_connection_domain_restore_helper(GSimpleAsyncResult *res,<br>
> +                                      GObject *object,<br>
> +                                      GCancellable *cancellable G_GNUC_UNUSED)<br>
> +{<br>
> +    GVirConnection *conn = GVIR_CONNECTION(object);<br>
> +    DomainRestoreFromFileData *data;<br>
> +    GVirConfigDomain *conf;<br>
> +    GError *err = NULL;<br>
> +<br>
> +    data = g_simple_async_result_get_op_res_gpointer(res);<br>
> +    conf =  gvir_config_domain_new_from_xml(data->custom_xml, &err);<br>
> +<br>
> +    if(!gvir_connection_domain_restore(conn, data->filename, conf, data->flags, &err))<br>
> +       g_simple_async_result_take_error(res, err);<br>
> +}<br>
> +<br>
> +/*<br>
> + * Async function of gvir_connection_domain_restore<br>
> + */<br>
> +void gvir_connection_domain_restore_async(GVirConnection *conn,<br>
> +                                          gchar *filename,<br>
> +                                          GVirConfigDomain *conf,<br>
> +                                          guint flags,<br>
> +                                          GCancellable *cancellable,<br>
> +                                          GAsyncReadyCallback callback,<br>
> +                                          gpointer user_data)<br>
<br>
</div></div>Possible coding-style issue here as well.<br>
<div><div class="h5"><br>
> +{<br>
> +    GSimpleAsyncResult *res;<br>
> +    DomainRestoreFromFileData *data;<br>
> +    gchar *custom_xml;<br>
> +<br>
> +    g_return_if_fail(GVIR_IS_CONNECTION(conn));<br>
> +    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN (conf));<br>
> +    g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));<br>
> +<br>
> +    custom_xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf));<br>
> +<br>
> +    data = g_slice_new0(DomainRestoreFromFileData);<br>
> +    data->filename = filename;<br>
> +    data->custom_xml = custom_xml;<br>
> +    data->flags = flags;<br>
> +<br>
> +    res = g_simple_async_result_new(G_OBJECT(conn),<br>
> +                                    callback,<br>
> +                                    user_data,<br>
> +                                    gvir_connection_domain_restore_async);<br>
> +    g_simple_async_result_set_op_res_gpointer(res, data,<br>
> +                                              (GDestroyNotify)domain_restore_from_file_data_free);<br>
> +<br>
> +    g_simple_async_result_run_in_thread(res,<br>
> +                                        gvir_connection_domain_restore_helper,<br>
> +                                        G_PRIORITY_DEFAULT,<br>
> +                                        cancellable);<br>
> +<br>
> +    g_object_unref(res);<br>
> +}<br>
> +<br>
> +gboolean gvir_connection_domain_restore_finish(GVirConnection *conn,<br>
> +                                               GAsyncResult *result,<br>
> +                                               GError **err)<br>
> +{<br>
> +    g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);<br>
> +    g_return_val_if_fail(g_simple_async_result_is_valid(result, G_OBJECT(conn),<br>
> +                                                        gvir_connection_domain_restore_async),<br>
> +                                                        FALSE);<br>
> +<br>
> +     if (g_simple_async_result_propagate_error(G_SIMPLE_ASYNC_RESULT(result), err))<br>
> +        return FALSE;<br>
> +<br>
> +    return TRUE;<br>
> +}<br>
> diff --git a/libvirt-gobject/libvirt-gobject-connection.h b/libvirt-gobject/libvirt-gobject-connection.h<br>
> index c80eecf..01d5d0b 100644<br>
> --- a/libvirt-gobject/libvirt-gobject-connection.h<br>
> +++ b/libvirt-gobject/libvirt-gobject-connection.h<br>
> @@ -75,6 +75,8 @@ struct _GVirConnectionClass<br>
>      void (*domain_added)(GVirConnection *conn, GVirDomain *dom);<br>
>      void (*domain_removed)(GVirConnection *conn, GVirDomain *dom);<br>
><br>
> +    void (*domain_restored)(GVirConnection *conn);<br>
> +<br>
>      GVirStream *(*stream_new)(GVirConnection *conn, gpointer handle);<br>
><br>
>      gpointer padding[20];<br>
> @@ -202,6 +204,23 @@ gvir_connection_get_capabilities_finish(GVirConnection *conn,<br>
>                                          GAsyncResult *result,<br>
>                                          GError **err);<br>
><br>
> +gboolean gvir_connection_domain_restore(GVirConnection *conn,<br>
> +                                        gchar *filename,<br>
> +                                        GVirConfigDomain *conf,<br>
> +                                        guint flags,<br>
> +                                        GError **err);<br>
> +<br>
> +void gvir_connection_domain_restore_async(GVirConnection *conn,<br>
> +                                          gchar *filename,<br>
> +                                          GVirConfigDomain *conf,<br>
> +                                          guint flags,<br>
> +                                          GCancellable *cancellable,<br>
> +                                          GAsyncReadyCallback callback,<br>
> +                                          gpointer user_data);<br>
> +<br>
> +gboolean gvir_connection_domain_restore_finish(GVirConnection *conn,<br>
> +                                               GAsyncResult *result,<br>
> +                                               GError **err);<br>
>  G_END_DECLS<br>
><br>
>  #endif /* __LIBVIRT_GOBJECT_CONNECTION_H__ */<br>
> diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym<br>
> index 8ff9e24..0aaefa2 100644<br>
> --- a/libvirt-gobject/libvirt-gobject.sym<br>
> +++ b/libvirt-gobject/libvirt-gobject.sym<br>
> @@ -31,6 +31,9 @@ LIBVIRT_GOBJECT_0.0.8 {<br>
>         gvir_connection_create_storage_pool;<br>
>         gvir_connection_start_domain;<br>
>         gvir_connection_get_node_info;<br>
> +        gvir_connection_domain_restore;<br>
> +        gvir_connection_domain_restore_async;<br>
> +        gvir_connection_domain_restore_finish;<br>
<br>
</div></div>Same warning about tabs.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Regards,<br>
<br>
Zeeshan Ali (Khattak)<br>
FSF member#5124<br>
</font></span></blockquote></div><br>