diff -Nur ./libvirt_org/src/xenapi/xenapi_driver.c ./libvirt/src/xenapi/xenapi_driver.c

--- ./libvirt_org/src/xenapi/xenapi_driver.c    1970-01-01 01:00:00.000000000 +0100

+++ ./libvirt/src/xenapi/xenapi_driver.c  2010-02-18 16:26:13.000000000 +0000

@@ -0,0 +1,1774 @@

+

+/*

+ * xenapi_driver.c: Xen API driver.

+ * Copyright (C) 2009 Citrix Ltd.

+ * Sharadha Prabhakar <sharadha.prabhakar@citrix.com>

+*/

+

+#include <config.h>

+#include <stdint.h>

+#include <unistd.h>

+#include <string.h>

+#include <stdlib.h>

+#include <errno.h>

+#include <sys/types.h>

+#include <libxml/uri.h>

+#include <xen_internal.h>

+#include <libxml/parser.h>

+#include <curl/curl.h>

+#include <xen/api/xen_common.h>

+#include <xen/api/xen_vm.h>

+#include <xen/api/xen_vm.h>

+#include <xen/api/xen_all.h>

+#include <xen/api/xen_vm_metrics.h>

+

+#include "libvirt_internal.h"

+#include "libvirt/libvirt.h"

+#include "virterror_internal.h"

+#include "datatypes.h"

+#include "xenapi_driver.h"

+#include "util.h"

+#include "uuid.h"

+#include "memory.h"

+#include "driver.h"

+#include "buf.h"

+#include "xenapi_utils.h"

+

+char *url;

+

+/*

+*XenapiOpen

+*

+*Authenticates and creates a session with the server

+*Return VIR_DRV_OPEN_SUCCESS on success, else VIR_DRV_OPEN_ERROR

+*/

+static virDrvOpenStatus

+xenapiOpen (virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED)

+{

+    char *user,*passwd;

+    char delims[]=":";

+    xen_session *session;

+    struct _xenapiPrivate *privP;

+

+    if (!STREQ(conn->uri->scheme,"XenAPI")) {

+        xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED ,"Check URI format: 'XenAPI://user:password@server'", __FILE__, __FUNCTION__, __LINE__);

+        return VIR_DRV_OPEN_ERROR;

+    }

+    if (conn->uri->server==NULL) {

+        xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED ,"Server name not in URI", __FILE__, __FUNCTION__, __LINE__);

+        return VIR_DRV_OPEN_ERROR;

+    } 

+

+    user = strtok(conn->uri->user,delims);

+    passwd = strtok(NULL,delims);

+

+

+

+    url = (char *)malloc(strlen("https://")+strlen(conn->uri->server)+1);

+    strcpy(url,"https://");

+    strcat(url,conn->uri->server);

+    url[strlen("https://")+strlen(conn->uri->server)]='\0';

+

+    xmlInitParser();

+    xmlKeepBlanksDefault(0);

+    xen_init();

+    curl_global_init(CURL_GLOBAL_ALL);

+   

+    session = xen_session_login_with_password( call_func, NULL, user, passwd, xen_api_latest_version);

+

+    if ( session != NULL && session->ok ) {

+     privP = malloc(sizeof(struct _xenapiPrivate));

+        privP->session = session;

+        conn->privateData = privP;

+        return VIR_DRV_OPEN_SUCCESS;

+    } else {

+        xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED ,"", __FILE__, __FUNCTION__, __LINE__);

+        return VIR_DRV_OPEN_ERROR;

+    }     

+}

+

+/*

+* xenapiClose:

+*

+* Returns 0 on successful session logout

+*

+*/

+static int

+xenapiClose (virConnectPtr conn)

+{

+    xen_session_logout(((struct _xenapiPrivate *)(conn->privateData))->session);

+    VIR_FREE(conn->privateData);

+    return 0;

+}

+

+/*

+*

+* xenapiSupportsFeature

+*

+* Returns 0

+*/

+static int

+xenapiSupportsFeature (virConnectPtr conn ATTRIBUTE_UNUSED, int feature)

+{

+    switch (feature) {

+        case VIR_DRV_FEATURE_MIGRATION_V2:

+     case VIR_DRV_FEATURE_MIGRATION_P2P:

+     default:

+         return 0;

+    }

+}

+

+/*

+* xenapiType:

+*

+*

+*Returns name of the driver

+*/

+static const char *

+xenapiType (virConnectPtr conn ATTRIBUTE_UNUSED)

+{

+    return "XenAPI";

+}

+

+

+/*

+* xenapiGetVersion:

+*

+* Gets the version of XenAPI

+*

+*/

+static int

+xenapiGetVersion (virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *hvVer)

+{

+    *hvVer = 1;

+    return 0;

+}

+

+

+/*

+* xenapiGetHostname:

+*

+*

+* Returns the hostname on success, or NULL on failure

+*/

+static char *

+xenapiGetHostname (virConnectPtr conn)

+{

+    char *result;

+    xen_host host;

+

+    if (!(xen_session_get_this_host(((struct _xenapiPrivate *)(conn->privateData))->session, &host,

+                            ((struct _xenapiPrivate *)(conn->privateData))->session))) {

+        if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok))

+            xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__, __FUNCTION__, __LINE__);

+        else

+            xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,"Unable to find host", __FILE__, __FUNCTION__, __LINE__);

+        return NULL;

+    }           

+    xen_host_get_hostname(((struct _xenapiPrivate *)(conn->privateData))->session, &result, host);

+    xen_host_free(host);

+    return result;

+}

+

+

+/*

+* xenapiGetMAxVcpus:

+*

+*

+* Returns a hardcoded value for Maximum VCPUS

+*/

+static int

+xenapiGetMaxVcpus (virConnectPtr conn ATTRIBUTE_UNUSED, const char *type ATTRIBUTE_UNUSED)

+{

+    /* this is hardcoded for simplicity and set to a resonable value compared

+       to the actual value */

+    return 16;

+}

+

+

+/*

+* xenapiNodeGetInfo:

+*

+*

+* Returns Node details on success or else -1

+*/

+static int

+xenapiNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info)

+{

+    int64_t memory,mhz;

+    xen_host_cpu_set *host_cpu_set;

+    xen_host_cpu host_cpu;

+    xen_host_metrics_set *xen_met_set;

+    char *modelname;

+    info->nodes = 1;

+    info->threads = 1;

+    info->sockets = 1;

+

+    if (xen_host_metrics_get_all(((struct _xenapiPrivate *)(conn->privateData))->session,

+                                  &xen_met_set)) {                    

+        xen_host_metrics_get_memory_total(((struct _xenapiPrivate *)(conn->privateData))->session,

+                                         &memory, xen_met_set->contents[0]);

+        info->memory = (unsigned long)(memory/1024);                        

+        xen_host_metrics_set_free(xen_met_set);

+    } else {

+        xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR ,"Unable to get host metric Information",

+                                  __FILE__, __FUNCTION__, __LINE__);                          

+        return -1;

+    }

