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@citrix.com>
+*/
+
+#include <config.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <libxml/uri.h>
+#include <xen_internal.h>
+#include <libxml/parser.h>
+#include <curl/curl.h>
+#include <xen/api/xen_common.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_all.h>
+#include <xen/api/xen_vm_metrics.h>
+
+#include "libvirt_internal.h"
+#include "libvirt/libvirt.h"
+#include "virterror_internal.h"
+#include "datatypes.h"
+#include "xenapi_driver.h"
+#include "util.h"
+#include "uuid.h"
+#include "memory.h"
+#include "driver.h"
+#include "buf.h"
+#include "xenapi_utils.h"
+
+char *url;
+
+/*
+*XenapiOpen
+*
+*Authenticates and creates a session with the
server
+*Return VIR_DRV_OPEN_SUCCESS on success, else
VIR_DRV_OPEN_ERROR
+*/
+static virDrvOpenStatus
+xenapiOpen (virConnectPtr conn, virConnectAuthPtr
auth ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED)
+{
+ char *user,*passwd;
+ char delims[]=":";
+ xen_session *session;
+ struct _xenapiPrivate *privP;
+
+ if
(!STREQ(conn->uri->scheme,"XenAPI")) {
+
xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED ,"Check URI format:
'XenAPI://user:password@server'", __FILE__, __FUNCTION__, __LINE__);
+ return
VIR_DRV_OPEN_ERROR;
+ }
+ if
(conn->uri->server==NULL) {
+ xenapiSessionErrorHandler(conn,
VIR_ERR_AUTH_FAILED ,"Server name not in URI", __FILE__,
__FUNCTION__, __LINE__);
+ return
VIR_DRV_OPEN_ERROR;
+ }
+
+ user =
strtok(conn->uri->user,delims);
+ passwd = strtok(NULL,delims);
+
+
+
+ url = (char
*)malloc(strlen("https://")+strlen(conn->uri->server)+1);
+
strcpy(url,"https://");
+
strcat(url,conn->uri->server);
+
url[strlen("https://")+strlen(conn->uri->server)]='\0';
+
+ xmlInitParser();
+ xmlKeepBlanksDefault(0);
+ xen_init();
+
curl_global_init(CURL_GLOBAL_ALL);
+
+ session =
xen_session_login_with_password( call_func, NULL, user, passwd,
xen_api_latest_version);
+
+ if ( session != NULL &&
session->ok ) {
+ privP =
malloc(sizeof(struct _xenapiPrivate));
+
privP->session = session;
+
conn->privateData = privP;
+ return
VIR_DRV_OPEN_SUCCESS;
+ } else {
+
xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED ,"", __FILE__,
__FUNCTION__, __LINE__);
+ return
VIR_DRV_OPEN_ERROR;
+ }
+}
+
+/*
+* xenapiClose:
+*
+* Returns 0 on successful session logout
+*
+*/
+static int
+xenapiClose (virConnectPtr conn)
+{
+ xen_session_logout(((struct
_xenapiPrivate *)(conn->privateData))->session);
+ VIR_FREE(conn->privateData);
+ return 0;
+}
+
+/*
+*
+* xenapiSupportsFeature
+*
+* Returns 0
+*/
+static int
+xenapiSupportsFeature (virConnectPtr conn
ATTRIBUTE_UNUSED, int feature)
+{
+ switch (feature) {
+ case
VIR_DRV_FEATURE_MIGRATION_V2:
+ case VIR_DRV_FEATURE_MIGRATION_P2P:
+ default:
+ return
0;
+ }
+}
+
+/*
+* xenapiType:
+*
+*
+*Returns name of the driver
+*/
+static const char *
+xenapiType (virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ return "XenAPI";
+}
+
+
+/*
+* xenapiGetVersion:
+*
+* Gets the version of XenAPI
+*
+*/
+static int
+xenapiGetVersion (virConnectPtr conn
ATTRIBUTE_UNUSED, unsigned long *hvVer)
+{
+ *hvVer = 1;
+ return 0;
+}
+
+
+/*
+* xenapiGetHostname:
+*
+*
+* Returns the hostname on success, or NULL on
failure
+*/
+static char *
+xenapiGetHostname (virConnectPtr conn)
+{
+ char *result;
+ xen_host host;
+
+ if
(!(xen_session_get_this_host(((struct _xenapiPrivate
*)(conn->privateData))->session, &host,
+
((struct
_xenapiPrivate *)(conn->privateData))->session))) {
+ if
(!(((struct _xenapiPrivate *)(conn->privateData))->session->ok))
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__, __FUNCTION__,
__LINE__);
+ else
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,"Unable to find
host", __FILE__, __FUNCTION__, __LINE__);
+ return
NULL;
+ }
+ xen_host_get_hostname(((struct
_xenapiPrivate *)(conn->privateData))->session, &result, host);
+ xen_host_free(host);
+ return result;
+}
+
+
+/*
+* xenapiGetMAxVcpus:
+*
+*
+* Returns a hardcoded value for Maximum VCPUS
+*/
+static int
+xenapiGetMaxVcpus (virConnectPtr conn ATTRIBUTE_UNUSED,
const char *type ATTRIBUTE_UNUSED)
+{
+ /* this is hardcoded for
simplicity and set to a resonable value compared
+ to the actual
value */
+ return 16;
+}
+
+
+/*
+* xenapiNodeGetInfo:
+*
+*
+* Returns Node details on success or else -1
+*/
+static int
+xenapiNodeGetInfo (virConnectPtr conn,
virNodeInfoPtr info)
+{
+ int64_t memory,mhz;
+ xen_host_cpu_set *host_cpu_set;
+ xen_host_cpu host_cpu;
+ xen_host_metrics_set
*xen_met_set;
+ char *modelname;
+ info->nodes = 1;
+ info->threads = 1;
+ info->sockets = 1;
+
+ if
(xen_host_metrics_get_all(((struct _xenapiPrivate
*)(conn->privateData))->session,
+
&xen_met_set)) {
+ xen_host_metrics_get_memory_total(((struct
_xenapiPrivate *)(conn->privateData))->session,
+
&memory, xen_met_set->contents[0]);
+
info->memory = (unsigned
long)(memory/1024);
+
xen_host_metrics_set_free(xen_met_set);
+ } else {
+
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR ,"Unable to get
host metric Information",
+
__FILE__, __FUNCTION__, __LINE__);
+ return
-1;
+ }
+ if
(xen_host_cpu_get_all(((struct _xenapiPrivate
*)(conn->privateData))->session,
+
&host_cpu_set))
{
+ host_cpu
= host_cpu_set->contents[0];
+
xen_host_cpu_get_modelname(((struct _xenapiPrivate
*)(conn->privateData))->session,
+
&modelname,
host_cpu);
+ strncpy(info->model,
modelname, LIBVIRT_MODELNAME_LEN-2);
+
info->model[LIBVIRT_MODELNAME_LEN-1]='\0';
+ xen_host_cpu_get_speed(((struct
_xenapiPrivate *)(conn->privateData))->session,
+
&mhz, host_cpu);
+
info->mhz = (unsigned
long)mhz;
+
info->cpus = host_cpu_set->size;
+
info->cores = host_cpu_set->size;
+
+
xen_host_cpu_set_free(host_cpu_set);
+
free(modelname);
+ return 0;
+ }
+ xenapiSessionErrorHandler(conn,
VIR_ERR_INTERNAL_ERROR ,"Unable to get Host CPU set",
+
__FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+
+/*
+* xenapiGetCapabilities:
+*
+*
+* Returns capabilities as an XML string
+*/
+static char *
+xenapiGetCapabilities (virConnectPtr conn
ATTRIBUTE_UNUSED)
+{
+ virBuffer buf =
VIR_BUFFER_INITIALIZER;
+ virBufferAddLit(&buf,
"<capabilities>\n");
+ virBufferAddLit(&buf,
"<host>\n");
+ virBufferAddLit(&buf,
" <cpu></cpu>\n");
+ virBufferAddLit(&buf,
"</host>");
+ virBufferAddLit(&buf,
"<guest>\n");
+ virBufferAddLit(&buf,
"<os_type>hvm</os_type>\n");
+ virBufferAddLit(&buf,
"<arch>\n");
+ virBufferAddLit(&buf,
"<domain type='xenapi'></domain>\n");
+ virBufferAddLit(&buf,
"</arch>\n");
+ virBufferAddLit(&buf,
"</guest>\n");
+ virBufferAddLit(&buf,
"</capabilities>\n");
+ return
virBufferContentAndReset(&buf);
+}
+
+/*
+* xenapiListDomains
+*
+* Collects the list of active domains, and store
their ID in @maxids
+* Returns the number of domain found or -1 in case
of error
+*/
+static int
+xenapiListDomains (virConnectPtr conn, int *ids,
int maxids)
+{
+ /* vm.list */
+ int i,list;
+ xen_host host;
+ xen_vm_set *result=NULL;
+ if
(xen_session_get_this_host(((struct _xenapiPrivate
*)(conn->privateData))->session, &host,
+
((struct _xenapiPrivate *)(conn->privateData))->session)) {
+
xen_host_get_resident_vms(((struct _xenapiPrivate
*)(conn->privateData))->session, &result, host);
+
xen_host_free(host);
+ } else {
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__,
__FUNCTION__, __LINE__);
+ }
+ if (result != NULL) {
+ for (
i=0; (i < (result->size)) && (i<maxids) ; i++ ) {
+
int64_t t0;
+
xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session,
&t0, result->contents[i]);
+
ids[i] = (int)(t0 & 0xffffffff);
+ }
+ list = result->size;
+ xen_vm_set_free(result);
+ return
list;
+ }
+ return -1;
+}
+
+/*
+* xenapiNumOfDomains
+*
+*
+* Returns the number of domains found or -1 in case
of error
+*/
+static int
+xenapiNumOfDomains (virConnectPtr conn)
+{
+ /* #(vm.list) */
+ xen_vm_set *result=NULL;
+ xen_host host=NULL;
+ int numDomains=-1;
+
+
xen_session_get_this_host(((struct _xenapiPrivate
*)(conn->privateData))->session, &host,
+
((struct _xenapiPrivate *)(conn->privateData))->session);
+ if ( host!=NULL ) {
+
xen_host_get_resident_vms(((struct _xenapiPrivate
*)(conn->privateData))->session, &result, host);
+ if (
result != NULL) {
+
numDomains = result->size;
+
xen_vm_set_free(result);
+ }
+ xen_host_free(host);
+ }
+ if (!(((struct _xenapiPrivate
*)(conn->privateData))->session->ok))
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return numDomains;
+}
+
+/*
+* xenapiDomainCreateXML
+*
+* Launches a new domain based on the XML description
+* Returns the domain pointer or NULL in case of
error
+*/
+static virDomainPtr
+xenapiDomainCreateXML (virConnectPtr conn,
+
const char *xmlDesc, ATTRIBUTE_UNUSED unsigned int flags)
+{
+ xen_vm_record *record=NULL;
+ xen_vm vm=NULL;
+ virDomainPtr domP=NULL;
+ createVMRecordFromXml( conn,
xmlDesc, &record, &vm);
+ if (record!=NULL) {
+ unsigned
char raw_uuid[RAW_UUID_BUFLEN];
+
virUUIDParse(record->uuid,raw_uuid);
+ if (vm!=NULL) {
+
if (xen_vm_start(((struct _xenapiPrivate *)(conn->privateData))->session,
+
vm, false, false)) {
+
domP = virGetDomain(conn,
record->name_label, raw_uuid);
+
xen_vm_free(vm);
+ }
+
else
+
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ }
+
xen_vm_record_free(record);
+ }
+ else
+
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return domP;
+}
+
+/*
+* xenapiDomainLookupByID
+*
+*
+* Returns a valid domain pointer of the domain with
ID same as the one passed
+* or NULL in case of error
+*/
+static virDomainPtr
+xenapiDomainLookupByID (virConnectPtr conn, int id)
+{
+ int i;
+ int64_t domID;
+ char *uuid;
+ xen_host host;
+ xen_vm_set *result;
+ xen_vm_record *record;
+ unsigned char
raw_uuid[RAW_UUID_BUFLEN];
+ virDomainPtr domP=NULL;
+
+
xen_session_get_this_host(((struct _xenapiPrivate
*)(conn->privateData))->session, &host,
+
((struct _xenapiPrivate *)(conn->privateData))->session);
+ if (host!=NULL &&
((struct _xenapiPrivate *)(conn->privateData))->session->ok)
{
+
xen_host_get_resident_vms(((struct _xenapiPrivate
*)(conn->privateData))->session, &result, host);
+ if (
result !=NULL ) {
+
for( i=0; i < (result->size); i++) {
+
xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session,
&domID, result->contents[i]);
+
if ( domID == id ) {
+
xen_vm_get_record(((struct _xenapiPrivate
*)(conn->privateData))->session,
+
&record, result->contents[i]);
+
xen_vm_get_uuid(((struct _xenapiPrivate *)(conn->privateData))->session,
&uuid, result->contents[i]);
+
virUUIDParse(uuid,raw_uuid);
+
domP =
virGetDomain(conn, record->name_label, raw_uuid);
+
if (domP!=NULL) {
+
int64_t domid=-1;
+
xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session,
+
&domid, result->contents[i]);
+
domP->id = domid;
+
}
+
xen_uuid_free(uuid);
+
xen_vm_record_free(record);
+
}
+
}
+
xen_vm_set_free(result);
+ } else {
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN ,NULL, __FILE__,
__FUNCTION__, __LINE__);
+ }
+ xen_host_free(host);
+ } else {
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__,
__FUNCTION__, __LINE__);
+ }
+ return domP;
+}
+
+/*
+* xenapiDomainLookupByUUID
+*
+* Returns the domain pointer of domain with
matching UUID
+* or -1 in case of error
+*/
+static virDomainPtr
+xenapiDomainLookupByUUID (virConnectPtr conn,
+
const unsigned char *uuid)
+{
+ /* vm.get_by_uuid */
+ xen_vm vm;
+ xen_vm_record *record;
+ unsigned char
raw_uuid[RAW_UUID_BUFLEN];
+ virDomainPtr domP=NULL;
+ if (xen_vm_get_by_uuid(((struct
_xenapiPrivate *)(conn->privateData))->session,
+
&vm, (char *)uuid)) {
+
xen_vm_get_record(((struct _xenapiPrivate
*)(conn->privateData))->session,
+
&record, vm);
+ if
(record != NULL) {
+
virUUIDParse((char *)uuid,raw_uuid);
+
domP = virGetDomain(conn, record->name_label,
raw_uuid);
+
xen_vm_record_free(record);
+ }
+ else
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN ,NULL, __FILE__, __FUNCTION__,
__LINE__);
+
xen_vm_free(vm);
+ } else
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN ,NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return domP;
+}
+
+/*
+* xenapiDomainLookupByName
+*
+* Returns the domain pointer of domain with
matching name
+* or -1 in case of error
+*/
+static virDomainPtr
+xenapiDomainLookupByName (virConnectPtr conn,
+
const char *name)
+{
+ /* vm.get_by_name_label */
+ xen_vm_set *vms=NULL;
+ xen_vm vm;
+ char *uuid=NULL;
+ unsigned char
raw_uuid[RAW_UUID_BUFLEN];
+ virDomainPtr domP=NULL;
+
+
xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(conn->privateData))->session,
+
&vms,
(char *)name);
+ if (vms!=NULL &&
vms->size!=0)
{
+ vm =
vms->contents[0];
+ xen_vm_get_uuid(((struct
_xenapiPrivate *)(conn->privateData))->session,
+
&uuid, vm);
+ if
(uuid!=NULL) {
+ virUUIDParse(uuid,raw_uuid);
+ domP =
virGetDomain(conn, name, raw_uuid);
+
if (domP != NULL) {
+
int64_t domid=-1;
+
xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session,
+
&domid, vm);
+
domP->id = domid;
+
xen_uuid_free(uuid);
+
xen_vm_set_free(vms);
+
return domP;
+
} else {
+
xen_uuid_free(uuid);
+
xen_vm_set_free(vms);
+
if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok)) {
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL,
__FILE__, __FUNCTION__, __LINE__);
+
}
+
return NULL;
+
}
+ }
+ }
+ if (!(((struct _xenapiPrivate
*)(conn->privateData))->session->ok)) {
+
xenapiSessionErrorHandler(conn,VIR_ERR_NO_DOMAIN,NULL,__FILE__,__FUNCTION__,
__LINE__);
+ } else {
+
xenapiSessionErrorHandler(conn,VIR_ERR_NO_DOMAIN,"Domain name not
found",__FILE__,__FUNCTION__, __LINE__);
+ }
+ return NULL;
+}
+
+/*
+* xenapiDomainSuspend
+*
+* a VM is paused
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainSuspend (virDomainPtr dom)
+{
+ /* vm.pause() */
+ xen_vm vm;
+ xen_vm_set *vms;
+ if
(!xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name)) {
+
xenapiSessionErrorHandler(dom->conn,VIR_ERR_NO_DOMAIN,NULL,__FILE__,__FUNCTION__,
__LINE__);
+ return
-1;
+ }
+ vm = vms->contents[0];
+ if (!xen_vm_pause(((struct
_xenapiPrivate *)(dom->conn->privateData))->session, vm)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(vms);
+ return
-1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+/*
+* xenapiDomainResume
+*
+* Resumes a VM
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainResume (virDomainPtr dom)
+{
+ /* vm.unpause() */
+ xen_vm vm;
+ xen_vm_set *vms;
+ if
(!xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return
-1;
+ }
+ if (vms!=NULL &&
vms->size!=0) {
+ vm =
vms->contents[0];
+ if
(!xen_vm_unpause(((struct _xenapiPrivate
*)(dom->conn->privateData))->session, vm)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(vms);
+
return
-1;
+
}
+
xen_vm_set_free(vms);
+ }
+ return 0;
+}
+
+/*
+* xenapiDomainShutdown
+*
+* shutsdown a VM
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainShutdown (virDomainPtr dom)
+{
+ /* vm.clean_shutdown */
+ xen_vm vm;
+ xen_vm_set *vms;
+
if(!xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return
-1;
+ }
+ vm = vms->contents[0];
+ if
(!xen_vm_clean_shutdown(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
vm)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(vms);
+ return
-1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+/*
+* xenapiDomainReboot
+*
+* Reboots a VM
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainReboot (virDomainPtr dom, unsigned int
flags ATTRIBUTE_UNUSED)
+{
+ /* vm.clean_reboot */
+ xen_vm vm;
+ struct xen_vm_set *vms;
+ xen_vm_get_by_name_label(((struct
_xenapiPrivate *)(dom->conn->privateData))->session,
+
&vms, dom->name);
+ if (vms==NULL ||
vms->size==0) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__,
__LINE__);
+ return
-1;
+ }
+ vm = vms->contents[0];
+ if
(!xen_vm_clean_reboot(((struct _xenapiPrivate
*)(dom->conn->privateData))->session, vm)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(vms);
+ return
-1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+/*
+* xenapiDomaindestroy
+*
+* A VM is hard shutdown
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainDestroy (virDomainPtr dom)
+{
+ /* vm.hard_shutdown */
+ xen_vm vm;
+ struct xen_vm_set *vms;
+
xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name);
+ if (vms==NULL ||
vms->size==0) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return
-1;
+ }
+ vm = vms->contents[0];
+ if
(!xen_vm_hard_shutdown(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
vm)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(vms);
+ return
-1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+/*
+* xenapiDomainGetOSType
+*
+*
+* Returns OS version on success or NULL in case of
error
+*/
+static char *
+xenapiDomainGetOSType (virDomainPtr dom)
+{
+ /* vm.get_os-version */
+ int i;
+ xen_vm vm;
+ char *os_version=NULL;
+ xen_vm_record *record;
+ xen_string_string_map *result;
+ char
uuid[VIR_UUID_STRING_BUFLEN];
+
virUUIDFormat(dom->uuid,uuid);
+ if (xen_vm_get_by_uuid(((struct
_xenapiPrivate *)(dom->conn->privateData))->session,
+
&vm, uuid)) {
+
xen_vm_get_record(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&record, vm);
+ if
(record!=NULL) {
+
xen_vm_guest_metrics_get_os_version(((struct _xenapiPrivate
*)(dom->conn->privateData))->session, &result,
+
record->guest_metrics->u.handle);
+
if (result != NULL) {
+
for (i=0; i<(result->size);
i++) {
+
if (STREQ(result->contents[i].key, "distro")) {
+
if
(STREQ(result->contents[i].val, "windows")) {
+
os_version = strdup(result->contents[i].val);
+
} else {
+
os_version = strdup("linux");
+
}
+
}
+
}
+
xen_string_string_map_free(result);
+ } else
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_OS, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_record_free(record);
+ } else
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_free(vm);
+ }
+ else
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ if ( os_version == NULL ) {
+
os_version = strdup("unknown");
+ }
+ return os_version;
+}
+
+/*
+* xenapiDomainGetMaxMemory
+*
+* Returns maximum static memory for VM on success
+* or 0 in case of error
+*/
+static unsigned long
+xenapiDomainGetMaxMemory (virDomainPtr dom)
+{
+ int64_t mem_static_max=0;
+ xen_vm vm;
+ xen_vm_set *vms;
+
xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name);
+ if (vms != NULL &&
vms->size!=0) {
+ /*
vm.get_memory_static_max */
+ vm = vms->contents[0];
+
xen_vm_get_memory_static_max(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&mem_static_max, vm);
+ xen_vm_set_free(vms);
+ return
(unsigned long)(mem_static_max/1024);
+ } else {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return 0;
+ }
+}
+
+/*
+* xenapiDomainSetMaxMemory
+*
+* Sets maximum static memory for VM on success
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainSetMaxMemory (virDomainPtr dom,
unsigned long memory)
+{
+ /* vm.set_memory_static_max */
+ xen_vm vm;
+ struct xen_vm_set *vms;
+
xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name);
+ if (vms!=NULL &&
vms->size!=0) {
+ vm =
vms->contents[0];
+ if
(!(xen_vm_set_memory_static_max(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
vm, memory))) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(vms);
+
return -1;
+ }
+
xen_vm_set_free(vms);
+ } else {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return
-1;
+ }
+ return 0;
+}
+
+static int
+xenapiDomainSetMemory (virDomainPtr dom, unsigned
long memory ATTRIBUTE_UNUSED)
+{
+ /* XenAPI doesn't allow this
function */
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "",
__FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainGetInfo:
+*
+* Fills a structure with domain information
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainGetInfo (virDomainPtr dom,
virDomainInfoPtr info)
+{
+ int64_t
maxmem=0,memory=0,vcpu=0;
+ xen_vm vm;
+ xen_vm_record *record;
+ xen_vm_set *vms;
+ info->cpuTime = 0; /* CPU
time is not advertised */
+ if
(xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name)) {
+ vm =
vms->contents[0];
+
xen_vm_get_memory_static_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+
&maxmem, vm);
+
info->maxMem = (maxmem/1024);
+ enum xen_vm_power_state
state = XEN_VM_POWER_STATE_UNKNOWN;
+
xen_vm_get_power_state(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+
&state, vm);
+
info->state =
mapPowerState(state);
+ xen_vm_get_record(((struct
_xenapiPrivate *)(dom->conn->privateData))->session,
+
&record, vm);
+ if (record!=NULL)
{
+
xen_vm_metrics_get_memory_actual(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&memory, record->metrics->u.handle);
+
info->memory = (memory/1024);
+
xen_vm_record_free(record);
+
}
+
xen_vm_get_vcpus_max(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vcpu, vm);
+
info->nrVirtCpu =
vcpu;
+ xen_vm_set_free(vms);
+ return
0;
+ }
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainSave
+*
+* suspends a VM
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainSave (virDomainPtr dom, const char *to
ATTRIBUTE_UNUSED)
+{
+ int ret_code = -1;
+ ret_code =
xenapiDomainSuspend(dom);
+ return ret_code;
+}
+
+/*
+* xenapiDomainRestore
+*
+* Resumes a VM
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainRestore (virConnectPtr conn, const char
*from ATTRIBUTE_UNUSED)
+{
+ /* resume from : NI */
+ xen_vm_set *result=NULL;
+ xen_host host=NULL;
+ xen_vm_record *record = NULL;
+ unsigned char
raw_uuid[RAW_UUID_BUFLEN];
+ virDomainPtr domP=NULL;
+ int ret_code=-1;
+
+
xen_session_get_this_host(((struct _xenapiPrivate
*)(conn->privateData))->session, &host,
+
((struct _xenapiPrivate *)(conn->privateData))->session);
+ if ( host!=NULL ) {
+
xen_host_get_resident_vms(((struct _xenapiPrivate
*)(conn->privateData))->session, &result, host);
+ if (
result != NULL ) {
+
xen_vm_get_record(((struct _xenapiPrivate
*)(conn->privateData))->session,
+
&record, result->contents[0]);
+
if (record!=NULL)
{
+
virUUIDParse(record->uuid,raw_uuid);
+
domP =
virGetDomain(conn, record->name_label, raw_uuid);
+
if (domP!=NULL)
+
ret_code =
xenapiDomainResume(domP);
+
else
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_record_free(record);
+ }
+
xen_vm_set_free(result);
+ }
+
xen_host_free(host);
+ }
+ if (!(((struct _xenapiPrivate
*)(conn->privateData))->session->ok))
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return ret_code;
+}
+
+static int
+xenapiDomainCoreDump (virDomainPtr dom, const char
*to ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED)
+{
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainSetVcpus
+*
+* Sets the VCPUs on the domain
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainSetVcpus (virDomainPtr dom, unsigned
int nvcpus)
+{
+
+ /* vm.set_vcpus_max */
+ xen_vm vm;
+ xen_vm_set *vms;
+
xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name);
+ if (vms!=NULL &&
vms->size!=0) {
+ vm =
vms->contents[0];
+ if
(xen_vm_set_vcpus_number_live(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
vm, (int64_t)nvcpus)) {
+
xen_vm_set_free(vms);
+ return
0;
+ }
+ }
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainPinVcpu
+*
+* Dynamically change the real CPUs which can be
allocated to a virtual CPU
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainPinVcpu (virDomainPtr dom, unsigned int
vcpu,
+
unsigned char *cpumap, int maplen)
+{
+ char *value;
+ xen_vm vm;
+ xen_vm_set *vms;
+ xen_vm_get_by_name_label(((struct
_xenapiPrivate *)(dom->conn->privateData))->session,
+
&vms, dom->name);
+ if (vms!=NULL &&
vms->size!=0) {
+ vm =
vms->contents[0];
+ value =
mapDomainPinVcpu(vcpu, cpumap, maplen);
+ xen_vm_remove_from_vcpus_params(((struct
_xenapiPrivate *)(dom->conn->privateData))->session, vm, (char
*)"mask");
+ if
(xen_vm_add_to_vcpus_params(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
vm, (char *)"mask", value)) {
+
xen_vm_set_free(vms);
+ return
0;
+ }
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ }
+ xenapiSessionErrorHandler(dom->conn,
VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainGetVcpus
+*
+* Gets Vcpu information
+* Return number of structures filled on success or
-1 in case of error
+*/
+static int
+xenapiDomainGetVcpus (virDomainPtr dom,
+
virVcpuInfoPtr info, int maxinfo,
+
unsigned char *cpumaps, int maplen)
+{
+
+ xen_vm_set *vms=NULL;
+ xen_vm vm=NULL;
+ xen_string_string_map
*vcpu_params=NULL;
+ int nvcpus=0,cpus=0,i;
+ virDomainInfoPtr domInfo;
+ virNodeInfo nodeInfo;
+ virVcpuInfoPtr ifptr;
+ char *mask=NULL;
+ if((cpumaps!=NULL) &&
(maplen < 1))
+ return
-1;
+ domInfo =(struct _virDomainInfo
*) malloc(sizeof(struct _virDomainInfo));
+ if
(virDomainGetInfo(dom,domInfo)==0) {
+ nvcpus =
domInfo->nrVirtCpu;
+ free(domInfo);
+ } else {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, "Couldn't
fetch Domain Information",
+
__FILE__, __FUNCTION__, __LINE__);
+ return
-1;
+ }
+ if (
virNodeGetInfo(dom->conn,&nodeInfo)==0)
+ cpus =
nodeInfo.cpus;
+ else {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, "Couldn't
fetch Node Information",
+
__FILE__, __FUNCTION__, __LINE__);
+ return
-1;
+ }
+ if(nvcpus > maxinfo) nvcpus =
maxinfo;
+
+ if (cpumaps != NULL)
+
memset(cpumaps, 0, maxinfo * maplen);
+
+ if
(!xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return
-1;
+ }
+ vm = vms->contents[0];
+ if
(!xen_vm_get_vcpus_params(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vcpu_params, vm)) {
+ xenapiSessionErrorHandler(dom->conn,
VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return
-1;
+ }
+ for (i=0;
i<vcpu_params->size; i++) {
+ if
(STREQ(vcpu_params->contents[i].key,"mask")) {
+ mask =
strdup(vcpu_params->contents[i].val);
+ }
+ }
+ for (i=0,ifptr=info
;i<nvcpus; i++,ifptr++) {
+
ifptr->number = i;
+ ifptr->state =
VIR_VCPU_RUNNING;
+ ifptr->cpuTime = 0;
+ ifptr->cpu = 0;
+ if (mask !=NULL)
+ getCpuBitMapfromString(mask,VIR_GET_CPUMAP(cpumaps,maplen,i),maplen);
+ }
+ return i;
+}
+
+/*
+* xenapiDomainGetMaxVcpus
+*
+*
+* Returns maximum number of Vcpus on success or -1
in case of error
+*/
+static int
+xenapiDomainGetMaxVcpus (virDomainPtr dom)
+{
+ xen_vm vm;
+ xen_vm_set *vms;
+ int64_t maxvcpu=0;
+ enum xen_vm_power_state state;
+
+ if
(xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name)) {
+ vm =
vms->contents[0];
+
xen_vm_get_power_state(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&state, vm);
+ if(state
== XEN_VM_POWER_STATE_RUNNING) {
+
xen_vm_get_vcpus_max(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&maxvcpu, vm);
+ } else {
+ maxvcpu
= xenapiGetMaxVcpus(dom->conn, NULL);
+ }
+ xen_vm_set_free(vms);
+ return (int)maxvcpu;
+ }
+ xenapiSessionErrorHandler(dom->conn,
VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainDumpXML
+*
+*
+* Returns XML string of the domain configuration on
success or -1 in case of error
+*/
+static char *
+xenapiDomainDumpXML (virDomainPtr dom,
ATTRIBUTE_UNUSED int flags)
+{
+ virBuffer buf =
VIR_BUFFER_INITIALIZER;
+ char
uuid_string[VIR_UUID_STRING_BUFLEN];
+ xen_vm vm=NULL;
+ xen_vm_set *vms;
+ xen_string_string_map
*result=NULL;
+
+ xen_vm_get_by_name_label(((struct
_xenapiPrivate *)(dom->conn->privateData))->session,
+
&vms, dom->name);
+ if (vms==NULL ||
vms->size==0) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__,
__LINE__);
+ return
NULL;
+ }
+
+ vm =
vms->contents[0];
+ virBufferAddLit(&buf,
"<domain type='xenapi'>\n");
+ virBufferEscapeString(&buf,
" <name>%s</name>\n",
"testVM");
+ virUUIDFormat(dom->uuid,uuid_string);
+ virBufferEscapeString(&buf,
" <uuid>%s</uuid>\n",uuid_string);
+
+
+ virBufferAddLit(&buf,
" <os>\n");
+ char *boot_policy=NULL;
+
xen_vm_get_hvm_boot_policy(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&boot_policy,
vm);
+ if (STREQ(boot_policy,"BIOS
order"))
{
+
virBufferAddLit(&buf, "
<type>hvm</type>\n");
+
xen_vm_get_hvm_boot_params(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+
&result, vm);
+ if
(result!=NULL) {
+
int i;
+
for (i=0; i<(result->size); i++) {
+
if (STREQ(result->contents[i].key,"order")) {
+
int j=0;
+
while(result->contents[i].val[j]!='\0') {
+
virBufferEscapeString(&buf,
" <boot dev='%s'
/>\n",
+
mapXmlBootOrder(result->contents[i].val[j]));
+
j++;
+
}
+
}
+ }
+
xen_string_string_map_free(result);
+ }
+
VIR_FREE(boot_policy);
+ } else {
+
virBufferAddLit(&buf, "
<type>linux</type>\n");
+
virBufferAddLit(&buf, "
<loader>pygrub</loader>\n");
+ char
*value=NULL;
+
xen_vm_get_pv_kernel(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&value, vm);
+ if
(!STREQ(value,"")) {
+
virBufferEscapeString(&buf,"
<kernel>%s</kernel>\n",value);
+
VIR_FREE(value);
+ }
+
xen_vm_get_pv_ramdisk(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&value, vm);
+ if
(!STREQ(value,"")) {
+
virBufferEscapeString(&buf,"
<initrd>%s</initrd>\n",value);
+
VIR_FREE(value);
+ }
+
xen_vm_get_pv_args(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&value, vm);
+ if
(!STREQ(value,"")) {
+
virBufferEscapeString(&buf,"
<cmdline>%s</cmdline>\n",value);
+
VIR_FREE(value);
+ }
+ VIR_FREE(boot_policy);
+ }
+ virBufferAddLit(&buf,
" </os>\n");
+ virBufferAddLit(&buf,
" <bootloader>pygrub</bootloader>\n");
+ char *val=NULL;
+
xen_vm_get_pv_bootloader_args(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&val,
vm);
+ if (!STREQ(val,"")) {
+ virBufferEscapeString(&buf,"
<bootloader_args>%s</bootloader_args>\n",val);
+ VIR_FREE(val);
+ }
+ unsigned long memory=0;
+ memory =
xenapiDomainGetMaxMemory(dom);
+
virBufferVSprintf(&buf,"
<memory>%lu</memory>\n",memory);
+ int64_t dynamic_mem=0;
+ if
(xen_vm_get_memory_dynamic_max(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&dynamic_mem, vm)) {
+
virBufferVSprintf(&buf,"
<currentmemory>%lld</currentmemory>\n",(dynamic_mem/1024));
+ } else {
+
virBufferVSprintf(&buf,"
<currentmemory>%lu</currentmemory>\n",memory);
+ }
+
virBufferVSprintf(&buf,"
<vcpu>%d</vcpu>\n",xenapiDomainGetMaxVcpus(dom));
+ enum xen_on_normal_exit action;
+ if (xen_vm_get_actions_after_shutdown(((struct
_xenapiPrivate *)(dom->conn->privateData))->session,
+
&action, vm)) {
+
virBufferEscapeString(&buf,"
<on_poweroff>%s</on_poweroff>\n",xen_on_normal_exit_to_string(action));
+ }
+ if
(xen_vm_get_actions_after_reboot(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&action, vm)) {
+
virBufferEscapeString(&buf,"
<on_reboot>%s</on_reboot>\n",xen_on_normal_exit_to_string(action));
+ }
+ enum xen_on_crash_behaviour
crash;
+ if
(xen_vm_get_actions_after_crash(((struct _xenapiPrivate
*)(dom->conn->privateData))->session, &crash, vm)) {
+
virBufferEscapeString(&buf,"
<on_crash>%s</on_crash>\n",xen_on_crash_behaviour_to_string(crash));
+ }
+ xen_vm_get_platform(((struct
_xenapiPrivate *)(dom->conn->privateData))->session,
+
&result,
vm);
+ if (result!=NULL)
{
+ int i;
+
virBufferAddLit(&buf, " <features>\n");
+ for(i=0; i<
(result->size); i++) {
+ if
(STREQ(result->contents[i].val,"true")) {
+
virBufferVSprintf(&buf,"
<%s/>\n",result->contents[i].key);
+ }
+ }
+
virBufferAddLit(&buf, " </features>\n");
+
xen_string_string_map_free(result);
+ }
+ struct xen_vif_set
*vif_set=NULL;
+ xen_vm_get_vifs(((struct
_xenapiPrivate *)(dom->conn->privateData))->session,
+
&vif_set, vm);
+ if (vif_set) {
+ int i;
+ xen_vif vif;
+ xen_vif_record
*vif_rec=NULL;
+ xen_network network;
+ char *bridge=NULL;
+ for (i=0;
i<vif_set->size; i++) {
+
virBufferAddLit(&buf, " <interface
type='bridge'>\n");
+ vif =
vif_set->contents[i];
+
xen_vif_get_network(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&network, vif);
+ if
(network!=NULL)
{
+
xen_network_get_bridge(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&bridge, network);
+
if (bridge!=NULL) {
+
virBufferEscapeString(&buf,"
<source bridge='%s' />\n",bridge);
+
VIR_FREE(bridge);
+
}
+
xen_network_free(network);
+ }
+
xen_vif_get_record(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vif_rec, vif);
+
if (vif_rec!=NULL) {
+
virBufferEscapeString(&buf,"
<mac address='%s' />\n", vif_rec->mac);
+
xen_vif_record_free(vif_rec);
+ }
+
virBufferAddLit(&buf, " </interface>\n");
+ }
+ xen_vif_set_free(vif_set);
+ }
+ virBufferAddLit(&buf,
"</domain>");
+ if (vms) xen_vm_set_free(vms);
+ return
virBufferContentAndReset(&buf);
+}
+
+static char *
+xenapiDomainXMLFromNative(virConnectPtr conn,
+
const char *format ATTRIBUTE_UNUSED,
+
const char *config ATTRIBUTE_UNUSED,
+
unsigned int flags ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(conn,
VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return NULL;
+}
+
+
+static char *
+xenapiDomainXMLToNative(virConnectPtr conn,
+
const char *format ATTRIBUTE_UNUSED,
+
const char *xmlData ATTRIBUTE_UNUSED,
+
unsigned int flags ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(conn,
VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return NULL;
+}
+
+/*
+* xenapiListDefinedDomains
+*
+* list the defined but inactive domains, stores the
pointers to the names in @names
+* Returns number of names provided in the array or
-1 in case of error
+*/
+static int
+xenapiListDefinedDomains (virConnectPtr conn, char
**const names,
+
int maxnames)
+{
+ int i,j=0,doms;
+ xen_vm_set *result;
+ xen_vm_record *record;
+ xen_vm_get_all(((struct
_xenapiPrivate *)(conn->privateData))->session, &result);
+ if (result != NULL) {
+ for
(i=0; i< (result->size) && j< maxnames; i++) {
+
xen_vm_get_record(((struct _xenapiPrivate
*)(conn->privateData))->session,
+
&record, result->contents[i]);
+ if (
record!=NULL ) {
+
if ( record->is_a_template == 0 ) {
+
char *usenames;
+
usenames = strdup(record->name_label);
+
names[j++]=usenames;
+
}
+
xen_vm_record_free(record);
+ } else
{
+
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get VM
record", __FILE__, __FUNCTION__, __LINE__);
+
xen_vm_set_free(result);
+
return -1;
+
}
+ }
+ doms=j;
+
xen_vm_set_free(result);
+ return
doms;
+ }
+ xenapiSessionErrorHandler(conn,
VIR_ERR_NO_DEVICE, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiNumOfDefinedDomains
+*
+* Provides the number of defined but inactive
domains
+* Returns number of domains found on success or -1
in case of error
+*/
+static int
+xenapiNumOfDefinedDomains (virConnectPtr conn)
+{
+ xen_vm_set *result;
+ xen_vm_record *record;
+ int DomNum=0,i;
+ xen_vm_get_all(((struct
_xenapiPrivate *)(conn->privateData))->session, &result);
+ if ( result != NULL) {
+ for (
i=0; i< (result->size); i++ ) {
+
xen_vm_get_record(((struct _xenapiPrivate
*)(conn->privateData))->session,
+
&record, result->contents[i]);
+
if (record==NULL && !(((struct _xenapiPrivate
*)(conn->privateData))->session->ok)) {
+
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(result);
+
return -1;
+
}
+
if (record->is_a_template == 0)
+
DomNum++;
+
xen_vm_record_free(record);
+ }
+
xen_vm_set_free(result);
+ return
DomNum;
+ }
+ xenapiSessionErrorHandler(conn,
VIR_ERR_NO_DEVICE, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainCreate
+*
+* starts a VM
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainCreate (virDomainPtr dom)
+{
+ xen_vm_set *vms;
+ xen_vm vm;
+ xen_vm_get_by_name_label(((struct
_xenapiPrivate *)(dom->conn->privateData))->session,
+
&vms, dom->name);
+ if (vms!=NULL &&
vms->size!=0) {
+ vm =
vms->contents[0];
+ if
(!xen_vm_start(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
vm, false, false)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(vms);
+
return -1;
+ }
+
xen_vm_set_free(vms);
+ } else {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return
-1;
+ }
+ return 0;
+}
+
+/*
+* xenapiDomainDefineXML
+*
+* Defines a domain from the given XML but does not
start it
+* Returns 0 on success or -1 in case of error
+*/
+static virDomainPtr
+xenapiDomainDefineXML (virConnectPtr conn, const
char *xml)
+{
+ xen_vm_record *record=NULL;
+ xen_vm vm=NULL;
+ virDomainPtr domP=NULL;
+ if(createVMRecordFromXml( conn,
xml, &record, &vm)!=0) {
+ if
(!(((struct _xenapiPrivate *)(conn->privateData))->session->ok))
+
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ else
+
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get VM
information from XML",
+
__FILE__, __FUNCTION__, __LINE__);
+ return
NULL;
+ }
+ if (record!=NULL) {
+ unsigned
char raw_uuid[RAW_UUID_BUFLEN];
+
virUUIDParse(record->uuid,raw_uuid);
+ domP = virGetDomain(conn,
record->name_label, raw_uuid);
+ if
(domP==NULL && !(((struct _xenapiPrivate
*)(conn->privateData))->session->ok))
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_record_free(record);
+ }
+ else if (vm!=NULL)
+
xen_vm_free(vm);
+ return domP;
+}
+
+/*
+* xenapiDomainUndefine
+*
+* destroys a domain
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainUndefine (virDomainPtr dom)
+{
+ struct xen_vm_set *vms;
+ xen_vm vm;
+ if
(!xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return
-1;
+ }
+ vm = vms->contents[0];
+ if (!xen_vm_destroy(((struct
_xenapiPrivate *)(dom->conn->privateData))->session, vm)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(vms);
+ return
-1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+static int
+xenapiDomainAttachDevice (virDomainPtr dom, const
char *xml ATTRIBUTE_UNUSED)
+{
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "",
__FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainDetachDevice (virDomainPtr dom, const
char *xml ATTRIBUTE_UNUSED)
+{
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "",
__FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainGetAutostart
+*
+* Provides a boolean value indicating whether the domain
configured
+* to be automatically started when the host machine
boots
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainGetAutostart (virDomainPtr dom, int
*autostart)
+{
+ int i,flag=0;
+ xen_vm_set *vms;
+ xen_vm vm;
+ xen_string_string_map *result;
+
if(!xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return
-1;
+ }
+ vm = vms->contents[0];
+ if
(!xen_vm_get_other_config(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&result, vm)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(vms);
+ return
-1;
+ }
+ for (i=0; i <
result->size; i++) {
+ if
(STREQ(result->contents[i].key, "auto_poweron")) {
+ flag=1;
+ if
(STREQ(result->contents[i].val, "true"))
+
*autostart = 1;
+ else
+
*autostart = 0;
+ }
+ }
+ xen_vm_set_free(vms);
+
xen_string_string_map_free(result);
+ if (flag==0) return -1;
+ return 0;
+}
+
+/*
+* xenapiDomainSetAutostart
+*
+* Configure the domain to be automatically started
when the host machine boots
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainSetAutostart (virDomainPtr dom, int
autostart)
+{
+ xen_vm_set *vms;
+ xen_vm vm;
+ char *value;
+ if
(!xen_vm_get_by_name_label(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
&vms, dom->name)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return
-1;
+ }
+ vm = vms->contents[0];
+
xen_vm_remove_from_other_config(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
vm, (char *)"auto_poweron");
+ if (autostart==1)
+ value =
(char *)"true";
+ else
+ value =
(char *)"false";
+ if
(!xen_vm_add_to_other_config(((struct _xenapiPrivate
*)(dom->conn->privateData))->session,
+
vm, (char *)"auto_poweron", value)) {
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__,
__FUNCTION__, __LINE__);
+
xen_vm_set_free(vms);
+ return
-1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+static char *
+xenapiDomainGetSchedulerType (virDomainPtr dom
ATTRIBUTE_UNUSED, int *nparams)
+{
+ *nparams = 0;
+ return (char
*)"credit";
+}
+
+static int
+xenapiDomainGetSchedulerParameters (virDomainPtr
dom,
+
virSchedParameterPtr params ATTRIBUTE_UNUSED,
+
int *nparams ATTRIBUTE_UNUSED)
+{
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "",
__FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainSetSchedulerParameters (virDomainPtr
dom,
+
virSchedParameterPtr params ATTRIBUTE_UNUSED,
+
int nparams ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dom->conn,
VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainMigratePrepare (virConnectPtr dconn,
+
char **cookie ATTRIBUTE_UNUSED,
+
int *cookielen ATTRIBUTE_UNUSED,
+
const char *uri_in ATTRIBUTE_UNUSED,
+
char **uri_out ATTRIBUTE_UNUSED,
+
unsigned long flags ATTRIBUTE_UNUSED,
+
const char *dname ATTRIBUTE_UNUSED,
+
unsigned long resource ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dconn,
VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainMigratePerform (virDomainPtr dom,
+
const char *cookie ATTRIBUTE_UNUSED,
+
int cookielen ATTRIBUTE_UNUSED,
+
const char *uri ATTRIBUTE_UNUSED,
+
unsigned long flags ATTRIBUTE_UNUSED,
+
const char *dname ATTRIBUTE_UNUSED,
+
unsigned long resource ATTRIBUTE_UNUSED)
+{
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__,
__FUNCTION__, __LINE__);
+ return -1;
+}
+
+static virDomainPtr
+xenapiDomainMigrateFinish (virConnectPtr dconn,
+
const char *dname,
+
const char *cookie ATTRIBUTE_UNUSED,
+
int
cookielen ATTRIBUTE_UNUSED,
+
const char *uri ATTRIBUTE_UNUSED,
+
unsigned long flags ATTRIBUTE_UNUSED)
+{
+ return xenapiDomainLookupByName
(dconn, dname);
+}
+
+static int
+xenapiDomainBlockStats (virDomainPtr dom, const
char *path ATTRIBUTE_UNUSED,
+
struct _virDomainBlockStats *stats ATTRIBUTE_UNUSED)
+{
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "",
__FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainInterfaceStats (virDomainPtr dom, const
char *path ATTRIBUTE_UNUSED,
+
struct _virDomainInterfaceStats *stats ATTRIBUTE_UNUSED)
+{
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "",
__FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainBlockPeek (virDomainPtr dom, const char
*path ATTRIBUTE_UNUSED,
+
unsigned long long offset ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED,
+
void *buffer ATTRIBUTE_UNUSED, unsigned int flags ATTRIBUTE_UNUSED)
+{
+
xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "",
__FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiNodeGetFreeMemory
+*
+* provides the free memory available on the Node
+* Returns memory size on success or 0 in case of
error
+*/
+static unsigned long long
+xenapiNodeGetFreeMemory (virConnectPtr conn)
+{
+ xen_host_metrics_set
*xen_met_set;
+ unsigned long long freeMem=0;
+ xen_host_metrics_get_all(((struct
_xenapiPrivate *)(conn->privateData))->session,
+
&xen_met_set);
+ if (xen_met_set != NULL) {
+ if
(!xen_host_metrics_get_memory_free(((struct _xenapiPrivate
*)(conn->privateData))->session,
+
(int64_t *)&freeMem, xen_met_set->contents[0])) {
+
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get host
metrics - memory information",
+
__FILE__, __FUNCTION__, __LINE__);
+
freeMem=0;
+ }
+
xen_host_metrics_set_free(xen_met_set);
+ } else {
+
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get host
metrics",
+
__FILE__, __FUNCTION__, __LINE__);
+ }
+ return freeMem;
+}
+
+/*
+* xenapiNodeGetCellsFreeMemory
+*
+*
+* Returns the number of entries filled in freeMems,
or -1 in case of error.
+*/
+static int
+xenapiNodeGetCellsFreeMemory (virConnectPtr conn,
unsigned long long *freeMems ATTRIBUTE_UNUSED,
+
int startCell, int maxCells)
+{
+ if (maxCells >1 &&
startCell >0) {
+
xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__,
__FUNCTION__, __LINE__);
+ return
-1;
+ } else {
+
freeMems[0] = xenapiNodeGetFreeMemory(conn);
+ return 1;
+ }
+}
+
+
+static int
+xenapiDomainEventRegister (virConnectPtr conn,
+
virConnectDomainEventCallback callback ATTRIBUTE_UNUSED,
+
void *opaque ATTRIBUTE_UNUSED,
+
void (*freefunc)(void *) ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(conn,
VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainEventDeregister (virConnectPtr conn,
+
virConnectDomainEventCallback callback ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(conn,
VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiNodeDeviceDettach (virNodeDevicePtr dev)
+{
+
xenapiSessionErrorHandler(dev->conn, VIR_ERR_NO_SUPPORT, "",
__FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiNodeDeviceReAttach (virNodeDevicePtr dev)
+{
+
xenapiSessionErrorHandler(dev->conn, VIR_ERR_NO_SUPPORT, "",
__FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiNodeDeviceReset (virNodeDevicePtr dev)
+{
+ xenapiSessionErrorHandler(dev->conn,
VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/* The interface which we export upwards to
libvirt.c. */
+static virDriver xenapiDriver = {
+ VIR_DRV_XENAPI,
+ "XenAPI",
+ xenapiOpen, /* open */
+ xenapiClose, /* close */
+ xenapiSupportsFeature, /*
supports_feature */
+ xenapiType, /* type */
+ xenapiGetVersion, /* version */
+ NULL, /*getlibvirtVersion */
+ xenapiGetHostname, /*
getHostname */
+ xenapiGetMaxVcpus, /*
getMaxVcpus */
+ xenapiNodeGetInfo, /*
nodeGetInfo */
+ xenapiGetCapabilities, /*
getCapabilities */
+ xenapiListDomains, /*
listDomains */
+ xenapiNumOfDomains, /*
numOfDomains */
+ xenapiDomainCreateXML, /*
domainCreateXML */
+ xenapiDomainLookupByID, /*
domainLookupByID */
+ xenapiDomainLookupByUUID, /*
domainLookupByUUID */
+ xenapiDomainLookupByName, /*
domainLookupByName */
+ xenapiDomainSuspend, /*
domainSuspend */
+ xenapiDomainResume, /* domainResume
*/
+ xenapiDomainShutdown, /*
domainShutdown */
+ xenapiDomainReboot, /*
domainReboot */
+ xenapiDomainDestroy, /*
domainDestroy */
+ xenapiDomainGetOSType, /*
domainGetOSType */
+ xenapiDomainGetMaxMemory, /*
domainGetMaxMemory */
+ xenapiDomainSetMaxMemory, /*
domainSetMaxMemory */
+ xenapiDomainSetMemory, /*
domainSetMemory */
+ xenapiDomainGetInfo, /*
domainGetInfo */
+ xenapiDomainSave, /* domainSave
*/
+ xenapiDomainRestore, /*
domainRestore */
+ xenapiDomainCoreDump, /*
domainCoreDump */
+ xenapiDomainSetVcpus, /*
domainSetVcpus */
+ xenapiDomainPinVcpu, /*
domainPinVcpu */
+ xenapiDomainGetVcpus, /*
domainGetVcpus */
+ xenapiDomainGetMaxVcpus, /*
domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel
*/
+ NULL, /* nodeGetSecurityModel */
+ xenapiDomainDumpXML, /*
domainDumpXML */
+ xenapiDomainXMLFromNative, /*
domainXmlFromNative */
+ xenapiDomainXMLToNative, /*
domainXmlToNative */
+ xenapiListDefinedDomains, /*
listDefinedDomains */
+ xenapiNumOfDefinedDomains, /*
numOfDefinedDomains */
+ xenapiDomainCreate, /*
domainCreate */
+ xenapiDomainDefineXML, /*
domainDefineXML */
+ xenapiDomainUndefine, /*
domainUndefine */
+ xenapiDomainAttachDevice, /*
domainAttachDevice */
+ NULL,
+ xenapiDomainDetachDevice, /*
domainDetachDevice */
+ NULL,
+ xenapiDomainGetAutostart, /*
domainGetAutostart */
+ xenapiDomainSetAutostart, /*
domainSetAutostart */
+ xenapiDomainGetSchedulerType, /*
domainGetSchedulerType */
+
xenapiDomainGetSchedulerParameters, /* domainGetSchedulerParameters */
+
xenapiDomainSetSchedulerParameters, /* domainSetSchedulerParameters */
+ xenapiDomainMigratePrepare, /*
domainMigratePrepare */
+ xenapiDomainMigratePerform, /*
domainMigratePerform */
+ xenapiDomainMigrateFinish, /*
domainMigrateFinish */
+ xenapiDomainBlockStats, /*
domainBlockStats */
+ xenapiDomainInterfaceStats, /*
domainInterfaceStats */
+ NULL,
+ xenapiDomainBlockPeek, /*
domainBlockPeek */
+ NULL, /* domainMemoryPeek */
+ xenapiNodeGetCellsFreeMemory, /*
nodeGetCellsFreeMemory */
+ xenapiNodeGetFreeMemory, /*
getFreeMemory */
+ xenapiDomainEventRegister, /*
domainEventRegister */
+ xenapiDomainEventDeregister, /*
domainEventDeregister */
+ NULL, /* domainMigratePrepare2
*/
+ NULL, /* domainMigrateFinish2 */
+ xenapiNodeDeviceDettach, /*
nodeDeviceDettach */
+ xenapiNodeDeviceReAttach, /*
nodeDeviceReAttach */
+ xenapiNodeDeviceReset, /*
nodeDeviceReset */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+/**
+ * xenapiRegister:
+ *
+ *
+ * Returns the driver priority or -1 in case of
error.
+ */
+int
+xenapiRegister (void)
+{
+ return virRegisterDriver
(&xenapiDriver);
+}
+
+/*
+* write_func
+* used by curl to read data from the server
+*/
+size_t
+write_func(void *ptr, size_t size, size_t nmemb,
void *comms_)
+{
+ xen_comms *comms = comms_;
+ size_t n = size * nmemb;
+ #ifdef PRINT_XML
+
printf("\n\n---Result from server -----------------------\n");
+
printf("%s\n",((char*) ptr));
+ fflush(stdout);
+ #endif
+ return (size_t)
(comms->func(ptr, n, comms->handle) ? n : 0);
+}
+
+/*
+* call_func
+* sets curl options, used with
xen_session_login_with_password
+*/
+int
+call_func(const void *data, size_t len, void
*user_handle,
+
void *result_handle, xen_result_func result_func)
+{
+ (void)user_handle;
+ #ifdef PRINT_XML
+
+
printf("\n\n---Data to server: -----------------------\n");
+ printf("%s\n",((char*)
data));
+
fflush(stdout);
+ #endif
+ CURL *curl = curl_easy_init();
+ if (!curl) {
+ return -1;
+ }
+ xen_comms comms = {
+ .func = result_func,
+ .handle = result_handle
+ };
+ curl_easy_setopt(curl,
CURLOPT_URL, url);
+ curl_easy_setopt(curl,
CURLOPT_NOPROGRESS, 1);
+ //curl_easy_setopt(curl,
CURLOPT_VERBOSE, 1);
+ #ifdef CURLOPT_MUTE
+
curl_easy_setopt(curl, CURLOPT_MUTE, 1);
+ #endif
+ curl_easy_setopt(curl,
CURLOPT_WRITEFUNCTION, &write_func);
+ curl_easy_setopt(curl,
CURLOPT_WRITEDATA, &comms);
+ curl_easy_setopt(curl,
CURLOPT_POST, 1);
+ curl_easy_setopt(curl,
CURLOPT_POSTFIELDS, data);
+ curl_easy_setopt(curl,
CURLOPT_POSTFIELDSIZE, len);
+ curl_easy_setopt(curl,
CURLOPT_SSL_VERIFYPEER, 0);
+ curl_easy_setopt(curl,
CURLOPT_SSL_VERIFYHOST, 0);
+ CURLcode result =
curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+ return result;
+}
+
+
+
+
diff -Nur ./libvirt_org/src/xenapi/xenapi_driver.h
./libvirt/src/xenapi/xenapi_driver.h
---
./libvirt_org/src/xenapi/xenapi_driver.h 1970-01-01
01:00:00.000000000 +0100
+++ ./libvirt/src/xenapi/xenapi_driver.h
2010-02-18 15:37:49.000000000 +0000
@@ -0,0 +1,44 @@
+/*
+ * xenapi.c: Xen API driver.
+ * Copyright (C) 2009 Citrix Ltd.
+ * Sharadha Prabhakar
<sharadha.prabhakar@citrix.com>
+ */
+
+
+#ifndef __VIR_XENAPI_H__
+#define __VIR_XENAPI_H__
+
+#include <xen/api/xen_common.h>
+#include <libxml/tree.h>
+
+//#define PRINT_XML
+#define RAW_UUID_BUFLEN (16)
+#define LIBVIRT_MODELNAME_LEN (32)
+
+
+extern int xenapiRegister (void);
+
+typedef struct
+{
+ xen_result_func func;
+ void *handle;
+} xen_comms;
+
+
+
+int
+call_func(const void *data, size_t len, void
*user_handle,
+
void *result_handle, xen_result_func result_func);
+size_t
+write_func(void *ptr, size_t size, size_t nmemb,
void *comms);
+
+/* xenAPI driver's private data structure */
+struct _xenapiPrivate {
+ xen_session *session;
+ void *handle;
+ char *uname;
+ char *pwd;
+ xen_api_version version;
+};
+
+#endif /* __VIR_XENAPI_H__ */