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@xxxxxxxxxx> +*/ + +#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 = ""
*)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@xxxxxxxxxx> + */ + + +#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__ */ |
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list