+    if (xen_host_cpu_get_all(((struct _xenapiPrivate *)(conn->privateData))->session,

+                             &host_cpu_set)) {            

+        host_cpu = host_cpu_set->contents[0];

+        xen_host_cpu_get_modelname(((struct _xenapiPrivate *)(conn->privateData))->session,

+                                &modelname, host_cpu);          

+     strncpy(info->model, modelname, LIBVIRT_MODELNAME_LEN-2);

+        info->model[LIBVIRT_MODELNAME_LEN-1]='\0';

+        xen_host_cpu_get_speed(((struct _xenapiPrivate *)(conn->privateData))->session,

+                             &mhz, host_cpu);

+        info->mhz = (unsigned long)mhz;                   

+        info->cpus = host_cpu_set->size;

+        info->cores = host_cpu_set->size;

+

+     xen_host_cpu_set_free(host_cpu_set);

+        free(modelname);

+     return 0;

+    }

+    xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR ,"Unable to get Host CPU set",

+                              __FILE__, __FUNCTION__, __LINE__);                        

+    return -1;

+}

+

+

+/*

+* xenapiGetCapabilities:

+*

+*

+* Returns capabilities as an XML string

+*/

+static char *

+xenapiGetCapabilities (virConnectPtr conn ATTRIBUTE_UNUSED)

+{

+    virBuffer buf = VIR_BUFFER_INITIALIZER;

+    virBufferAddLit(&buf, "<capabilities>\n");

+    virBufferAddLit(&buf, "<host>\n");

+    virBufferAddLit(&buf, "    <cpu></cpu>\n");

+    virBufferAddLit(&buf, "</host>");

+    virBufferAddLit(&buf, "<guest>\n");

+    virBufferAddLit(&buf, "<os_type>hvm</os_type>\n");

+    virBufferAddLit(&buf, "<arch>\n");

+    virBufferAddLit(&buf, "<domain type='xenapi'></domain>\n");

+    virBufferAddLit(&buf, "</arch>\n");

+    virBufferAddLit(&buf, "</guest>\n");

+    virBufferAddLit(&buf, "</capabilities>\n");

+    return virBufferContentAndReset(&buf);

+}

+

+/*

+* xenapiListDomains

+*

+* Collects the list of active domains, and store their ID in @maxids

+* Returns the number of domain found or -1 in case of error

+*/

+static int

+xenapiListDomains (virConnectPtr conn, int *ids, int maxids)

+{

+    /* vm.list */

+    int i,list;

+    xen_host host;

+    xen_vm_set *result=NULL;

+    if (xen_session_get_this_host(((struct _xenapiPrivate *)(conn->privateData))->session, &host,

+                                    ((struct _xenapiPrivate *)(conn->privateData))->session)) {

+        xen_host_get_resident_vms(((struct _xenapiPrivate *)(conn->privateData))->session, &result, host);

+        xen_host_free(host);

+    } else {

+        xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__, __FUNCTION__, __LINE__);   

+    }     

+    if (result != NULL) {

+        for ( i=0; (i < (result->size)) && (i<maxids) ; i++ ) {

+            int64_t t0;

+            xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session, &t0, result->contents[i]);

+            ids[i] = (int)(t0 & 0xffffffff);

+        }

+     list = result->size;

+     xen_vm_set_free(result);

+        return list;

+    }

+    return -1;

+}

+

+/*

+* xenapiNumOfDomains

+*

+*

+* Returns the number of domains found or -1 in case of error

+*/

+static int

+xenapiNumOfDomains (virConnectPtr conn)

+{

+    /* #(vm.list) */

+    xen_vm_set *result=NULL;

+    xen_host host=NULL;

+    int numDomains=-1;

+

+    xen_session_get_this_host(((struct _xenapiPrivate *)(conn->privateData))->session, &host,

+                                    ((struct _xenapiPrivate *)(conn->privateData))->session);

+    if ( host!=NULL ) {

+        xen_host_get_resident_vms(((struct _xenapiPrivate *)(conn->privateData))->session, &result, host);

+        if ( result != NULL) {

+            numDomains = result->size;

+         xen_vm_set_free(result);

+        }

+     xen_host_free(host);

+    }

+    if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok))     

+        xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__, __FUNCTION__, __LINE__);

+    return numDomains;

+}

+

+/*

+* xenapiDomainCreateXML

+*

+* Launches a new domain based on the XML description

+* Returns the domain pointer or NULL in case of error

+*/

+static virDomainPtr

+xenapiDomainCreateXML (virConnectPtr conn,

+                       const char *xmlDesc, ATTRIBUTE_UNUSED unsigned int flags)

+{

+    xen_vm_record *record=NULL;

+    xen_vm vm=NULL;

+    virDomainPtr domP=NULL;

+    createVMRecordFromXml( conn, xmlDesc, &record, &vm);

+    if (record!=NULL) {

+        unsigned char raw_uuid[RAW_UUID_BUFLEN];

+     virUUIDParse(record->uuid,raw_uuid);

+     if (vm!=NULL) {

+            if (xen_vm_start(((struct _xenapiPrivate *)(conn->privateData))->session,

+                                                 vm, false, false)) {

+             domP = virGetDomain(conn, record->name_label, raw_uuid);

+             xen_vm_free(vm);

+         }

+            else

+                xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);     

+     }

+        xen_vm_record_free(record); 

+    }

+    else

+        xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+    return domP;

+}

+

+/*

+* xenapiDomainLookupByID

+*

+*

+* Returns a valid domain pointer of the domain with ID same as the one passed

+* or NULL in case of error

+*/

+static virDomainPtr

+xenapiDomainLookupByID (virConnectPtr conn, int id)

+{

+    int i;

+    int64_t domID;

+    char *uuid;

+    xen_host host;

+    xen_vm_set *result;

+    xen_vm_record *record;

+    unsigned char raw_uuid[RAW_UUID_BUFLEN];

+    virDomainPtr domP=NULL;

+

+    xen_session_get_this_host(((struct _xenapiPrivate *)(conn->privateData))->session, &host,

+                           ((struct _xenapiPrivate *)(conn->privateData))->session);

+    if (host!=NULL && ((struct _xenapiPrivate *)(conn->privateData))->session->ok) {                      

+        xen_host_get_resident_vms(((struct _xenapiPrivate *)(conn->privateData))->session, &result, host);

+        if ( result !=NULL ) {

+            for( i=0; i < (result->size); i++) {

+                xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session, &domID, result->contents[i]);

+             if ( domID == id ) {

+                 xen_vm_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,

+                                   &record, result->contents[i]);

+                 xen_vm_get_uuid(((struct _xenapiPrivate *)(conn->privateData))->session, &uuid, result->contents[i]);

+                 virUUIDParse(uuid,raw_uuid);

+                 domP = virGetDomain(conn, record->name_label, raw_uuid);

+                    if (domP!=NULL) {

+                        int64_t domid=-1;

+                        xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session,

+                                         &domid, result->contents[i]);

+                        domP->id = domid;

+                    }

+               xen_uuid_free(uuid);

+                 xen_vm_record_free(record);

+             }

+            }

+         xen_vm_set_free(result);

+        } else {

+            xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN ,NULL, __FILE__, __FUNCTION__, __LINE__);

+        }

+     xen_host_free(host);

+    } else {

+        xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__, __FUNCTION__, __LINE__);

+    }

+    return domP;

+}

+

+/*

+* xenapiDomainLookupByUUID

+*

+* Returns the domain pointer of domain with matching UUID

+* or -1 in case of error

+*/

+static virDomainPtr

