On Thu, May 19, 2011 at 04:51:29PM -0400, Laine Stump wrote:
> From: Michal Privoznik <mpriv...@redhat.com>
> 
> ---
>  src/conf/interface_conf.c |   45 ++++++++++++++++++++++++
>  src/conf/interface_conf.h |    4 ++
>  src/test/test_driver.c    |   83 
> +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 132 insertions(+), 0 deletions(-)
> 
> diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c
> index f3848bd..4ff68aa 100644
> --- a/src/conf/interface_conf.c
> +++ b/src/conf/interface_conf.c
> @@ -1227,6 +1227,51 @@ void virInterfaceObjListFree(virInterfaceObjListPtr 
> interfaces)
>      interfaces->count = 0;
>  }
>  
> +int virInterfaceObjListClone(virConnectPtr conn,
> +                             virInterfaceObjListPtr src,
> +                             virInterfaceObjListPtr dest)
> +{
> +    int ret = -1;
> +    unsigned int i, cnt;
> +
> +    if (!src || !dest)
> +        goto end;
> +
> +    cnt = src->count;
> +    for (i = 0; i < cnt; i++) {
> +        virInterfaceDefPtr def = src->objs[i]->def;
> +        virInterfaceDefPtr backup;
> +        virInterfaceObjPtr iface;
> +        char *xml = virInterfaceDefFormat(def);
> +
> +        if (!xml) {
> +            virReportOOMError();
> +            goto no_memory;
> +        }
> +
> +        if ((backup = virInterfaceDefParseString(xml)) == NULL) {
> +            VIR_FREE(xml);
> +            goto no_memory;
> +        }
> +
> +        VIR_FREE(xml);
> +        if ((iface = virInterfaceAssignDef(dest, backup)) == NULL)
> +            goto no_memory;
> +
> +        virInterfaceObjUnlock(iface);
> +
> +        conn->refs++;
> +    }
> +
> +    ret = cnt;
> +end:
> +    return ret;
> +
> +no_memory:
> +    virInterfaceObjListFree(dest);

  I'ts always a problem when the callee frees up memory allocated by
  the caller in case of error, as it's so easy to mess things up. I
  would rather not do that here, and have the caller do the free if we
  fail.
  example: src == NULL, dest != NULL, and we leak dest.

> +    goto end;
> +}
> +
>  virInterfaceObjPtr virInterfaceAssignDef(virInterfaceObjListPtr interfaces,
>                                           const virInterfaceDefPtr def)
>  {
> diff --git a/src/conf/interface_conf.h b/src/conf/interface_conf.h
> index 6073b49..870a8ee 100644
> --- a/src/conf/interface_conf.h
> +++ b/src/conf/interface_conf.h
> @@ -192,6 +192,10 @@ virInterfaceObjPtr virInterfaceFindByName(const 
> virInterfaceObjListPtr
>  void virInterfaceDefFree(virInterfaceDefPtr def);
>  void virInterfaceObjFree(virInterfaceObjPtr iface);
>  void virInterfaceObjListFree(virInterfaceObjListPtr vms);
> +int virInterfaceObjListClone(virConnectPtr conn,
> +                             virInterfaceObjListPtr src,
> +                             virInterfaceObjListPtr dest);
> +
>  
>  virInterfaceObjPtr virInterfaceAssignDef(virInterfaceObjListPtr interfaces,
>                                           const virInterfaceDefPtr def);
> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> index e86bc4e..b58c5d2 100644
> --- a/src/test/test_driver.c
> +++ b/src/test/test_driver.c
> @@ -85,6 +85,8 @@ struct _testConn {
>      virDomainObjList domains;
>      virNetworkObjList networks;
>      virInterfaceObjList ifaces;
> +    bool transaction_running;
> +    virInterfaceObjList backupIfaces;
>      virStoragePoolObjList pools;
>      virNodeDeviceObjList devs;
>      int numCells;
> @@ -3455,6 +3457,84 @@ cleanup:
>      return ret;
>  }
>  
> +static int testInterfaceChangeBegin(virConnectPtr conn,
> +                                    unsigned int flags ATTRIBUTE_UNUSED)
> +{
> +    testConnPtr privconn = conn->privateData;
> +    int ret = -1;
> +
> +    testDriverLock(privconn);
> +    if (privconn->transaction_running) {
> +        testError(VIR_ERR_OPERATION_INVALID, _("there is another transaction 
> "
> +                                               "running."));
> +        goto cleanup;
> +    }
> +
> +    privconn->transaction_running = true;
> +
> +    if (virInterfaceObjListClone(conn, &privconn->ifaces,
> +                                 &privconn->backupIfaces) < 0)
> +        goto cleanup;
> +
> +    ret = 0;
> +cleanup:
> +    testDriverUnlock(privconn);
> +    return ret;
> +}
> +
> +static int testInterfaceChangeCommit(virConnectPtr conn,
> +                                     unsigned int flags ATTRIBUTE_UNUSED)
> +{
> +    testConnPtr privconn = conn->privateData;
> +    int ret = -1;
> +
> +    testDriverLock(privconn);
> +
> +    if (!privconn->transaction_running) {
> +        testError(VIR_ERR_OPERATION_INVALID, _("no transaction running, "
> +                  "nothing to be commited."));
> +        goto cleanup;
> +    }
> +
> +    virInterfaceObjListFree(&privconn->backupIfaces);
> +    privconn->transaction_running = false;
> +
> +    ret = 0;
> +
> +cleanup:
> +    testDriverUnlock(privconn);
> +
> +    return ret;
> +}
> +
> +static int testInterfaceChangeRollback(virConnectPtr conn,
> +                                       unsigned int flags ATTRIBUTE_UNUSED)
> +{
> +    testConnPtr privconn = conn->privateData;
> +    int ret = -1;
> +
> +    testDriverLock(privconn);
> +
> +    if (!privconn->transaction_running) {
> +        testError(VIR_ERR_OPERATION_INVALID, _("no transaction running, "
> +                  "nothing to rollback."));
> +        goto cleanup;
> +    }
> +
> +    virInterfaceObjListFree(&privconn->ifaces);
> +    privconn->ifaces.count = privconn->backupIfaces.count;
> +    privconn->ifaces.objs = privconn->backupIfaces.objs;
> +    privconn->backupIfaces.count = 0;
> +    privconn->backupIfaces.objs = NULL;
> +
> +    privconn->transaction_running = false;
> +
> +    ret = 0;
> +
> +cleanup:
> +    testDriverUnlock(privconn);
> +    return ret;
> +}
>  
>  static char *testInterfaceGetXMLDesc(virInterfacePtr iface,
>                                       unsigned int flags ATTRIBUTE_UNUSED)
> @@ -5428,6 +5508,9 @@ static virInterfaceDriver testInterfaceDriver = {
>      .interfaceCreate = testInterfaceCreate, /* 0.7.0 */
>      .interfaceDestroy = testInterfaceDestroy, /* 0.7.0 */
>      .interfaceIsActive = testInterfaceIsActive, /* 0.7.3 */
> +    .interfaceChangeBegin = testInterfaceChangeBegin,   /* 0.9.2 */
> +    .interfaceChangeCommit = testInterfaceChangeCommit,  /* 0.9.2 */
> +    .interfaceChangeRollback = testInterfaceChangeRollback, /* 0.9.2 */
>  };

  Except for the small nit on how virInterfaceObjListClone()
handle errors, fine, and ACK once fixed (just do the free in the
caller on error).

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

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

Reply via email to