diff -Nur ./libvirt_org/src/xenapi/xenapi_utils.c ./libvirt/src/xenapi/xenapi_utils.c
--- ./libvirt_org/src/xenapi/xenapi_utils.c 1970-01-01 01:00:00.000000000 +0100
+++ ./libvirt/src/xenapi/xenapi_utils.c 2010-02-18 16:26:52.000000000 +0000
@@ -0,0 +1,507 @@
+/*
+ * xenapi_utils.c: Xen API driver -- utils parts.
+ * Copyright (C) 2009 Citrix Ltd.
+ * Sharadha Prabhakar <sharadha.prabhakar(a)citrix.com>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <config.h>
+
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <libxml/uri.h>
+#include <xen_internal.h>
+#include <libxml/parser.h>
+#include <curl/curl.h>
+#include <xen/api/xen_common.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_all.h>
+#include <xen/api/xen_vm_metrics.h>
+
+#include "libvirt_internal.h"
+#include "libvirt/libvirt.h"
+#include "virterror_internal.h"
+#include "datatypes.h"
+#include "xenapi_driver.h"
+#include "util.h"
+#include "uuid.h"
+#include "memory.h"
+#include "driver.h"
+#include "buf.h"
+#include "xenapi_utils.h"
+
+/* returns 'file' or 'block' for the storage type */
+int
+getStorageVolumeType(char *type)
+{
+ if((STREQ(type,"lvmoiscsi")) ||
+ (STREQ(type,"lvmohba")) ||
+ (STREQ(type,"lvm")) ||
+ (STREQ(type,"file")) ||
+ (STREQ(type,"iso")) ||
+ (STREQ(type,"ext")) ||
+ (STREQ(type,"nfs")))
+ return (int)VIR_STORAGE_VOL_FILE;
+ else if((STREQ(type,"iscsi")) ||
+ (STREQ(type,"equal")) ||
+ (STREQ(type,"hba")) ||
+ (STREQ(type,"cslg")) ||
+ (STREQ(type,"udev")) ||
+ (STREQ(type,"netapp")))
+ return (int)VIR_STORAGE_VOL_BLOCK;
+ return -1;
+}
+
+/* returns error description if any received from the server */
+char *
+returnErrorFromSession(xen_session *session)
+{
+ int i;
+ char *buf = NULL;
+ for (i=0; i<session->error_description_count-1; i++) {
+ if (buf==NULL) {
+ buf = (char *)realloc(buf,strlen(session->error_description[i])+1);
+ strcpy(buf,session->error_description[i]);
+ } else {
+ buf = (char
*)realloc(buf,strlen(buf)+strlen(session->error_description[i])+2);
+ strcat(buf,":");
+ strcat(buf,session->error_description[i]);
+ }
+ }
+ return buf;
+}
+
+/* XenAPI error handler - internally calls libvirt error handler after clearing error
+flag in session */
+void xenapiSessionErrorHandler(virConnectPtr conn, virErrorNumber errNum,
+ const char *buf, const char *filename, const char *func,
size_t lineno)
+{
+ if (buf==NULL) {
+ char *ret=NULL;
+ ret = returnErrorFromSession(((struct _xenapiPrivate
*)(conn->privateData))->session);
+ virReportErrorHelper (conn, VIR_FROM_XENAPI, errNum, filename, func, lineno,
_("%s\n"), ret);
+ xen_session_clear_error(((struct _xenapiPrivate
*)(conn->privateData))->session);
+ VIR_FREE(ret);
+ } else {
+ virReportErrorHelper (conn, VIR_FROM_XENAPI, errNum, filename, func, lineno,
_("%s\n"), buf);
+ }
+}
+
+/* converts bitmap to string of the form '1,2...' */
+char *
+mapDomainPinVcpu(unsigned int vcpu, unsigned char *cpumap, int maplen)
+{
+ char buf[VIR_UUID_BUFLEN], mapstr[sizeof(cpumap_t) * 64];
+ char *ret=NULL;
+ int i, j;
+ mapstr[0] = 0;
+ for (i = 0; i < maplen; i++) {
+ for (j = 0; j < 8; j++) {
+ if (cpumap[i] & (1 << j)) {
+ snprintf(buf, sizeof(buf), "%d,", (8 * i) + j);
+ strcat(mapstr, buf);
+ }
+ }
+ }
+ mapstr[strlen(mapstr) - 1] = 0;
+ snprintf(buf, sizeof(buf), "%d", vcpu);
+ ret = strdup(mapstr);
+ return ret;
+}
+
+/* obtains the CPU bitmap from the string passed */
+void
+getCpuBitMapfromString(char *mask, unsigned char *cpumap, int maplen)
+{
+ int pos;
+ int max_bits = maplen * 8;
+ char *num = NULL;
+ bzero(cpumap, maplen);
+ num = strtok (mask, ",");
+ while (num != NULL) {
+ sscanf (num, "%d", &pos);
+ if (pos<0 || pos>max_bits-1)
+ printf ("number in str %d exceeds cpumap's max bits %d\n", pos,
max_bits);
+ else
+ (cpumap)[pos/8] |= (1<<(pos%8));
+ num = strtok (NULL, ",");
+ }
+}
+
+
+/* mapping XenServer power state to Libvirt power state */
+virDomainState
+mapPowerState(enum xen_vm_power_state state)
+{
+ virDomainState virState;
+ switch (state) {
+ case (XEN_VM_POWER_STATE_HALTED):
+ case (XEN_VM_POWER_STATE_SUSPENDED):
+ virState = VIR_DOMAIN_SHUTOFF;
+ break;
+ case (XEN_VM_POWER_STATE_PAUSED):
+ virState = VIR_DOMAIN_PAUSED;
+ break;
+ case (XEN_VM_POWER_STATE_RUNNING):
+ virState = VIR_DOMAIN_RUNNING;
+ break;
+ case (XEN_VM_POWER_STATE_UNKNOWN):
+ case (XEN_VM_POWER_STATE_UNDEFINED):
+ virState = VIR_DOMAIN_NOSTATE;
+ break;
+ default:
+ virState = VIR_DOMAIN_NOSTATE;
+ break;
+ }
+ return virState;
+}
+
+/* Gets the value of the child for the current node passed */
+char *
+getXmlChildValue(xmlDocPtr doc, xmlNodePtr cur, const char *tag)
+{
+ char *key = NULL;
+ cur = cur->xmlChildrenNode;
+ while (cur != NULL) {
+ if ((!xmlStrcmp(cur->name, (const xmlChar *)tag))){
+ cur = cur->xmlChildrenNode;
+ key = (char *)xmlNodeListGetString(doc,cur,1);
+ }
+ cur = cur->next;
+ }
+ return key;
+}
+
+/* allocate a flexible array and fill values(key,val) */
+int
+allocStringMap (xen_string_string_map **strings, char *key, char *val)
+{
+ int sz = ((*strings) == NULL)?0:(*strings)->size;
+ sz++;
+ *strings = realloc(*strings,sizeof(xen_string_string_map)+
+ sizeof(xen_string_string_map_contents)*sz);
+ (*strings)->size = sz;
+ (*strings)->contents[sz-1].key = strdup(key);
+ (*strings)->contents[sz-1].val = strdup(val);
+ return 0;
+}
+
+/* create boot order string as understood by libvirt */
+void
+createXmlBootOrderString(char **order, char *key)
+{
+ int sz = ((*order)==NULL)?0:(strlen(*order)+1);
+ const char *temp=NULL;
+ if (strcmp(key,"fd")==0)
+ temp="a";
+ else if (strcmp(key,"hd")==0)
+ temp="c";
+ else if (strcmp(key,"cdrom")==0)
+ temp="d";
+ else if (strcmp(key,"network")==0)
+ temp="n";
+ if (temp!=NULL) {
+ *order = (char *)realloc(*order,sz+strlen(temp)+1);
+ if(sz==0) strcpy(*order,temp);
+ else strcat(*order,temp);
+ }
+}
+
+enum xen_on_normal_exit
+actionShutdownStringtoEnum(char *str)
+{
+ enum xen_on_normal_exit code = XEN_ON_NORMAL_EXIT_UNDEFINED;
+ if (STREQ(str, "destroy"))
+ code = XEN_ON_NORMAL_EXIT_DESTROY;
+ else if (STREQ(str, "restart"))
+ code = XEN_ON_NORMAL_EXIT_RESTART;
+ return code;
+}
+
+enum xen_on_crash_behaviour
+actionCrashStringtoEnum(char *str)
+{
+ enum xen_on_crash_behaviour code = XEN_ON_CRASH_BEHAVIOUR_UNDEFINED;
+ if (STREQ(str, "destroy"))
+ code = XEN_ON_CRASH_BEHAVIOUR_DESTROY;
+ else if (STREQ(str, "restart"))
+ code = XEN_ON_CRASH_BEHAVIOUR_RESTART;
+ else if (STREQ(str, "preserve"))
+ code = XEN_ON_CRASH_BEHAVIOUR_PRESERVE;
+ else if (STREQ(str, "rename-restart"))
+ code = XEN_ON_CRASH_BEHAVIOUR_RENAME_RESTART;
+ return code;
+}
+
+/* convert boot order string libvirt format to XenServer format */
+const char *
+mapXmlBootOrder(char c) {
+ switch(c) {
+ case 'a':
+ return "fd";
+ case 'c':
+ return "hd";
+ case 'd':
+ return "cdrom";
+ case 'n':
+ return "network";
+ default:
+ return NULL;
+ }
+}
+
+/* creates network intereface for VM */
+int
+createVifNetwork (virConnectPtr conn, xen_vm vm, char *device,
+ char *bridge, char *mac)
+{
+ xen_vm xvm = NULL;
+ char *uuid = NULL;
+ xen_vm_get_uuid(((struct _xenapiPrivate *)(conn->privateData))->session,
&uuid, vm);
+ if (uuid) {
+ if(!xen_vm_get_by_uuid(((struct _xenapiPrivate
*)(conn->privateData))->session,
+ &xvm, uuid))
+ return -1;
+ VIR_FREE(uuid);
+ }
+ xen_vm_record_opt *vm_opt = xen_vm_record_opt_alloc();
+ vm_opt->is_record = 0;
+ vm_opt->u.handle = xvm;
+ xen_network_set *net_set = NULL;
+ xen_network_record *net_rec = NULL;
+ int cnt=0;
+ if (xen_network_get_all(((struct _xenapiPrivate
*)(conn->privateData))->session, &net_set)) {
+ for(cnt=0;cnt<(net_set->size);cnt++) {
+ if (xen_network_get_record(((struct _xenapiPrivate
*)(conn->privateData))->session,
+ &net_rec, net_set->contents[cnt])) {
+ if (STREQ(net_rec->bridge,bridge)) {
+ break;
+ } else {
+ xen_network_record_free(net_rec);
+ }
+ }
+ }
+ }
+ if ( (cnt<net_set->size) && net_rec) {
+ xen_network network = NULL;
+ xen_network_get_by_uuid(((struct _xenapiPrivate
*)(conn->privateData))->session,
+ &network, net_rec->uuid);
+ xen_network_record_opt *network_opt = xen_network_record_opt_alloc();
+ network_opt->is_record = 0;
+ network_opt->u.handle = network;
+ xen_vif_record *vif_record = xen_vif_record_alloc();
+ vif_record->mac = mac;
+ vif_record->vm = vm_opt;
+ vif_record->network = network_opt;
+ xen_vif vif=NULL;
+
+ vif_record->other_config = xen_string_string_map_alloc(0);
+ vif_record->runtime_properties = xen_string_string_map_alloc(0);
+ vif_record->qos_algorithm_params = xen_string_string_map_alloc(0);
+ vif_record->device = strdup(device);
+ xen_vif_create(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &vif, vif_record);
+ if (vif!=NULL) {
+ xen_vif_free(vif);
+ xen_vif_record_free(vif_record);
+ xen_network_record_free(net_rec);
+ xen_network_set_free(net_set);
+ return 0;
+ }
+ xen_vif_record_free(vif_record);
+ xen_network_record_free(net_rec);
+ }
+ if (net_set!=NULL) xen_network_set_free(net_set);
+ return -1;
+}
+
+/* Create a VM record from the XML description */
+int
+createVMRecordFromXml (virConnectPtr conn, const char *xmlDesc,
+ xen_vm_record **record, xen_vm *vm)
+{
+ xmlDocPtr doc;
+ xmlNodePtr cur,child,temp;
+ doc = xmlParseMemory(xmlDesc,strlen(xmlDesc));
+ if (doc == NULL) {
+ xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"", __FILE__,
__FUNCTION__, __LINE__);
+ return -1;
+ }
+ cur = xmlDocGetRootElement(doc);
+ if (cur == NULL) {
+ xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"", __FILE__,
__FUNCTION__, __LINE__);
+ xmlFreeDoc(doc);
+ return -1;
+ }
+ if (xmlStrcmp(cur->name, (const xmlChar *) "domain")) {
+ xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"root node not
domain", __FILE__, __FUNCTION__, __LINE__);
+ xmlFreeDoc(doc);
+ return -1;
+ }
+ *record = xen_vm_record_alloc();
+ char *name = getXmlChildValue(doc,cur,"name");
+ (*record)->name_label = strdup(name);
+ child = cur->xmlChildrenNode;
+ while (child!=NULL) {
+ if ((!xmlStrcmp(child->name, (const xmlChar *)"os"))) {
+ char *ostype = getXmlChildValue(doc,child,"type");
+ if (ostype!=NULL) {
+ if (STREQ(ostype,"hvm")) {
+ (*record)->hvm_boot_policy = strdup("BIOS order");
+ temp = child;
+ child = child->xmlChildrenNode;
+ char *boot_order = NULL;
+ while (child != NULL) {
+ if ((!xmlStrcmp(child->name, (const xmlChar
*)"boot"))){
+ xmlChar *key;
+ key = xmlGetProp(child, (const xmlChar *)"dev");
+ if (key!=NULL) {
+ createXmlBootOrderString(&boot_order,(char *)key);
+ xmlFree(key);
+ }
+ }
+ child = child->next;
+ }
+ if (boot_order!=NULL) {
+ xen_string_string_map *hvm_boot_params=NULL;
+ allocStringMap(&hvm_boot_params, (char
*)"order",boot_order);
+ //int size = sizeof(xen_string_string_map) +
+ // (hvm_boot_params->size *
sizeof(xen_string_string_map_contents));
+ //(*record)->hvm_boot_params = (xen_string_string_map *)
malloc(size);
+ //memcpy((char *)(*record)->hvm_boot_params, (char *)hvm_boot_params,
size);
+ (*record)->hvm_boot_params = hvm_boot_params;
+ VIR_FREE(boot_order);
+ //freeStringMap(hvm_boot_params);
+ }
+ child = temp;
+ } else if (STREQ(ostype,"linux")) {
+ (*record)->pv_bootloader = strdup("pygrub");
+ char *kernel = getXmlChildValue(doc,child,"kernel");
+ if (kernel != NULL){
+ (*record)->pv_kernel = kernel;
+ //strcpy((*record)->pv_kernel,kernel);
+ //free(kernel);
+ }
+ char *initrd = getXmlChildValue(doc,child,"initrd");
+ if (initrd != NULL) {
+ (*record)->pv_ramdisk = initrd;//(char
*)malloc(strlen(initrd)+1);
+ //strcpy((*record)->pv_ramdisk,initrd);
+ //free(initrd);
+ }
+ char *cmdline = getXmlChildValue(doc,child,"cmdline");
+ if (cmdline != NULL) {
+ (*record)->pv_args = cmdline; //(char
*)malloc(strlen(cmdline)+1);
+ //strcpy((*record)->pv_args,cmdline);
+ //free(cmdline);
+ }
+ (*record)->hvm_boot_params = xen_string_string_map_alloc(0);
+ }
+ VIR_FREE(ostype);
+ }
+ }
+ child = child->next;
+ }
+ char *bootload_args = getXmlChildValue(doc,cur,"bootloader_args");
+ if (bootload_args!=NULL) {
+ (*record)->pv_bootloader_args =bootload_args; //(char
*)malloc(strlen(bootload_args)+1);
+ //strcpy((*record)->pv_bootloader_args,bootload_args);
+ //free(bootload_args);
+ }
+ char *memory = getXmlChildValue(doc,cur,"memory");
+ if (memory!=NULL) {
+ int64_t static_max=0;
+ static_max = atoll(memory);
+ (*record)->memory_static_max = static_max * 1024;
+ VIR_FREE(memory);
+ }
+ char *curmemory = getXmlChildValue(doc,cur,"currentmemory");
+ if (curmemory!=NULL) {
+ int64_t dy_max=0;
+ dy_max = atoll(curmemory);
+ (*record)->memory_dynamic_max = dy_max * 1024;
+ VIR_FREE(curmemory);
+ } else {
+ (*record)->memory_dynamic_max = (*record)->memory_static_max;
+ }
+ char *vcpu = getXmlChildValue(doc, cur, "vcpu");
+ if (vcpu!=NULL) {
+ (*record)->vcpus_max = atoll(vcpu);
+ (*record)->vcpus_at_startup = atoll(vcpu);
+ VIR_FREE(vcpu);
+ }
+ char *on_poweroff = getXmlChildValue(doc,cur,"on_poweroff");
+ if (on_poweroff!=NULL) {
+ (*record)->actions_after_shutdown = actionShutdownStringtoEnum(on_poweroff);
+ VIR_FREE(on_poweroff);
+ }
+ char *on_reboot = getXmlChildValue(doc,cur,"on_reboot");
+ if (on_reboot!=NULL) {
+ (*record)->actions_after_reboot = actionShutdownStringtoEnum(on_reboot);
+ VIR_FREE(on_reboot);
+ }
+ char *on_crash = getXmlChildValue(doc,cur,"on_crash");
+ if (on_crash!=NULL) {
+ (*record)->actions_after_crash = actionCrashStringtoEnum(on_crash);
+ VIR_FREE(on_crash);
+ }
+ temp = cur;
+ cur = cur->xmlChildrenNode;
+ xen_string_string_map *strings=NULL;
+ while (cur != NULL) {
+ if ((!xmlStrcmp(cur->name, (const xmlChar *)"features"))){
+ for (child=cur->children;child!=NULL;child=child->next) {
+ allocStringMap(&strings,(char *)child->name,(char
*)"true");
+ }
+ }
+ cur = cur->next;
+ }
+ cur = temp;
+ if (strings!=NULL) {
+ //int size = sizeof(xen_string_string_map)+
sizeof(xen_string_string_map_contents)*strings->size;
+ (*record)->platform = strings; //(xen_string_string_map *)malloc(size);
+ //memcpy((void *)(*record)->platform,(void *)strings,size);
+ }
+ (*record)->vcpus_params = xen_string_string_map_alloc(0);
+ (*record)->other_config = xen_string_string_map_alloc(0);
+ (*record)->last_boot_cpu_flags = xen_string_string_map_alloc(0);
+ (*record)->xenstore_data = xen_string_string_map_alloc(0);
+ (*record)->hvm_shadow_multiplier = 1.000;
+ if (!xen_vm_create(((struct _xenapiPrivate *)(conn->privateData))->session,
+ vm, *record)) {
+ xmlFreeDoc(doc);
+ xenapiSessionErrorHandler(conn,VIR_ERR_INTERNAL_ERROR ,NULL, __FILE__,
__FUNCTION__, __LINE__);
+ return -1;
+ }
+ cur = cur->xmlChildrenNode;
+ int device_number=0;
+ xmlChar *bridge=NULL,*mac=NULL;
+ while (cur != NULL) {
+ if ((!xmlStrcmp(cur->name, (const xmlChar *)"interface"))){
+ for (child=cur->children;child!=NULL;child=child->next) {
+ if ((!xmlStrcmp(child->name, (const xmlChar *)"source"))) {
+ bridge = xmlGetProp(child, (const xmlChar *)"bridge");
+ }
+ if ((!xmlStrcmp(child->name, (const xmlChar *)"mac"))) {
+ mac = xmlGetProp(child, (const xmlChar *)"address");
+ }
+ }
+ if (mac!=NULL && bridge!=NULL) {
+ char device[NETWORK_DEVID_SIZE]="\0";
+ sprintf(device,"%d",device_number);
+ createVifNetwork(conn, *vm, device, (char *)bridge, (char *)mac);
+ xmlFree(bridge);
+ device_number++;
+ }
+ }
+ cur = cur->next;
+ }
+ xmlFreeDoc(doc);
+ return 0;
+}
+
diff -Nur ./libvirt_org/src/xenapi/xenapi_utils.h ./libvirt/src/xenapi/xenapi_utils.h
--- ./libvirt_org/src/xenapi/xenapi_utils.h 1970-01-01 01:00:00.000000000 +0100
+++ ./libvirt/src/xenapi/xenapi_utils.h 2010-02-18 16:28:10.000000000 +0000
@@ -0,0 +1,94 @@
+/*
+ * xenapi_utils.h: Xen API driver -- utils header
+ * Copyright (C) 2009 Citrix Ltd.
+ * Sharadha Prabhakar <sharadha.prabhakar(a)citrix.com>
+ */
+
+#ifndef _VIR_XENAPI_UTILS_
+#define _VIR_XENAPI_UTILS_
+
+#include <stdio.h>
+#include <string.h>
+#include <config.h>
+
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <libxml/uri.h>
+#include <xen_internal.h>
+#include <libxml/parser.h>
+#include <curl/curl.h>
+#include <xen/api/xen_common.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_all.h>
+#include <xen/api/xen_vm_metrics.h>
+//#include <xen/dom0_ops.h>
+
+#include "libvirt_internal.h"
+#include "libvirt/libvirt.h"
+#include "virterror_internal.h"
+#include "datatypes.h"
+#include "xenapi_driver.h"
+#include "util.h"
+#include "uuid.h"
+#include "memory.h"
+#include "driver.h"
+#include "buf.h"
+
+#define NETWORK_DEVID_SIZE (10)
+
+typedef uint64_t cpumap_t;
+
+void getCpuBitMapfromString(char *mask, unsigned char *cpumap, int maplen);
+
+int getStorageVolumeType(char *type);
+
+char *returnErrorFromSession(xen_session *session);
+
+void xenapiSessionErrorHandler(virConnectPtr conn, virErrorNumber errNum,
+ const char *buf, const char *filename, const char *func,
size_t lineno);
+
+
+virDomainState
+mapPowerState(enum xen_vm_power_state state);
+
+char *
+mapDomainPinVcpu(unsigned int vcpu, unsigned char *cpumap, int maplen);
+
+char *
+getXmlChildValue(xmlDocPtr doc, xmlNodePtr cur, const char *tag);
+
+int
+createVMRecordFromXml (virConnectPtr conn, const char *xmlDesc,
+ xen_vm_record **record, xen_vm *vm);
+
+int
+allocStringMap (xen_string_string_map **strings, char *key, char *val);
+
+void
+createXmlBootOrderString(char **order, char *key);
+
+enum xen_on_normal_exit
+actionShutdownStringtoEnum(char *str);
+
+enum xen_on_crash_behaviour
+actionCrashStringtoEnum(char *str);
+
+int
+createVifNetwork(virConnectPtr conn, xen_vm vm, char *device,
+ char *bridge, char *mac);
+
+const char *
+mapXmlBootOrder(char c);
+
+
+
+
+
+
+
+#endif //_VIR_XENAPI_UTILS_