+xenapiDomainLookupByUUID (virConnectPtr conn,

+                          const unsigned char *uuid)

+{

+    /* vm.get_by_uuid */

+    xen_vm vm;

+    xen_vm_record *record;

+    unsigned char raw_uuid[RAW_UUID_BUFLEN];

+    virDomainPtr domP=NULL;

+    if (xen_vm_get_by_uuid(((struct _xenapiPrivate *)(conn->privateData))->session,

+                            &vm, (char *)uuid)) {

+        xen_vm_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,

+                           &record, vm);

+        if (record != NULL) {

+            virUUIDParse((char *)uuid,raw_uuid);                   

+            domP = virGetDomain(conn, record->name_label, raw_uuid);               

+         xen_vm_record_free(record);

+        }

+        else

+            xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN ,NULL, __FILE__, __FUNCTION__, __LINE__);

+        xen_vm_free(vm);

+    } else

+        xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN ,NULL, __FILE__, __FUNCTION__, __LINE__);

+    return domP;

+}

+

+/*

+* xenapiDomainLookupByName

+*

+* Returns the domain pointer of domain with matching name

+* or -1 in case of error

+*/

+static virDomainPtr

+xenapiDomainLookupByName (virConnectPtr conn,

+                          const char *name)

+{

+    /* vm.get_by_name_label */

+    xen_vm_set *vms=NULL;

+    xen_vm vm;

+    char *uuid=NULL;

+    unsigned char raw_uuid[RAW_UUID_BUFLEN];

+    virDomainPtr domP=NULL;

+  

+    xen_vm_get_by_name_label(((struct _xenapiPrivate *)(conn->privateData))->session,

+                             &vms, (char *)name);

+    if (vms!=NULL && vms->size!=0) {                    

+        vm = vms->contents[0];

+     xen_vm_get_uuid(((struct _xenapiPrivate *)(conn->privateData))->session,

+                     &uuid, vm);

+        if (uuid!=NULL) {

+         virUUIDParse(uuid,raw_uuid);

+         domP = virGetDomain(conn, name, raw_uuid);

+            if (domP != NULL) {

+                int64_t domid=-1;

+                xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session,

+                                 &domid, vm);

+                domP->id = domid;

+                xen_uuid_free(uuid);

+                xen_vm_set_free(vms);

+           return domP;

+            } else {

+                xen_uuid_free(uuid);      

+                xen_vm_set_free(vms);

+           if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok)) {

+               xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+           }

+                return NULL;

+            }

+        }

+    }

+    if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok)) {

+        xenapiSessionErrorHandler(conn,VIR_ERR_NO_DOMAIN,NULL,__FILE__,__FUNCTION__, __LINE__);

+    } else {

+        xenapiSessionErrorHandler(conn,VIR_ERR_NO_DOMAIN,"Domain name not found",__FILE__,__FUNCTION__, __LINE__);

+    }

+    return NULL;

+}

+

+/*

+* xenapiDomainSuspend

+*

+* a VM is paused

+* Returns 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainSuspend (virDomainPtr dom)

+{

+    /* vm.pause() */

+    xen_vm vm;

+    xen_vm_set *vms;

+    if (!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                           &vms, dom->name)) {

+        xenapiSessionErrorHandler(dom->conn,VIR_ERR_NO_DOMAIN,NULL,__FILE__,__FUNCTION__, __LINE__);

+        return -1;                     

+    }

+    vm = vms->contents[0];

+    if (!xen_vm_pause(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+        xen_vm_set_free(vms);

+        return -1;

+    }

+    xen_vm_set_free(vms);

+    return 0;

+}

+

+/*

+* xenapiDomainResume

+*

+* Resumes a VM

+* Returns 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainResume (virDomainPtr dom)

+{

+    /* vm.unpause() */

+    xen_vm vm;

+    xen_vm_set *vms;

+    if (!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                               &vms, dom->name)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;                    

+    }

+    if (vms!=NULL && vms->size!=0) {

+        vm = vms->contents[0];

+        if (!xen_vm_unpause(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {

+            xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+            xen_vm_set_free(vms);

+            return -1;                

+        }       

+        xen_vm_set_free(vms);

+    }

+    return 0;

+}

+

+/*

+* xenapiDomainShutdown

+*

+* shutsdown a VM

+* Returns 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainShutdown (virDomainPtr dom)

+{

+    /* vm.clean_shutdown */

+    xen_vm vm;

+    xen_vm_set *vms;

+    if(!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                           &vms, dom->name)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;                    

+    }

+    vm = vms->contents[0];

+    if (!xen_vm_clean_shutdown(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+        xen_vm_set_free(vms);

+        return -1;

+    }

+    xen_vm_set_free(vms);

+    return 0;

+}

+

+/*

+* xenapiDomainReboot

+*

+* Reboots a VM

+* Returns 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainReboot (virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED)

+{

+    /* vm.clean_reboot */

+    xen_vm vm;

+    struct xen_vm_set *vms;

+    xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                           &vms, dom->name);

+    if (vms==NULL || vms->size==0) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    vm = vms->contents[0];

+    if (!xen_vm_clean_reboot(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+        xen_vm_set_free(vms);

+        return -1;

+    }

+    xen_vm_set_free(vms);

+    return 0;

+}

+

+/*

+* xenapiDomaindestroy

+*

+* A VM is hard shutdown

+* Returns 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainDestroy (virDomainPtr dom)

+{ 

+    /* vm.hard_shutdown */

+    xen_vm vm;

+    struct xen_vm_set *vms;

+    xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                           &vms, dom->name);

+    if (vms==NULL || vms->size==0) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    vm = vms->contents[0];

+    if (!xen_vm_hard_shutdown(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+        xen_vm_set_free(vms);

+        return -1;

+    }

+    xen_vm_set_free(vms);

+    return 0;

+}

+

+/*

+* xenapiDomainGetOSType

+*

+*

+* Returns OS version on success or NULL in case of error

+*/

+static char *

+xenapiDomainGetOSType (virDomainPtr dom)

+{

+    /* vm.get_os-version */

+    int i;

+    xen_vm vm;

+    char *os_version=NULL;

+    xen_vm_record *record;

+    xen_string_string_map *result;

+    char uuid[VIR_UUID_STRING_BUFLEN];

+    virUUIDFormat(dom->uuid,uuid);

+    if (xen_vm_get_by_uuid(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                       &vm, uuid)) {                 

+        xen_vm_get_record(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                          &record, vm);

+        if (record!=NULL) {

+            xen_vm_guest_metrics_get_os_version(((struct _xenapiPrivate *)(dom->conn->privateData))->session, &result,

+                                                 record->guest_metrics->u.handle);

+            if (result != NULL) {

+             for (i=0; i<(result->size); i++) {

+               if (STREQ(result->contents[i].key, "distro")) {

+                   if (STREQ(result->contents[i].val, "windows")) {

+                         os_version = strdup(result->contents[i].val);

+                 } else {

+                     os_version = strdup("linux");

+                 }

+               }

+           }

+                xen_string_string_map_free(result);

+         } else

+                xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_OS, NULL, __FILE__, __FUNCTION__, __LINE__);

+            xen_vm_record_free(record);

+        } else

+            xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        xen_vm_free(vm);

+    }

