Devel
  Threads by month 
                
            - ----- 2025 -----
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2024 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2023 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2022 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2021 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2020 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2019 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2018 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2017 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2016 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2015 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2014 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2013 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2012 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2011 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2010 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2009 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2008 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2007 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2006 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2005 -----
 - December
 
February 2010
- 46 participants
 - 256 discussions
 
                    
                        Hello,
I would like to use -redir argument for qemu-kvm guest, but I can't find any
mention in docs about this option. Is there any way how to arrange port
redirection with libvirt? I can't use a bridge for networking, because I
can't use an IP address from host's range.
Thank you,
Jaromír Červenka
Official openSUSE community member
Web: http://www.cervajz.com/
Jabber: cervajz(a)cervajz.com
MSN: jara.cervenka(a)seznam.cz
Tel.: +420 607 592 687
Alt. e-mails:
jaromir.cervenka(a)opensuse.org,
jaromir.cervenka(a)speel.cz
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        How can I set viridian=1 using libvirt? Is it possible?
I haven't seen any reference about it on the xml format documentation
Best Regards,
  Diego Dias
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    18 Feb '10
                    
                        Resending patch 3/4 which didn't reach the first time seemingly.
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(a)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(a)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__ */
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    18 Feb '10
                    
                        diff -Nur ./libvirt_org/src/xenapi/xenapi_utils.c ./libvirt/src/xenapi/xenapi_utils.c
