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@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@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_