+    else

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+    if ( os_version == NULL ) {

+        os_version = strdup("unknown");

+    }     

+    return os_version;

+}

+

+/*

+* xenapiDomainGetMaxMemory

+*

+* Returns maximum static memory for VM on success

+* or 0 in case of error

+*/

+static unsigned long

+xenapiDomainGetMaxMemory (virDomainPtr dom)

+{

+    int64_t mem_static_max=0;

+    xen_vm vm;

+    xen_vm_set *vms;

+    xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                             &vms, dom->name);

+    if (vms != NULL && vms->size!=0) {

+        /* vm.get_memory_static_max */

+     vm = vms->contents[0];

+        xen_vm_get_memory_static_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                          &mem_static_max, vm);                            

+     xen_vm_set_free(vms);

+        return (unsigned long)(mem_static_max/1024);

+    } else {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+     return 0;

+    }

+}

+

+/*

+* xenapiDomainSetMaxMemory

+*

+* Sets maximum static memory for VM on success

+* Returns 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainSetMaxMemory (virDomainPtr dom, unsigned long memory)

+{

+    /* vm.set_memory_static_max */

+    xen_vm vm;

+    struct xen_vm_set *vms;

+    xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                 &vms, dom->name);

+    if (vms!=NULL && vms->size!=0) {

+        vm = vms->contents[0];

+        if (!(xen_vm_set_memory_static_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                        vm, memory))) {

+            xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+            xen_vm_set_free(vms);

+            return -1;

+        }

+        xen_vm_set_free(vms);

+    } else {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    return 0;

+}

+

+static int

+xenapiDomainSetMemory (virDomainPtr dom, unsigned long memory ATTRIBUTE_UNUSED)

+{

+    /* XenAPI doesn't allow this function */

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+/*

+* xenapiDomainGetInfo:

+*

+* Fills a structure with domain information

+* Returns 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)

+{

+    int64_t maxmem=0,memory=0,vcpu=0;

+    xen_vm vm;

+    xen_vm_record *record;

+    xen_vm_set *vms;

+    info->cpuTime = 0; /* CPU time is not advertised */

+    if (xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                     &vms, dom->name)) {

+        vm = vms->contents[0];

+     xen_vm_get_memory_static_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                  &maxmem, vm);

+        info->maxMem = (maxmem/1024);   

+     enum xen_vm_power_state state = XEN_VM_POWER_STATE_UNKNOWN;

+     xen_vm_get_power_state(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                       &state, vm);

+        info->state = mapPowerState(state);                     

+     xen_vm_get_record(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                       &record, vm);

+        if (record!=NULL) {

+            xen_vm_metrics_get_memory_actual(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                             &memory, record->metrics->u.handle);

+            info->memory = (memory/1024);

+         xen_vm_record_free(record);

+        }                       

+     xen_vm_get_vcpus_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                              &vcpu, vm);

+        info->nrVirtCpu = vcpu;               

+     xen_vm_set_free(vms);

+        return 0;

+    }

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+/*

+* xenapiDomainSave

+*

+* suspends a VM

+* Return 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainSave (virDomainPtr dom, const char *to ATTRIBUTE_UNUSED)

+{

+    int ret_code = -1;

+    ret_code = xenapiDomainSuspend(dom);

+    return ret_code;

+}

+

+/*

+* xenapiDomainRestore

+*

+* Resumes a VM

+* Return 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainRestore (virConnectPtr conn, const char *from ATTRIBUTE_UNUSED)

+{

+    /* resume from : NI */

+    xen_vm_set *result=NULL;

+    xen_host host=NULL;

+    xen_vm_record *record = NULL;

+    unsigned char raw_uuid[RAW_UUID_BUFLEN];

+    virDomainPtr domP=NULL;

+    int ret_code=-1;

+

+    xen_session_get_this_host(((struct _xenapiPrivate *)(conn->privateData))->session, &host,

+                              ((struct _xenapiPrivate *)(conn->privateData))->session);

+    if ( host!=NULL ) {

+        xen_host_get_resident_vms(((struct _xenapiPrivate *)(conn->privateData))->session, &result, host);

+        if ( result != NULL ) {

+         xen_vm_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,

+                           &record, result->contents[0]);

+            if (record!=NULL) {                     

+                virUUIDParse(record->uuid,raw_uuid);

+                   domP = virGetDomain(conn, record->name_label, raw_uuid);

+             if (domP!=NULL)

+                 ret_code = xenapiDomainResume(domP);

+                else

+                    xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+           xen_vm_record_free(record);   

+         }    

+            xen_vm_set_free(result);

+        }

+        xen_host_free(host);

+    }

+    if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok))

+        xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+    return ret_code;

+}

+

+static int

+xenapiDomainCoreDump (virDomainPtr dom, const char *to ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, NULL, __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+/*

+* xenapiDomainSetVcpus

+*

+* Sets the VCPUs on the domain

+* Return 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)

+{

+

+    /* vm.set_vcpus_max */

+    xen_vm vm;

+    xen_vm_set *vms;

+    xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                             &vms, dom->name);

+    if (vms!=NULL && vms->size!=0) {

+        vm = vms->contents[0];

+     if (xen_vm_set_vcpus_number_live(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                  vm, (int64_t)nvcpus)) {

+         xen_vm_set_free(vms);

+         return 0;

+     }

+    }

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__); 

+    return -1;

+}

+

+/*

+* xenapiDomainPinVcpu

+*

+* Dynamically change the real CPUs which can be allocated to a virtual CPU

+* Returns 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainPinVcpu (virDomainPtr dom, unsigned int vcpu,

+                     unsigned char *cpumap, int maplen)

+{

+    char *value;

+    xen_vm vm;

+    xen_vm_set *vms;

+    xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                             &vms, dom->name);

+    if (vms!=NULL && vms->size!=0) {

+        vm = vms->contents[0];

+        value = mapDomainPinVcpu(vcpu, cpumap, maplen);

+     xen_vm_remove_from_vcpus_params(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm, (char *)"mask");

+        if (xen_vm_add_to_vcpus_params(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                         vm, (char *)"mask", value)) {

+         xen_vm_set_free(vms);

+         return 0;

+     }

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+     xen_vm_set_free(vms);

+    }     

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+/*

+* xenapiDomainGetVcpus

+*

+* Gets Vcpu information

+* Return number of structures filled on success or -1 in case of error

+*/

+static int

+xenapiDomainGetVcpus (virDomainPtr dom,

+                      virVcpuInfoPtr info, int maxinfo,

+                      unsigned char *cpumaps, int maplen)