--- ./libvirt_org/src/xenapi/xenapi_utils.c     1970-01-01 01:00:00.000000000 +0100
+++ ./libvirt/src/xenapi/xenapi_utils.c   2010-02-18 16:26:52.000000000 +0000
@@ -0,0 +1,507 @@
+/*
+ * xenapi_utils.c: Xen API driver -- utils parts.
+ * Copyright (C) 2009 Citrix Ltd.
+ * Sharadha Prabhakar <sharadha.prabhakar(a)citrix.com>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#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"
+
+/* returns 'file' or 'block' for the storage type */
+int
+getStorageVolumeType(char *type)
+{
+    if((STREQ(type,"lvmoiscsi")) ||
+       (STREQ(type,"lvmohba")) ||
+       (STREQ(type,"lvm")) ||
+       (STREQ(type,"file")) ||
+       (STREQ(type,"iso")) ||
+       (STREQ(type,"ext")) ||
+       (STREQ(type,"nfs")))
+        return (int)VIR_STORAGE_VOL_FILE;
+    else if((STREQ(type,"iscsi")) ||
+       (STREQ(type,"equal")) ||
+       (STREQ(type,"hba")) ||
+       (STREQ(type,"cslg")) ||
+       (STREQ(type,"udev")) ||
+       (STREQ(type,"netapp")))
+        return (int)VIR_STORAGE_VOL_BLOCK;
+    return -1;
+}
+
+/* returns error description if any received from the server */
+char *
+returnErrorFromSession(xen_session *session)
+{
+    int i;
+    char *buf = NULL;
+    for (i=0; i<session->error_description_count-1; i++) {
+        if (buf==NULL) {
+            buf = (char *)realloc(buf,strlen(session->error_description[i])+1);
+            strcpy(buf,session->error_description[i]);
+        } else {
+            buf = (char *)realloc(buf,strlen(buf)+strlen(session->error_description[i])+2);
+            strcat(buf,":");
+            strcat(buf,session->error_description[i]);
+        }
+    }
+    return buf;
+}
+
+/* XenAPI error handler - internally calls libvirt error handler after clearing error
+flag in session */
+void xenapiSessionErrorHandler(virConnectPtr conn, virErrorNumber errNum,
+                               const char *buf, const char *filename, const char *func, size_t lineno)
+{
+    if (buf==NULL) {
+        char *ret=NULL;
+        ret = returnErrorFromSession(((struct _xenapiPrivate *)(conn->privateData))->session);
+        virReportErrorHelper (conn, VIR_FROM_XENAPI, errNum, filename, func, lineno, _("%s\n"), ret);
+        xen_session_clear_error(((struct _xenapiPrivate *)(conn->privateData))->session);
+        VIR_FREE(ret);
+    } else {
+        virReportErrorHelper (conn, VIR_FROM_XENAPI, errNum, filename, func, lineno, _("%s\n"), buf);
+    }
+}
+
+/* converts bitmap to string of the form '1,2...' */
+char *
+mapDomainPinVcpu(unsigned int vcpu, unsigned char *cpumap, int maplen)
+{
+    char buf[VIR_UUID_BUFLEN], mapstr[sizeof(cpumap_t) * 64];
+    char *ret=NULL;
+    int i, j;
+    mapstr[0] = 0;
+    for (i = 0; i < maplen; i++) {
+        for (j = 0; j < 8; j++) {
+            if (cpumap[i] & (1 << j)) {
+                snprintf(buf, sizeof(buf), "%d,", (8 * i) + j);
+                strcat(mapstr, buf);
+         }
+        }
+    }
+    mapstr[strlen(mapstr) - 1] = 0;
+    snprintf(buf, sizeof(buf), "%d", vcpu);
+    ret = strdup(mapstr);
+    return ret;
+}
+
+/* obtains the CPU bitmap from the string passed */
+void
+getCpuBitMapfromString(char *mask, unsigned char *cpumap, int maplen)
+{
+    int pos;
+    int max_bits = maplen * 8;
+    char *num = NULL;
+    bzero(cpumap, maplen);
+    num = strtok (mask, ",");
+    while (num != NULL) {
+        sscanf (num, "%d", &pos);
+        if (pos<0 || pos>max_bits-1)
+            printf ("number in str %d exceeds cpumap's max bits %d\n", pos, max_bits);
+        else
+            (cpumap)[pos/8] |= (1<<(pos%8));
+            num = strtok (NULL, ",");
+    }
+}
+
+
+/* mapping XenServer power state to Libvirt power state */
+virDomainState
+mapPowerState(enum xen_vm_power_state state)
+{
+    virDomainState virState;
+    switch (state) {
+        case (XEN_VM_POWER_STATE_HALTED):
+        case (XEN_VM_POWER_STATE_SUSPENDED):
+            virState = VIR_DOMAIN_SHUTOFF;
+            break;
+        case (XEN_VM_POWER_STATE_PAUSED):
+            virState = VIR_DOMAIN_PAUSED;
+            break;
+        case (XEN_VM_POWER_STATE_RUNNING):
+            virState = VIR_DOMAIN_RUNNING;
+            break;
+        case (XEN_VM_POWER_STATE_UNKNOWN):
+        case (XEN_VM_POWER_STATE_UNDEFINED):
+            virState = VIR_DOMAIN_NOSTATE;
+            break;
+        default:
+            virState = VIR_DOMAIN_NOSTATE;
+            break;
+    }
+    return virState;
+}
+
+/* Gets the value of the child for the current node passed */
+char *
+getXmlChildValue(xmlDocPtr doc, xmlNodePtr cur, const char *tag)
+{
+    char *key = NULL;
+    cur = cur->xmlChildrenNode;
+    while (cur != NULL) {
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)tag))){
+            cur = cur->xmlChildrenNode;
+            key = (char *)xmlNodeListGetString(doc,cur,1);
+        }
+        cur = cur->next;
+    }
+    return key;
+}
+
+/* allocate a flexible array and fill values(key,val) */
+int
+allocStringMap (xen_string_string_map **strings, char *key, char *val)
+{
+    int sz = ((*strings) == NULL)?0:(*strings)->size;
+    sz++;
+    *strings = realloc(*strings,sizeof(xen_string_string_map)+
+                       sizeof(xen_string_string_map_contents)*sz);
+    (*strings)->size = sz;
+    (*strings)->contents[sz-1].key = strdup(key);
+    (*strings)->contents[sz-1].val = strdup(val);
+    return 0;
+}
+
+/* create boot order string as understood by libvirt */
+void
+createXmlBootOrderString(char **order, char *key)
+{
+    int sz = ((*order)==NULL)?0:(strlen(*order)+1);
+    const char *temp=NULL;
+    if (strcmp(key,"fd")==0)
+        temp="a";
+    else if (strcmp(key,"hd")==0)
+        temp="c";
+    else if (strcmp(key,"cdrom")==0)
+        temp="d";
+    else if (strcmp(key,"network")==0)
+        temp="n";
+    if (temp!=NULL) {
+        *order = (char *)realloc(*order,sz+strlen(temp)+1);
+        if(sz==0) strcpy(*order,temp);
+        else strcat(*order,temp);
+    }
+}
+
+enum xen_on_normal_exit
+actionShutdownStringtoEnum(char *str)
+{
+    enum xen_on_normal_exit code = XEN_ON_NORMAL_EXIT_UNDEFINED;
+    if (STREQ(str, "destroy"))
+        code = XEN_ON_NORMAL_EXIT_DESTROY;
+    else if (STREQ(str, "restart"))
+        code = XEN_ON_NORMAL_EXIT_RESTART;
+    return code;
+}
+
+enum xen_on_crash_behaviour
+actionCrashStringtoEnum(char *str)
+{
+    enum xen_on_crash_behaviour code = XEN_ON_CRASH_BEHAVIOUR_UNDEFINED;
+    if (STREQ(str, "destroy"))
+        code = XEN_ON_CRASH_BEHAVIOUR_DESTROY;
+    else if (STREQ(str, "restart"))
+        code = XEN_ON_CRASH_BEHAVIOUR_RESTART;
+    else if (STREQ(str, "preserve"))
+        code = XEN_ON_CRASH_BEHAVIOUR_PRESERVE;
+    else if (STREQ(str, "rename-restart"))
+        code = XEN_ON_CRASH_BEHAVIOUR_RENAME_RESTART;
+    return code;
+}
+
+/* convert boot order string libvirt format to XenServer format */
+const char *
+mapXmlBootOrder(char c) {
+    switch(c) {
+        case 'a':
+         return "fd";
+     case 'c':
+         return "hd";
+     case 'd':
+         return "cdrom";
+     case 'n':
+         return "network";
+     default:
+         return NULL;
+    }
+}
+
+/* creates network intereface for VM */
+int
+createVifNetwork (virConnectPtr conn, xen_vm vm, char *device,
+                  char *bridge, char *mac)
+{
+    xen_vm xvm = NULL;
+    char *uuid = NULL;
+    xen_vm_get_uuid(((struct _xenapiPrivate *)(conn->privateData))->session, &uuid, vm);
+    if (uuid) {
+        if(!xen_vm_get_by_uuid(((struct _xenapiPrivate *)(conn->privateData))->session,
+                               &xvm, uuid))
+            return -1;
+        VIR_FREE(uuid);
+    }
+    xen_vm_record_opt *vm_opt = xen_vm_record_opt_alloc();
+    vm_opt->is_record = 0;
+    vm_opt->u.handle = xvm;
+    xen_network_set *net_set = NULL;
+    xen_network_record *net_rec = NULL;
+    int cnt=0;
+    if (xen_network_get_all(((struct _xenapiPrivate *)(conn->privateData))->session, &net_set)) {
+        for(cnt=0;cnt<(net_set->size);cnt++) {
+            if (xen_network_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,
+                                        &net_rec, net_set->contents[cnt])) {
+                if (STREQ(net_rec->bridge,bridge)) {
+                    break;
+                } else {
+                    xen_network_record_free(net_rec);
+                }
+            }
+        }
+    }
+    if ( (cnt<net_set->size) && net_rec) {
+        xen_network network = NULL;
+        xen_network_get_by_uuid(((struct _xenapiPrivate *)(conn->privateData))->session,
+                                    &network, net_rec->uuid);
+        xen_network_record_opt *network_opt = xen_network_record_opt_alloc();
+        network_opt->is_record = 0;
+        network_opt->u.handle = network;
+     xen_vif_record *vif_record = xen_vif_record_alloc();
+     vif_record->mac = mac;
+        vif_record->vm = vm_opt;
+        vif_record->network = network_opt;
+        xen_vif vif=NULL;
+
+     vif_record->other_config = xen_string_string_map_alloc(0);
+     vif_record->runtime_properties = xen_string_string_map_alloc(0);
+     vif_record->qos_algorithm_params = xen_string_string_map_alloc(0);
+     vif_record->device = strdup(device);
+     xen_vif_create(((struct _xenapiPrivate *)(conn->privateData))->session,
+                    &vif, vif_record);
+     if (vif!=NULL) {
+         xen_vif_free(vif);
+         xen_vif_record_free(vif_record);
+         xen_network_record_free(net_rec);
+         xen_network_set_free(net_set);
+         return 0;
+     }
+     xen_vif_record_free(vif_record);
+     xen_network_record_free(net_rec);
+    }
+    if (net_set!=NULL) xen_network_set_free(net_set);
+    return -1;
+}
+
+/* Create a VM record from the XML description */
+int
+createVMRecordFromXml (virConnectPtr conn, const char *xmlDesc,
+                       xen_vm_record **record, xen_vm *vm)
+{
+    xmlDocPtr doc;
+    xmlNodePtr cur,child,temp;
+    doc = xmlParseMemory(xmlDesc,strlen(xmlDesc));
+    if (doc == NULL) {
+        xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"", __FILE__, __FUNCTION__, __LINE__);
+        return -1;
+    }
+    cur = xmlDocGetRootElement(doc);
+    if (cur == NULL) {
+        xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"", __FILE__, __FUNCTION__, __LINE__);
+        xmlFreeDoc(doc);
+        return -1;
+    }
+    if (xmlStrcmp(cur->name, (const xmlChar *) "domain")) {
+        xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"root node not domain", __FILE__, __FUNCTION__, __LINE__);
+        xmlFreeDoc(doc);
+        return -1;
+    }
+    *record = xen_vm_record_alloc();
+    char *name = getXmlChildValue(doc,cur,"name");
+    (*record)->name_label = strdup(name);
+    child = cur->xmlChildrenNode;
+    while (child!=NULL) {
+        if ((!xmlStrcmp(child->name, (const xmlChar *)"os"))) {
+            char *ostype = getXmlChildValue(doc,child,"type");
+            if (ostype!=NULL) {
+                if (STREQ(ostype,"hvm")) {
+                    (*record)->hvm_boot_policy = strdup("BIOS order");
+                     temp = child;
+                     child = child->xmlChildrenNode;
+                     char *boot_order = NULL;
+                     while (child != NULL) {
+                         if ((!xmlStrcmp(child->name, (const xmlChar *)"boot"))){
+                             xmlChar *key;
+                             key = xmlGetProp(child, (const xmlChar *)"dev");
+                             if (key!=NULL) {
+                                 createXmlBootOrderString(&boot_order,(char *)key);
+                                 xmlFree(key);
+                             }
+                         }
+                         child = child->next;
+                     }
+                     if (boot_order!=NULL) {
+                    xen_string_string_map *hvm_boot_params=NULL;
+                 allocStringMap(&hvm_boot_params, (char *)"order",boot_order);
+                 //int size = sizeof(xen_string_string_map) +
+                 //          (hvm_boot_params->size * sizeof(xen_string_string_map_contents));
+                 //(*record)->hvm_boot_params = (xen_string_string_map *) malloc(size);
+                 //memcpy((char *)(*record)->hvm_boot_params, (char *)hvm_boot_params, size);
+                         (*record)->hvm_boot_params = hvm_boot_params;
+                 VIR_FREE(boot_order);
+                         //freeStringMap(hvm_boot_params);
+                     }
+                child = temp;
+           } else if (STREQ(ostype,"linux")) {
+                (*record)->pv_bootloader = strdup("pygrub");
+                char *kernel = getXmlChildValue(doc,child,"kernel");
+                if (kernel != NULL){
+                    (*record)->pv_kernel = kernel;
+                    //strcpy((*record)->pv_kernel,kernel);
+                 //free(kernel);
+                }
+                char *initrd = getXmlChildValue(doc,child,"initrd");
+                if (initrd != NULL) {
+                    (*record)->pv_ramdisk = initrd;//(char *)malloc(strlen(initrd)+1);
+                    //strcpy((*record)->pv_ramdisk,initrd);
+                    //free(initrd);
+                }
+                char *cmdline = getXmlChildValue(doc,child,"cmdline");
+                if (cmdline != NULL) {
+                    (*record)->pv_args = cmdline; //(char *)malloc(strlen(cmdline)+1);
+                      //strcpy((*record)->pv_args,cmdline);
+                 //free(cmdline);
+                }
+                (*record)->hvm_boot_params = xen_string_string_map_alloc(0);
+           }
+           VIR_FREE(ostype);
+          }
+     }
+     child = child->next;
+    }
+    char *bootload_args =  getXmlChildValue(doc,cur,"bootloader_args");
+    if (bootload_args!=NULL) {
+        (*record)->pv_bootloader_args =bootload_args; //(char *)malloc(strlen(bootload_args)+1);
+     //strcpy((*record)->pv_bootloader_args,bootload_args);
+     //free(bootload_args);
+    }
+    char *memory = getXmlChildValue(doc,cur,"memory");
+    if (memory!=NULL) {
+        int64_t static_max=0;
+        static_max = atoll(memory);
+        (*record)->memory_static_max = static_max * 1024;
+        VIR_FREE(memory);
+    }
+    char *curmemory = getXmlChildValue(doc,cur,"currentmemory");
+    if (curmemory!=NULL) {
+        int64_t dy_max=0;
+        dy_max = atoll(curmemory);
+        (*record)->memory_dynamic_max = dy_max * 1024;
+        VIR_FREE(curmemory);
+    } else {
+        (*record)->memory_dynamic_max = (*record)->memory_static_max;
+    }
+    char *vcpu =  getXmlChildValue(doc, cur, "vcpu");
+    if (vcpu!=NULL) {
+        (*record)->vcpus_max = atoll(vcpu);
+     (*record)->vcpus_at_startup =  atoll(vcpu);
+     VIR_FREE(vcpu);
+    }
+    char *on_poweroff = getXmlChildValue(doc,cur,"on_poweroff");
+    if (on_poweroff!=NULL) {
+        (*record)->actions_after_shutdown = actionShutdownStringtoEnum(on_poweroff);
+        VIR_FREE(on_poweroff);
+    }
+    char *on_reboot = getXmlChildValue(doc,cur,"on_reboot");
+    if (on_reboot!=NULL) {
+        (*record)->actions_after_reboot = actionShutdownStringtoEnum(on_reboot);
+        VIR_FREE(on_reboot);
+    }
+    char *on_crash = getXmlChildValue(doc,cur,"on_crash");
+    if (on_crash!=NULL) {
+        (*record)->actions_after_crash = actionCrashStringtoEnum(on_crash);
+        VIR_FREE(on_crash);
+    }
+    temp = cur;
+    cur = cur->xmlChildrenNode;
+    xen_string_string_map *strings=NULL;
+    while (cur != NULL) {
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"features"))){
+            for (child=cur->children;child!=NULL;child=child->next) {
+                allocStringMap(&strings,(char *)child->name,(char *)"true");
+            }
+        }
+        cur = cur->next;
+    }
+    cur = temp;
+    if (strings!=NULL) {
+        //int size = sizeof(xen_string_string_map)+ sizeof(xen_string_string_map_contents)*strings->size;
+        (*record)->platform = strings; //(xen_string_string_map *)malloc(size);
+        //memcpy((void *)(*record)->platform,(void *)strings,size);
+    }
+    (*record)->vcpus_params = xen_string_string_map_alloc(0);
+    (*record)->other_config = xen_string_string_map_alloc(0);
+    (*record)->last_boot_cpu_flags = xen_string_string_map_alloc(0);
+    (*record)->xenstore_data = xen_string_string_map_alloc(0);
+    (*record)->hvm_shadow_multiplier = 1.000;
+    if (!xen_vm_create(((struct _xenapiPrivate *)(conn->privateData))->session,
+                        vm, *record)) {
+        xmlFreeDoc(doc);
+        xenapiSessionErrorHandler(conn,VIR_ERR_INTERNAL_ERROR ,NULL, __FILE__, __FUNCTION__, __LINE__);
+        return -1;
+    }
+    cur = cur->xmlChildrenNode;
+    int device_number=0;
+    xmlChar *bridge=NULL,*mac=NULL;
+    while (cur != NULL) {
+        if ((!xmlStrcmp(cur->name, (const xmlChar *)"interface"))){
+            for (child=cur->children;child!=NULL;child=child->next) {
+                if ((!xmlStrcmp(child->name, (const xmlChar *)"source"))) {
+                    bridge = xmlGetProp(child, (const xmlChar *)"bridge");
+                }
+                if ((!xmlStrcmp(child->name, (const xmlChar *)"mac"))) {
+                    mac = xmlGetProp(child, (const xmlChar *)"address");
+                }
+            }
+         if (mac!=NULL && bridge!=NULL) {
+             char device[NETWORK_DEVID_SIZE]="\0";
+           sprintf(device,"%d",device_number);
+             createVifNetwork(conn, *vm, device, (char *)bridge, (char *)mac);
+             xmlFree(bridge);
+             device_number++;
+         }
+        }
+     cur = cur->next;
+    }
+    xmlFreeDoc(doc);
+    return 0;
+}
+
diff -Nur ./libvirt_org/src/xenapi/xenapi_utils.h ./libvirt/src/xenapi/xenapi_utils.h
--- ./libvirt_org/src/xenapi/xenapi_utils.h     1970-01-01 01:00:00.000000000 +0100
+++ ./libvirt/src/xenapi/xenapi_utils.h   2010-02-18 16:28:10.000000000 +0000
@@ -0,0 +1,94 @@
+/*
+ * xenapi_utils.h: Xen API driver -- utils header
+ * Copyright (C) 2009 Citrix Ltd.
+ * Sharadha Prabhakar <sharadha.prabhakar(a)citrix.com>
+ */
+
+#ifndef _VIR_XENAPI_UTILS_
+#define _VIR_XENAPI_UTILS_
+
+#include <stdio.h>
+#include <string.h>
+#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 <xen/dom0_ops.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"
+
+#define NETWORK_DEVID_SIZE  (10)
+
+typedef uint64_t cpumap_t;
+
+void getCpuBitMapfromString(char *mask, unsigned char *cpumap, int maplen);
+
+int getStorageVolumeType(char *type);
+
+char *returnErrorFromSession(xen_session *session);
+
+void xenapiSessionErrorHandler(virConnectPtr conn, virErrorNumber errNum,
+                               const char *buf, const char *filename, const char *func, size_t lineno);
+
+
+virDomainState
+mapPowerState(enum xen_vm_power_state state);
+
+char *
+mapDomainPinVcpu(unsigned int vcpu, unsigned char *cpumap, int maplen);
+
+char *
+getXmlChildValue(xmlDocPtr doc, xmlNodePtr cur, const char *tag);
+
+int
+createVMRecordFromXml (virConnectPtr conn, const char *xmlDesc,
+                       xen_vm_record **record, xen_vm *vm);
+
+int
+allocStringMap (xen_string_string_map **strings, char *key, char *val);
+
+void
+createXmlBootOrderString(char **order, char *key);
+
+enum xen_on_normal_exit
+actionShutdownStringtoEnum(char *str);
+
+enum xen_on_crash_behaviour
+actionCrashStringtoEnum(char *str);
+
+int
+createVifNetwork(virConnectPtr conn, xen_vm vm, char *device,
+                 char *bridge, char *mac);
+
+const char *
+mapXmlBootOrder(char c);
+
+
+
+
+
+
+
+#endif //_VIR_XENAPI_UTILS_
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    18 Feb '10
                    
                        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(a)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(a)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__ */
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    18 Feb '10
                    
                        diff -ur ./libvirt_org/src/libvirt.c ./libvirt/src/libvirt.c
--- ./libvirt_org/src/libvirt.c 2010-02-17 17:38:08.000000000 +0000
+++ ./libvirt/src/libvirt.c     2010-02-18 12:21:43.000000000 +0000
@@ -64,6 +64,9 @@
 #ifdef WITH_ESX
 #include "esx/esx_driver.h"
 #endif
+#ifdef WITH_XENAPI
+#include "xenapi/xenapi_driver.h"
+#endif
 #endif
 #define VIR_FROM_THIS VIR_FROM_NONE
@@ -357,6 +360,7 @@
     virDriverLoadModule("openvz");
     virDriverLoadModule("vbox");
     virDriverLoadModule("esx");
+    virDriverLoadModule("xenapi");
     virDriverLoadModule("remote");
 #else
 #ifdef WITH_TEST
@@ -377,6 +381,9 @@
 #ifdef WITH_ESX
     if (esxRegister() == -1) return -1;
 #endif
+#ifdef WITH_XENAPI
+    if (xenapiRegister () == -1) return -1;
+#endif
 #ifdef WITH_REMOTE
     if (remoteRegister () == -1) return -1;
 #endif
@@ -1035,6 +1042,10 @@
         if (STRCASEEQ(type, "Remote"))
             *typeVer = remoteVersion();
 #endif