+{

+

+    xen_vm_set *vms=NULL;

+    xen_vm vm=NULL;

+    xen_string_string_map *vcpu_params=NULL;

+    int nvcpus=0,cpus=0,i;

+    virDomainInfoPtr domInfo;

+    virNodeInfo nodeInfo;

+    virVcpuInfoPtr ifptr;

+    char *mask=NULL;

+    if((cpumaps!=NULL) && (maplen < 1))

+        return -1;

+    domInfo =(struct _virDomainInfo *) malloc(sizeof(struct _virDomainInfo));

+    if (virDomainGetInfo(dom,domInfo)==0) {

+        nvcpus = domInfo->nrVirtCpu;

+     free(domInfo);

+    } else {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, "Couldn't fetch Domain Information",

+                                   __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    if ( virNodeGetInfo(dom->conn,&nodeInfo)==0)

+        cpus = nodeInfo.cpus;

+    else {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, "Couldn't fetch Node Information",

+                                   __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    if(nvcpus > maxinfo) nvcpus = maxinfo;

+

+    if (cpumaps != NULL)

+        memset(cpumaps, 0, maxinfo * maplen);

+

+    if (!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                 &vms, dom->name)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    vm = vms->contents[0];

+    if (!xen_vm_get_vcpus_params(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                 &vcpu_params, vm)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    for (i=0; i<vcpu_params->size; i++) {

+        if (STREQ(vcpu_params->contents[i].key,"mask")) {

+         mask = strdup(vcpu_params->contents[i].val);

+         }

+    }

+    for (i=0,ifptr=info ;i<nvcpus; i++,ifptr++) {

+        ifptr->number = i;

+     ifptr->state = VIR_VCPU_RUNNING;

+     ifptr->cpuTime = 0;

+     ifptr->cpu = 0;

+     if (mask !=NULL)

+         getCpuBitMapfromString(mask,VIR_GET_CPUMAP(cpumaps,maplen,i),maplen);

+    }

+    return i;

+}

+

+/*

+* xenapiDomainGetMaxVcpus

+*

+*

+* Returns maximum number of Vcpus on success or -1 in case of error

+*/

+static int

+xenapiDomainGetMaxVcpus (virDomainPtr dom)

+{

+    xen_vm vm;

+    xen_vm_set *vms;

+    int64_t maxvcpu=0;

+    enum xen_vm_power_state state;

+

+    if (xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                &vms, dom->name)) {

+        vm = vms->contents[0];

+     xen_vm_get_power_state(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                            &state, vm);

+        if(state == XEN_VM_POWER_STATE_RUNNING)      {

+            xen_vm_get_vcpus_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                              &maxvcpu, vm);

+     } else {

+         maxvcpu = xenapiGetMaxVcpus(dom->conn, NULL);

+     }

+     xen_vm_set_free(vms);

+     return (int)maxvcpu;

+    }

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+/*

+* xenapiDomainDumpXML

+*

+*

+* Returns XML string of the domain configuration on success or -1 in case of error

+*/

+static char *

+xenapiDomainDumpXML (virDomainPtr dom, ATTRIBUTE_UNUSED int flags)

+{

+    virBuffer buf = VIR_BUFFER_INITIALIZER;

+    char uuid_string[VIR_UUID_STRING_BUFLEN];

+    xen_vm vm=NULL;

+    xen_vm_set *vms;

+    xen_string_string_map *result=NULL;

+

+    xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                             &vms, dom->name);

+    if (vms==NULL || vms->size==0) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return NULL;

+    }

+

+    vm = vms->contents[0];                   

+    virBufferAddLit(&buf, "<domain type='xenapi'>\n");

+    virBufferEscapeString(&buf, "    <name>%s</name>\n", "testVM");

+    virUUIDFormat(dom->uuid,uuid_string);

+    virBufferEscapeString(&buf, "    <uuid>%s</uuid>\n",uuid_string);

+

+

+    virBufferAddLit(&buf, "    <os>\n");

+    char *boot_policy=NULL;

+    xen_vm_get_hvm_boot_policy(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                &boot_policy, vm);

+    if (STREQ(boot_policy,"BIOS order")) {                      

+        virBufferAddLit(&buf, "        <type>hvm</type>\n");

+        xen_vm_get_hvm_boot_params(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                            &result, vm);

+        if (result!=NULL) {

+            int i;

+            for (i=0; i<(result->size); i++) {

+                if (STREQ(result->contents[i].key,"order")) {

+               int j=0;

+               while(result->contents[i].val[j]!='\0') {

+                        virBufferEscapeString(&buf, "        <boot dev='%s' />\n",

+                                       mapXmlBootOrder(result->contents[i].val[j]));

+                 j++;

+               }

+           }

+         }

+         xen_string_string_map_free(result);

+        }

+        VIR_FREE(boot_policy);    

+    } else {

+        virBufferAddLit(&buf, "        <type>linux</type>\n");

+        virBufferAddLit(&buf, "        <loader>pygrub</loader>\n");

+        char *value=NULL;

+        xen_vm_get_pv_kernel(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                       &value, vm);

+        if (!STREQ(value,"")) {

+            virBufferEscapeString(&buf,"        <kernel>%s</kernel>\n",value);

+         VIR_FREE(value);

+        } 

+        xen_vm_get_pv_ramdisk(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                              &value, vm);

+        if (!STREQ(value,"")) {

+            virBufferEscapeString(&buf,"        <initrd>%s</initrd>\n",value);

+         VIR_FREE(value);

+        }

+        xen_vm_get_pv_args(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                           &value, vm);

+        if (!STREQ(value,"")) {

+            virBufferEscapeString(&buf,"        <cmdline>%s</cmdline>\n",value);

+         VIR_FREE(value);

+        }

+     VIR_FREE(boot_policy);

+    }   

+    virBufferAddLit(&buf, "    </os>\n");

+    virBufferAddLit(&buf, "    <bootloader>pygrub</bootloader>\n");

+    char *val=NULL;

+    xen_vm_get_pv_bootloader_args(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                          &val, vm);                        

+    if (!STREQ(val,"")) {

+        virBufferEscapeString(&buf,"    <bootloader_args>%s</bootloader_args>\n",val);

+     VIR_FREE(val);

+    }

+    unsigned long memory=0;

+    memory = xenapiDomainGetMaxMemory(dom);

+    virBufferVSprintf(&buf,"    <memory>%lu</memory>\n",memory);

+    int64_t dynamic_mem=0;

+    if (xen_vm_get_memory_dynamic_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                             &dynamic_mem, vm)) {

+        virBufferVSprintf(&buf,"    <currentmemory>%lld</currentmemory>\n",(dynamic_mem/1024));

+    } else {

+        virBufferVSprintf(&buf,"    <currentmemory>%lu</currentmemory>\n",memory);

+    }

+    virBufferVSprintf(&buf,"    <vcpu>%d</vcpu>\n",xenapiDomainGetMaxVcpus(dom));

+    enum xen_on_normal_exit action;

+    if (xen_vm_get_actions_after_shutdown(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                      &action, vm)) {

+        virBufferEscapeString(&buf,"    <on_poweroff>%s</on_poweroff>\n",xen_on_normal_exit_to_string(action));

+    }     

+    if (xen_vm_get_actions_after_reboot(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                           &action, vm)) {

+        virBufferEscapeString(&buf,"    <on_reboot>%s</on_reboot>\n",xen_on_normal_exit_to_string(action));

+    }

+    enum xen_on_crash_behaviour crash;

+    if (xen_vm_get_actions_after_crash(((struct _xenapiPrivate *)(dom->conn->privateData))->session, &crash, vm)) {

+        virBufferEscapeString(&buf,"    <on_crash>%s</on_crash>\n",xen_on_crash_behaviour_to_string(crash));

+    }     

+    xen_vm_get_platform(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                            &result, vm);                     