+#if WITH_XENAPI
+        if (STRCASEEQ(type, "XenAPI"))
+            *typeVer = LIBVIR_VERSION_NUMBER;
+#endif
         if (*typeVer == 0) {
             virLibConnError(NULL, VIR_ERR_NO_SUPPORT, type);
             goto error;
diff -ur ./libvirt_org/src/driver.h ./libvirt/src/driver.h
--- ./libvirt_org/src/driver.h  2010-02-17 17:38:08.000000000 +0000
+++ ./libvirt/src/driver.h      2010-02-18 10:45:54.000000000 +0000
@@ -27,6 +27,7 @@
     VIR_DRV_ONE = 9,
     VIR_DRV_ESX = 10,
     VIR_DRV_PHYP = 11,
+    VIR_DRV_XENAPI = 12
 } virDrvNo;
diff -ur ./libvirt_org/include/libvirt/virterror.h ./libvirt/include/libvirt/virterror.h
--- ./libvirt_org/include/libvirt/virterror.h   2010-02-17 17:37:51.000000000 +0000
+++ ./libvirt/include/libvirt/virterror.h       2010-02-18 12:17:54.000000000 +0000
@@ -69,6 +69,7 @@
     VIR_FROM_PHYP,      /* Error from IBM power hypervisor */
     VIR_FROM_SECRET,    /* Error from secret storage */
     VIR_FROM_CPU,       /* Error from CPU driver */