+    if (result!=NULL) {     

+        int i;

+        virBufferAddLit(&buf, "    <features>\n");

+     for(i=0; i< (result->size); i++) {

+         if (STREQ(result->contents[i].val,"true")) {

+                virBufferVSprintf(&buf,"        <%s/>\n",result->contents[i].key);

+         }

+     }

+        virBufferAddLit(&buf, "    </features>\n");

+        xen_string_string_map_free(result);

+    }

+    struct xen_vif_set *vif_set=NULL;

+    xen_vm_get_vifs(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                     &vif_set, vm);

+    if (vif_set) {

+        int i;

+     xen_vif vif;

+     xen_vif_record *vif_rec=NULL;

+     xen_network network;

+     char *bridge=NULL;

+     for (i=0; i<vif_set->size; i++) {

+         virBufferAddLit(&buf, "    <interface type='bridge'>\n");

+         vif = vif_set->contents[i];

+            xen_vif_get_network(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                             &network, vif);

+         if (network!=NULL) {                 

+                xen_network_get_bridge(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                    &bridge, network);

+                if (bridge!=NULL) {

+                    virBufferEscapeString(&buf,"        <source bridge='%s' />\n",bridge);

+               VIR_FREE(bridge);

+           }

+             xen_network_free(network);

+         }

+         xen_vif_get_record(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                             &vif_rec, vif);

+            if (vif_rec!=NULL) {

+                virBufferEscapeString(&buf,"        <mac address='%s' />\n", vif_rec->mac);

+           xen_vif_record_free(vif_rec);

+         }

+         virBufferAddLit(&buf, "    </interface>\n");

+        }

+        xen_vif_set_free(vif_set);

+    }

+    virBufferAddLit(&buf, "</domain>");

+    if (vms) xen_vm_set_free(vms);

+    return virBufferContentAndReset(&buf);

+}

+

+static char *

+xenapiDomainXMLFromNative(virConnectPtr conn,

+                          const char *format ATTRIBUTE_UNUSED,

+                          const char *config ATTRIBUTE_UNUSED,

+                          unsigned int flags ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return NULL;

+}

+

+

+static char *

+xenapiDomainXMLToNative(virConnectPtr conn,

+                        const char *format ATTRIBUTE_UNUSED,

+                        const char *xmlData ATTRIBUTE_UNUSED,

+                        unsigned int flags ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return NULL;

+}

+

+/*

+* xenapiListDefinedDomains

+*

+* list the defined but inactive domains, stores the pointers to the names in @names

+* Returns number of names provided in the array or -1 in case of error

+*/

+static int

+xenapiListDefinedDomains (virConnectPtr conn, char **const names,

+                          int maxnames)

+{

+    int i,j=0,doms;

+    xen_vm_set *result;

+    xen_vm_record *record;

+    xen_vm_get_all(((struct _xenapiPrivate *)(conn->privateData))->session, &result);

+    if (result != NULL) {

+        for (i=0; i< (result->size) && j< maxnames; i++) {

+         xen_vm_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,

+                            &record, result->contents[i]);

+         if ( record!=NULL ) {                 

+                if ( record->is_a_template == 0 ) {

+                    char *usenames;

+               usenames = strdup(record->name_label);

+               names[j++]=usenames;

+           }   

+                xen_vm_record_free(record);

+         } else {

+                xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get VM record", __FILE__, __FUNCTION__, __LINE__);

+                xen_vm_set_free(result);

+                 return -1;

+            }   

+     }

+        doms=j;

+        xen_vm_set_free(result);

+        return doms;

+    }

+    xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE, NULL, __FILE__, __FUNCTION__, __LINE__); 

+    return -1;

+}

+

+/*

+* xenapiNumOfDefinedDomains

+*

+* Provides the number of defined but inactive domains

+* Returns number of domains found on success or -1 in case of error

+*/

+static int

+xenapiNumOfDefinedDomains (virConnectPtr conn)

+{

+    xen_vm_set *result;

+    xen_vm_record *record;

+    int DomNum=0,i;

+    xen_vm_get_all(((struct _xenapiPrivate *)(conn->privateData))->session, &result);

+    if ( result != NULL) {

+        for ( i=0; i< (result->size); i++ ) {

+         xen_vm_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,

+                            &record, result->contents[i]);

+            if (record==NULL && !(((struct _xenapiPrivate *)(conn->privateData))->session->ok)) {

+                xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+                xen_vm_set_free(result);

+                return -1;

+            }

+            if (record->is_a_template == 0)

+                DomNum++;

+         xen_vm_record_free(record);

+     }

+        xen_vm_set_free(result);

+        return DomNum;

+    }

+    xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE, NULL, __FILE__, __FUNCTION__, __LINE__); 

+    return -1;

+}

+

+/*

+* xenapiDomainCreate

+*

+* starts a VM

+* Return 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainCreate (virDomainPtr dom)

+{

+    xen_vm_set *vms;

+    xen_vm vm;

+    xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                           &vms, dom->name);

+    if (vms!=NULL && vms->size!=0) {

+        vm = vms->contents[0];

+        if (!xen_vm_start(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm, false, false)) {

+            xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+            xen_vm_set_free(vms);

+            return -1;

+        }

+        xen_vm_set_free(vms);

+    } else {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    return 0;

+}

+

+/*

+* xenapiDomainDefineXML

+*

+* Defines a domain from the given XML but does not start it

+* Returns 0 on success or -1 in case of error

+*/

+static virDomainPtr

+xenapiDomainDefineXML (virConnectPtr conn, const char *xml)

+{

+    xen_vm_record *record=NULL;

+    xen_vm vm=NULL;

+    virDomainPtr domP=NULL;

+    if(createVMRecordFromXml( conn, xml, &record, &vm)!=0) {

+        if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok))

+            xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+        else

+            xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get VM information from XML",

+                                      __FILE__, __FUNCTION__, __LINE__);

+        return NULL;

+    }

+    if (record!=NULL) {

+        unsigned char raw_uuid[RAW_UUID_BUFLEN];

+     virUUIDParse(record->uuid,raw_uuid);

+     domP = virGetDomain(conn, record->name_label, raw_uuid);

+        if (domP==NULL && !(((struct _xenapiPrivate *)(conn->privateData))->session->ok))

+            xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+     xen_vm_record_free(record);

+    }

+    else if (vm!=NULL)

+        xen_vm_free(vm);

+    return domP;

+}

+

+/*

+* xenapiDomainUndefine

+*

+* destroys a domain

+* Return 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainUndefine (virDomainPtr dom)

+{

+    struct xen_vm_set *vms;

+    xen_vm vm;

+    if (!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                           &vms, dom->name)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    vm = vms->contents[0];

+    if (!xen_vm_destroy(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+        xen_vm_set_free(vms);

+        return -1;

+    }

+    xen_vm_set_free(vms);

+    return 0;

+}

+

+static int

+xenapiDomainAttachDevice (virDomainPtr dom, const char *xml ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static int

+xenapiDomainDetachDevice (virDomainPtr dom, const char *xml ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+/*

+* xenapiDomainGetAutostart

+*

+* Provides a boolean value indicating whether the domain configured

+* to be automatically started when the host machine boots

+* Return 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainGetAutostart (virDomainPtr dom, int *autostart)

+{

+    int i,flag=0;

+    xen_vm_set *vms;

+    xen_vm vm;

+    xen_string_string_map *result;

+    if(!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                              &vms, dom->name)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    vm = vms->contents[0];

+    if (!xen_vm_get_other_config(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                &result, vm)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+        xen_vm_set_free(vms);

+        return -1;

+    }

+    for (i=0; i < result->size; i++) {

+     if (STREQ(result->contents[i].key, "auto_poweron")) {

+         flag=1;

+         if (STREQ(result->contents[i].val, "true"))

+             *autostart = 1;

+         else

+             *autostart = 0;

+     }   

+    }

+    xen_vm_set_free(vms);

+    xen_string_string_map_free(result);

+    if (flag==0) return -1;

+    return 0;

+}

+

+/*

+* xenapiDomainSetAutostart

+*

+* Configure the domain to be automatically started when the host machine boots

+* Return 0 on success or -1 in case of error

+*/

+static int

+xenapiDomainSetAutostart (virDomainPtr dom, int autostart)

+{

+    xen_vm_set *vms;

+    xen_vm vm;

+    char *value;

+    if (!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                 &vms, dom->name)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    }

+    vm = vms->contents[0];

+    xen_vm_remove_from_other_config(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                    vm, (char *)"auto_poweron");

+    if (autostart==1)

+        value = (char *)"true";

+    else

+        value = (char *)"false";

+    if (!xen_vm_add_to_other_config(((struct _xenapiPrivate *)(dom->conn->privateData))->session,

+                                   vm, (char *)"auto_poweron", value)) {

+        xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);

+        xen_vm_set_free(vms);

+        return -1;

+    }

+    xen_vm_set_free(vms);

+    return 0;

+}

+

+static char *

+xenapiDomainGetSchedulerType (virDomainPtr dom ATTRIBUTE_UNUSED, int *nparams)

+{

+    *nparams = 0;

+    return (char *)"credit";

+}

+

+static int

+xenapiDomainGetSchedulerParameters (virDomainPtr dom,

+                                    virSchedParameterPtr params ATTRIBUTE_UNUSED,

+                                    int *nparams ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static int

+xenapiDomainSetSchedulerParameters (virDomainPtr dom,

+                                    virSchedParameterPtr params ATTRIBUTE_UNUSED,

+                                    int nparams ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static int

+xenapiDomainMigratePrepare (virConnectPtr dconn,

+                            char **cookie ATTRIBUTE_UNUSED,

+                            int *cookielen ATTRIBUTE_UNUSED,

+                            const char *uri_in ATTRIBUTE_UNUSED,

+                            char **uri_out ATTRIBUTE_UNUSED,

+                            unsigned long flags ATTRIBUTE_UNUSED,

+                            const char *dname ATTRIBUTE_UNUSED,

+                            unsigned long resource ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(dconn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static int

+xenapiDomainMigratePerform (virDomainPtr dom,

+                            const char *cookie ATTRIBUTE_UNUSED,

+                            int cookielen ATTRIBUTE_UNUSED,

+                            const char *uri ATTRIBUTE_UNUSED,

+                            unsigned long flags ATTRIBUTE_UNUSED,

+                            const char *dname ATTRIBUTE_UNUSED,

+                            unsigned long resource ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static virDomainPtr

+xenapiDomainMigrateFinish (virConnectPtr dconn,

+                           const char *dname,

+                           const char *cookie ATTRIBUTE_UNUSED,

+                           int cookielen ATTRIBUTE_UNUSED,

+                           const char *uri ATTRIBUTE_UNUSED,

+                           unsigned long flags ATTRIBUTE_UNUSED)

+{

+    return xenapiDomainLookupByName (dconn, dname);

+}

+

+static int

+xenapiDomainBlockStats (virDomainPtr dom, const char *path ATTRIBUTE_UNUSED,

+                        struct _virDomainBlockStats *stats ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static int

+xenapiDomainInterfaceStats (virDomainPtr dom, const char *path ATTRIBUTE_UNUSED,

+                            struct _virDomainInterfaceStats *stats ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static int

+xenapiDomainBlockPeek (virDomainPtr dom, const char *path ATTRIBUTE_UNUSED,

+                       unsigned long long offset ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED,

+                       void *buffer ATTRIBUTE_UNUSED, unsigned int flags ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+/*

+* xenapiNodeGetFreeMemory

+*

+* provides the free memory available on the Node

+* Returns memory size on success or 0 in case of error

+*/

+static unsigned long long

+xenapiNodeGetFreeMemory (virConnectPtr conn)

+{

+    xen_host_metrics_set *xen_met_set;

+    unsigned long long freeMem=0;

+    xen_host_metrics_get_all(((struct _xenapiPrivate *)(conn->privateData))->session,

+                              &xen_met_set);

+    if (xen_met_set != NULL) {

+        if (!xen_host_metrics_get_memory_free(((struct _xenapiPrivate *)(conn->privateData))->session,

+                                              (int64_t *)&freeMem, xen_met_set->contents[0])) {

+            xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get host metrics - memory information",

+                                     __FILE__, __FUNCTION__, __LINE__);

+            freeMem=0;

+        }

+        xen_host_metrics_set_free(xen_met_set);

+    } else {

+        xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get host metrics",

+                                   __FILE__, __FUNCTION__, __LINE__);

+    }

+    return freeMem; 

+}

+

+/*

+* xenapiNodeGetCellsFreeMemory

+*

+*

+* Returns the number of entries filled in freeMems, or -1 in case of error.

+*/

+static int

+xenapiNodeGetCellsFreeMemory (virConnectPtr conn, unsigned long long *freeMems ATTRIBUTE_UNUSED,

+                              int startCell, int maxCells)

+{

+    if (maxCells >1 && startCell >0) {

+        xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+        return -1;

+    } else {

+        freeMems[0] = xenapiNodeGetFreeMemory(conn);

+     return 1;

+    }

+}

+

+

+static int

+xenapiDomainEventRegister (virConnectPtr conn,

+                           virConnectDomainEventCallback callback ATTRIBUTE_UNUSED,

+                           void *opaque ATTRIBUTE_UNUSED,

+                           void (*freefunc)(void *) ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static int

+xenapiDomainEventDeregister (virConnectPtr conn,

+                             virConnectDomainEventCallback callback ATTRIBUTE_UNUSED)

+{

+    xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static int

+xenapiNodeDeviceDettach (virNodeDevicePtr dev)

+{

+    xenapiSessionErrorHandler(dev->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static int

+xenapiNodeDeviceReAttach (virNodeDevicePtr dev)

+{

+    xenapiSessionErrorHandler(dev->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+static int

+xenapiNodeDeviceReset (virNodeDevicePtr dev)

+{

+    xenapiSessionErrorHandler(dev->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);

+    return -1;

+}

+

+/* The interface which we export upwards to libvirt.c. */

+static virDriver xenapiDriver = {

+    VIR_DRV_XENAPI,

+    "XenAPI",

+    xenapiOpen, /* open */

+    xenapiClose, /* close */

+    xenapiSupportsFeature, /* supports_feature */

+    xenapiType, /* type */

+    xenapiGetVersion, /* version */

+    NULL, /*getlibvirtVersion */

+    xenapiGetHostname, /* getHostname */

+    xenapiGetMaxVcpus, /* getMaxVcpus */

+    xenapiNodeGetInfo, /* nodeGetInfo */

+    xenapiGetCapabilities, /* getCapabilities */

+    xenapiListDomains, /* listDomains */

+    xenapiNumOfDomains, /* numOfDomains */

+    xenapiDomainCreateXML, /* domainCreateXML */

+    xenapiDomainLookupByID, /* domainLookupByID */

+    xenapiDomainLookupByUUID, /* domainLookupByUUID */

+    xenapiDomainLookupByName, /* domainLookupByName */

+    xenapiDomainSuspend, /* domainSuspend */

+    xenapiDomainResume, /* domainResume */

+    xenapiDomainShutdown, /* domainShutdown */

+    xenapiDomainReboot, /* domainReboot */

+    xenapiDomainDestroy, /* domainDestroy */

+    xenapiDomainGetOSType, /* domainGetOSType */

+    xenapiDomainGetMaxMemory, /* domainGetMaxMemory */

+    xenapiDomainSetMaxMemory, /* domainSetMaxMemory */

+    xenapiDomainSetMemory, /* domainSetMemory */

+    xenapiDomainGetInfo, /* domainGetInfo */

+    xenapiDomainSave, /* domainSave */

+    xenapiDomainRestore, /* domainRestore */

+    xenapiDomainCoreDump, /* domainCoreDump */

+    xenapiDomainSetVcpus, /* domainSetVcpus */

+    xenapiDomainPinVcpu, /* domainPinVcpu */

+    xenapiDomainGetVcpus, /* domainGetVcpus */

+    xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */

+    NULL, /* domainGetSecurityLabel */

+    NULL, /* nodeGetSecurityModel */

+    xenapiDomainDumpXML, /* domainDumpXML */

+    xenapiDomainXMLFromNative, /* domainXmlFromNative */

+    xenapiDomainXMLToNative, /* domainXmlToNative */

+    xenapiListDefinedDomains, /* listDefinedDomains */

+    xenapiNumOfDefinedDomains, /* numOfDefinedDomains */

+    xenapiDomainCreate, /* domainCreate */

+    xenapiDomainDefineXML, /* domainDefineXML */

+    xenapiDomainUndefine, /* domainUndefine */

+    xenapiDomainAttachDevice, /* domainAttachDevice */

+    NULL,

+    xenapiDomainDetachDevice, /* domainDetachDevice */

+    NULL,

+    xenapiDomainGetAutostart, /* domainGetAutostart */

+    xenapiDomainSetAutostart, /* domainSetAutostart */

+    xenapiDomainGetSchedulerType, /* domainGetSchedulerType */

+    xenapiDomainGetSchedulerParameters, /* domainGetSchedulerParameters */

+    xenapiDomainSetSchedulerParameters, /* domainSetSchedulerParameters */

+    xenapiDomainMigratePrepare, /* domainMigratePrepare */

+    xenapiDomainMigratePerform, /* domainMigratePerform */

+    xenapiDomainMigrateFinish, /* domainMigrateFinish */

+    xenapiDomainBlockStats, /* domainBlockStats */

+    xenapiDomainInterfaceStats, /* domainInterfaceStats */

+    NULL,

+    xenapiDomainBlockPeek, /* domainBlockPeek */

+    NULL, /* domainMemoryPeek */

+    xenapiNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */

+    xenapiNodeGetFreeMemory, /* getFreeMemory */

+    xenapiDomainEventRegister, /* domainEventRegister */

+    xenapiDomainEventDeregister, /* domainEventDeregister */

+    NULL, /* domainMigratePrepare2 */

+    NULL, /* domainMigrateFinish2 */

+    xenapiNodeDeviceDettach, /* nodeDeviceDettach */

+    xenapiNodeDeviceReAttach, /* nodeDeviceReAttach */

+    xenapiNodeDeviceReset, /* nodeDeviceReset */

+    NULL,

+    NULL,

+    NULL,

+    NULL,

+    NULL,

+    NULL,

+    NULL

+};

+

+/**

+ * xenapiRegister:

+ *

+ *

+ * Returns the driver priority or -1 in case of error.

+ */

+int

+xenapiRegister (void)

+{

+    return virRegisterDriver (&xenapiDriver);

+}

+

+/*

+* write_func

+* used by curl to read data from the server

+*/

+size_t

+write_func(void *ptr, size_t size, size_t nmemb, void *comms_)

+{

+    xen_comms *comms = comms_;

+    size_t n = size * nmemb;

+    #ifdef PRINT_XML

+        printf("\n\n---Result from server -----------------------\n");

+     printf("%s\n",((char*) ptr));

+     fflush(stdout);

+    #endif

+    return (size_t) (comms->func(ptr, n, comms->handle) ? n : 0);

+}

+

+/*

+* call_func

+* sets curl options, used with xen_session_login_with_password

+*/

+int

+call_func(const void *data, size_t len, void *user_handle,

+          void *result_handle, xen_result_func result_func)

+{

+    (void)user_handle;

+    #ifdef PRINT_XML

+

+        printf("\n\n---Data to server: -----------------------\n");

+        printf("%s\n",((char*) data));

+        fflush(stdout);

+    #endif

+    CURL *curl = curl_easy_init();

+    if (!curl) {

+      return -1;

+    }

+    xen_comms comms = {

+     .func = result_func,

+     .handle = result_handle

+    };

+    curl_easy_setopt(curl, CURLOPT_URL, url);

+    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);

+    //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

+    #ifdef CURLOPT_MUTE

+        curl_easy_setopt(curl, CURLOPT_MUTE, 1);

+    #endif

+    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);

+    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);

+    curl_easy_setopt(curl, CURLOPT_POST, 1);

+    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);

+    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);

+    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);

+    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);

+    CURLcode result = curl_easy_perform(curl);

+    curl_easy_cleanup(curl);

+    return result;

+}

+

+

+

+

diff -Nur ./libvirt_org/src/xenapi/xenapi_driver.h ./libvirt/src/xenapi/xenapi_driver.h

--- ./libvirt_org/src/xenapi/xenapi_driver.h    1970-01-01 01:00:00.000000000 +0100

+++ ./libvirt/src/xenapi/xenapi_driver.h  2010-02-18 15:37:49.000000000 +0000

@@ -0,0 +1,44 @@

+/*

+ * xenapi.c: Xen API driver.

+ * Copyright (C) 2009 Citrix Ltd.

+ * Sharadha Prabhakar <sharadha.prabhakar@citrix.com>

+ */

+

+

+#ifndef __VIR_XENAPI_H__

+#define __VIR_XENAPI_H__

+

+#include <xen/api/xen_common.h>

+#include <libxml/tree.h>

+

+//#define PRINT_XML

+#define RAW_UUID_BUFLEN  (16)

+#define LIBVIRT_MODELNAME_LEN  (32)

+

+

+extern int xenapiRegister (void);

+

+typedef struct

+{

+    xen_result_func func;

+    void *handle;

+} xen_comms;

+

+

+

+int

+call_func(const void *data, size_t len, void *user_handle,

+          void *result_handle, xen_result_func result_func);

+size_t

+write_func(void *ptr, size_t size, size_t nmemb, void *comms);

+

+/* xenAPI driver's private data structure */

+struct _xenapiPrivate {

+    xen_session *session;

+    void *handle;

+    char *uname;

+    char *pwd;

+    xen_api_version version;

+};

+

+#endif /* __VIR_XENAPI_H__ */