+    VIR_FROM_XENAPI     /* Error from XenAPI */
 } virErrorDomain;
diff -ur ./libvirt_org/src/util/virterror.c ./libvirt/src/util/virterror.c
--- ./libvirt_org/src/util/virterror.c  2010-02-17 17:38:14.000000000 +0000
+++ ./libvirt/src/util/virterror.c      2010-02-18 12:13:08.000000000 +0000
@@ -85,6 +85,9 @@
         case VIR_FROM_XEN:
             dom = "Xen ";
             break;
+        case VIR_FROM_XENAPI:
+            dom = "XenAPI ";
+            break;
         case VIR_FROM_XML:
             dom = "XML ";
             break;
Only in ./libvirt/src: xenapi
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        These patches rebase my previously posted virtio-serial patches, add support for
max_ports and vectors, and allow multiple virtio-serial devices to be used. I
wasn't going to bother with the latter, however it turns out this can be useful
if the user wants more than 31 virtserialports.
N.B. These apply on top of 2 previously posted patches. Specifically "Fix whitespace in domain.rng" and "Remove unused functions from domain_conf".
                    
                  
                  
                          
                            
                            4
                            
                          
                          
                            
                            13
                            
                          
                          
                            
    
                          
                        
                    18 Feb '10
                    
                        ---
 src/remote/remote_driver.c |   37 ++++++++++++++++++++++++++++++++++---
 1 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 13534ce..7f92fd0 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -154,6 +154,7 @@ struct private_data {
     virMutex lock;
 
     int sock;                   /* Socket. */
+    int errsock;                /* Socket connected to remote stderr */
     int watch;                  /* File handle watch */
     pid_t pid;                  /* PID of tunnel process */
     int uses_tls;               /* TLS enabled on socket? */
@@ -783,6 +784,7 @@ doRemoteOpen (virConnectPtr conn,
     case trans_ext: {
         pid_t pid;
         int sv[2];
+        int errsock[2];
 
         /* Fork off the external process.  Use socketpair to create a private
          * (unnamed) Unix domain socket to the child process so we don't have
@@ -794,14 +796,21 @@ doRemoteOpen (virConnectPtr conn,
             goto failed;
         }
 
+        if (socketpair (PF_UNIX, SOCK_STREAM, 0, errsock) == -1) {
+            virReportSystemError(errno, "%s",
+                                 _("unable to create socket pair"));
+            goto failed;
+        }
+
         if (virExec((const char**)cmd_argv, NULL, NULL,
-                    &pid, sv[1], &(sv[1]), NULL,
+                    &pid, sv[1], &(sv[1]), &(errsock[1]),
                     VIR_EXEC_CLEAR_CAPS) < 0)
             goto failed;
 
         /* Parent continues here. */
         close (sv[1]);
         priv->sock = sv[0];
+        priv->errsock = errsock[0];
         priv->pid = pid;
 
         /* Do not set 'is_secure' flag since we can't guarentee
@@ -827,6 +836,12 @@ doRemoteOpen (virConnectPtr conn,
         goto failed;
     }
 
+    if ((priv->errsock != -1) && virSetNonBlock(priv->errsock) < 0) {
+        virReportSystemError(errno, "%s",
+                             _("unable to make socket non-blocking"));
+        goto failed;
+    }
+
     if (pipe(wakeupFD) < 0) {
         virReportSystemError(errno, "%s",
                              _("unable to make pipe"));
@@ -939,6 +954,9 @@ doRemoteOpen (virConnectPtr conn,
 
  failed:
     /* Close the socket if we failed. */
+    if (priv->errsock >= 0)
+        close(priv->errsock);
+
     if (priv->sock >= 0) {
         if (priv->uses_tls && priv->session) {
             gnutls_bye (priv->session, GNUTLS_SHUT_RDWR);
@@ -986,6 +1004,7 @@ remoteAllocPrivateData(virConnectPtr conn)
     priv->localUses = 1;
     priv->watch = -1;
     priv->sock = -1;
+    priv->errsock = -1;
 
     return priv;
 }
@@ -1408,6 +1427,7 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv)
         sasl_dispose (&priv->saslconn);
 #endif
     close (priv->sock);
+    close (priv->errsock);
 
 #ifndef WIN32
     if (priv->pid > 0) {
@@ -7785,12 +7805,23 @@ remoteIOReadBuffer(virConnectPtr conn,
                 if (errno == EWOULDBLOCK)
                     return 0;
 
+                char errout[1024] = "\0";
+                if (priv->errsock) {
+                    recv(priv->errsock, errout, sizeof(errout), 0);
+                }
+
                 virReportSystemError(errno,
-                                     "%s", _("cannot recv data"));
+                                     _("cannot recv data: %s"), errout);
+
             } else {
+                char errout[1024] = "\0";
+                if (priv->errsock) {
+                    recv(priv->errsock, errout, sizeof(errout), 0);
+                }
+
                 errorf (in_open ? NULL : conn,
                         VIR_ERR_SYSTEM_ERROR,
-                        "%s", _("server closed connection"));
+                        _("server closed connection: %s"), errout);
             }
             return -1;
         }
-- 
1.6.5.2
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            2
                            
                          
                          
                            
    
                          
                        
                    
                    
                        Remove virDomainDevicePCIAddressEqual and virDomainDeviceDriveAddressEqual,
which are defined but not used anywhere.
* src/conf/domain_conf.[ch]: Remove virDomainDevicePCIAddressEqual and
                             virDomainDeviceDriveAddressEqual.
---
 src/conf/domain_conf.c |   24 ------------------------
 src/conf/domain_conf.h |    4 ----
 2 files changed, 0 insertions(+), 28 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7f3df78..df35209 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -972,30 +972,6 @@ static int virDomainDeviceInfoFormat(virBufferPtr buf,
 
 #ifndef PROXY
 
-int virDomainDevicePCIAddressEqual(virDomainDevicePCIAddressPtr a,
-                                   virDomainDevicePCIAddressPtr b)
-{
-    if (a->domain == b->domain &&
-        a->bus    == b->bus &&
-        a->slot   == b->slot &&
-        a->function == b->function)
-        return 1;
-
-    return 0;
-}
-
-
-int virDomainDeviceDriveAddressEqual(virDomainDeviceDriveAddressPtr a,
-                                     virDomainDeviceDriveAddressPtr b)
-{
-    if (a->controller == b->controller &&
-        a->bus == b->bus &&
-        a->unit == b->unit)
-        return 1;
-
-    return 0;
-}
-
 
 static int
 virDomainDevicePCIAddressParseXML(xmlNodePtr node,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d9b2f28..307d9b5 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -743,10 +743,6 @@ void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def);
 void virDomainVideoDefFree(virDomainVideoDefPtr def);
 void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
 void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
-int virDomainDevicePCIAddressEqual(virDomainDevicePCIAddressPtr a,
-                                   virDomainDevicePCIAddressPtr b);
-int virDomainDeviceDriveAddressEqual(virDomainDeviceDriveAddressPtr a,
-                                     virDomainDeviceDriveAddressPtr b);
 int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info,
                                   int type);
 int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr);
-- 
1.6.6
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            3
                            
                          
                          
                            
    
                          
                        
                    
                    
                        * src/qemu/qemu_driver.c: Fix typo in comment
---
 src/qemu/qemu_driver.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8766ca2..b4728e5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2724,7 +2724,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
     }
 
     /*
-     * Normally PCI addresses are assigned inhe virDomainCreate
+     * Normally PCI addresses are assigned in the virDomainCreate
      * or virDomainDefine methods. We might still need to assign
      * some here to cope with the question of upgrades. Regardless
      * we also need to populate the PCi address set cache for later
-- 
1.6.6
                    
                  
                  
                          
                            
                            3
                            
                          
                          
                            
                            2