Devel
Threads by month
- ----- 2026 -----
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 43 participants
- 40054 discussions
[libvirt] [PATCH] xenDaemonDomainSetAutostart: avoid appearance of impropriety
by Jim Meyering 19 Feb '10
by Jim Meyering 19 Feb '10
19 Feb '10
Coverity noticed that of the 13 uses of sexpr_lookup,
only this one was unchecked, and here, the result is dereferenced.
It happens to be a false positive, due to the preceding sexpr_node
check, but worth fixing: sexpr_node is just a very thin wrapper
around sexpr_lookup so there's little justification for looking
up the same string twice.
>From a9ab34214cf9d247d39731563dcc70b8f1dc73b5 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Wed, 17 Feb 2010 22:14:25 +0100
Subject: [PATCH] xenDaemonDomainSetAutostart: avoid appearance of impropriety
* src/xen/xend_internal.c (xenDaemonDomainSetAutostart): Rewrite to
avoid dereferencing the result of sexpr_lookup. While in this
particular case, it was guaranteed never to be NULL, due to the
preceding "if sexpr_node(...)" guard, it's cleaner to skip the
sexpr_node call altogether, and also saves a lookup.
---
src/xen/xend_internal.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 88923c8..1f8b106 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -4383,7 +4383,6 @@ xenDaemonDomainSetAutostart(virDomainPtr domain,
int autostart)
{
struct sexpr *root, *autonode;
- const char *autostr;
char buf[4096];
int ret = -1;
xenUnifiedPrivatePtr priv;
@@ -4408,16 +4407,17 @@ xenDaemonDomainSetAutostart(virDomainPtr domain,
return (-1);
}
- autostr = sexpr_node(root, "domain/on_xend_start");
- if (autostr) {
- if (!STREQ(autostr, "ignore") && !STREQ(autostr, "start")) {
+ autonode = sexpr_lookup(root, "domain/on_xend_start");
+ if (autonode) {
+ const char *val = (autonode->u.s.car->kind == SEXPR_VALUE
+ ? autonode->u.s.car->u.value : NULL);
+ if (!STREQ(val, "ignore") && !STREQ(val, "start")) {
virXendError(domain->conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("unexpected value from on_xend_start"));
goto error;
}
// Change the autostart value in place, then define the new sexpr
- autonode = sexpr_lookup(root, "domain/on_xend_start");
VIR_FREE(autonode->u.s.car->u.value);
autonode->u.s.car->u.value = (autostart ? strdup("start")
: strdup("ignore"));
--
1.7.0.219.g6bb57
2
1
This patch sets or unsets the IFF_VNET_HDR flag depending on what device
is used in the VM. The manipulation of the flag is done in the open
function and is only fatal if the IFF_VNET_HDR flag could not be cleared
although it has to be (or if an ioctl generally fails). In that case the
macvtap tap is closed again and the macvtap interface torn.
This patch also passes 'make syntax-check' :-).
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
2
1
Another missed va_end:
>From b2e727f9dd25f427d634ef4d79733b37af2b29dd Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Thu, 18 Feb 2010 20:46:24 +0100
Subject: [PATCH] virBufferStrcat: do not skip va_end
* src/util/buf.c (virBufferStrcat): Do not skip va_end due to
an early return.
---
src/util/buf.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/util/buf.c b/src/util/buf.c
index e683928..cc0a087 100644
--- a/src/util/buf.c
+++ b/src/util/buf.c
@@ -1,21 +1,21 @@
/*
* buf.c: buffers for libvirt
*
- * Copyright (C) 2005-2008 Red Hat, Inc.
+ * Copyright (C) 2005-2008, 2010 Red Hat, Inc.
*
* See COPYING.LIB for the License of this software
*
* Daniel Veillard <veillard(a)redhat.com>
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "c-ctype.h"
#define __VIR_BUFFER_C__
#include "buf.h"
@@ -410,25 +410,25 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str)
void
virBufferStrcat(virBufferPtr buf, ...)
{
va_list ap;
char *str;
if (buf->error)
return;
va_start(ap, buf);
while ((str = va_arg(ap, char *)) != NULL) {
unsigned int len = strlen(str);
unsigned int needSize = buf->use + len + 2;
if (needSize > buf->size) {
if (virBufferGrow(buf, needSize - buf->use) < 0)
- return;
+ break;
}
memcpy(&buf->content[buf->use], str, len);
buf->use += len;
buf->content[buf->use] = 0;
}
va_end(ap);
}
--
1.7.0.233.g05e1a
2
1
More coverity-prompted fixes:
>From 56d339d99b09c5943fa36600ca39939080cc64f4 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Thu, 18 Feb 2010 20:27:22 +0100
Subject: [PATCH] qparams.c: do not skip va_end, twice
* src/util/qparams.c (new_qparam_set, append_qparams): Do not skip
va_end due to an early return.
---
src/util/qparams.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/util/qparams.c b/src/util/qparams.c
index 9535ca4..f6d0713 100644
--- a/src/util/qparams.c
+++ b/src/util/qparams.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 2007, 2009 Red Hat, Inc.
+/* Copyright (C) 2007, 2009-2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
@@ -60,11 +60,12 @@ new_qparam_set (int init_alloc, ...)
while ((pname = va_arg (args, char *)) != NULL) {
pvalue = va_arg (args, char *);
if (append_qparam (ps, pname, pvalue) == -1) {
free_qparam_set (ps);
- return NULL;
+ ps = NULL;
+ break;
}
}
va_end (args);
return ps;
@@ -73,21 +74,24 @@ new_qparam_set (int init_alloc, ...)
int
append_qparams (struct qparam_set *ps, ...)
{
va_list args;
const char *pname, *pvalue;
+ int ret = 0;
va_start (args, ps);
while ((pname = va_arg (args, char *)) != NULL) {
pvalue = va_arg (args, char *);
- if (append_qparam (ps, pname, pvalue) == -1)
- return -1;
+ if (append_qparam (ps, pname, pvalue) == -1) {
+ ret = -1;
+ break;
+ }
}
va_end (args);
- return 0;
+ return ret;
}
/* Ensure there is space to store at least one more parameter
* at the end of the set.
*/
--
1.7.0.233.g05e1a
2
1
[libvirt] FW: [PATCH 1/4] Addition of XenAPI support to libvirt
by Sharadha Prabhakar (3P) 18 Feb '10
by Sharadha Prabhakar (3P) 18 Feb '10
18 Feb '10
This is a patch to add XenAPI driver support for libvirt version 0.7.6. XenAPI can be used against XenCloud platform and
managed through virsh and virt-manger. This patch supports domain related APIs in libvirt. It is possible to get domain information,
list active and inactive domains, get Domain XML configuration and Start/stop/pause/shutdown/destroy VMs.
There will be more patches after this review to support more libvirt APIs and add remote storage support to XenAPI.
In order to run this patch you would require libxenserver library.
The XenCloud platform can be downloaded from http://xen.org/products/cloudxen.html
diff -ur ./libvirt_org/configure.ac ./libvirt/configure.ac
--- ./libvirt_org/configure.ac 2010-02-17 17:39:21.000000000 +0000
+++ ./libvirt/configure.ac 2010-02-18 11:51:29.000000000 +0000
@@ -219,6 +219,8 @@
AC_HELP_STRING([--with-libssh2=@<:@PFX@:>@], [libssh2 location @<:@default=/usr/local/lib@:>@]),[],[with_libssh2=yes])
AC_ARG_WITH([phyp],
AC_HELP_STRING([--with-phyp], [add PHYP support @<:@default=check@:>@]),[],[with_phyp=check])
+AC_ARG_WITH([xenapi],
+ AC_HELP_STRING([--with-xenapi], [add XenAPI support @<:@default=yes@:>@]),[],[with_xenapi=check])
AC_ARG_WITH([vbox],
AC_HELP_STRING([--with-vbox], [add VirtualBox support @<:@default=yes@:>@]),[],[with_vbox=yes])
AC_ARG_WITH([lxc],
@@ -307,6 +309,11 @@
fi
AM_CONDITIONAL([WITH_VBOX], [test "$with_vbox" = "yes"])
+if test "$with_xenapi" = "yes"; then
+ AC_DEFINE_UNQUOTED([WITH_XENAPI], 1, [whether XenAPI driver is enabled])
+fi
+AM_CONDITIONAL([WITH_XENAPI], [test "$with_xenapi" = "yes"])
+
if test "$with_libvirtd" = "no" ; then
with_qemu=no
fi
@@ -1894,6 +1901,7 @@
AC_MSG_NOTICE([ UML: $with_uml])
AC_MSG_NOTICE([ OpenVZ: $with_openvz])
AC_MSG_NOTICE([ VBox: $with_vbox])
+AC_MSG_NOTICE([ XenAPI: $with_xenapi])
AC_MSG_NOTICE([ LXC: $with_lxc])
AC_MSG_NOTICE([ PHYP: $with_phyp])
AC_MSG_NOTICE([ ONE: $with_one])
diff -ur ./libvirt_org/src/Makefile.am ./libvirt/src/Makefile.am
--- ./libvirt_org/src/Makefile.am 2010-02-17 17:38:13.000000000 +0000
+++ ./libvirt/src/Makefile.am 2010-02-18 16:25:55.000000000 +0000
@@ -3,12 +3,19 @@
# No libraries with the exception of LIBXML should be listed
# here. List them against the individual XXX_la_CFLAGS targets
# that actually use them
+
+XENAPI_CFLAGS = -I@top_srcdir@/../libxenserver/include
+
INCLUDES = \
-I$(top_srcdir)/gnulib/lib \
-I../gnulib/lib \
-I../include \
+ -I/usr/include \
-I@top_srcdir@/src/util \
+ -I@top_srcdir@/src \
+ -I@top_srcdir@/src/xenapi \
-I@top_srcdir@/include \
+ $(XENAPI_CFLAGS) \
$(DRIVER_MODULE_CFLAGS) \
$(LIBXML_CFLAGS) \
-DLIBDIR=\""$(libdir)"\" \
@@ -42,6 +49,8 @@
augeastestdir = $(datadir)/augeas/lenses/tests
augeastest_DATA =
+XENAPI_LIBS = @top_srcdir@/../libxenserver/libxenserver.so
+
# These files are not related to driver APIs. Simply generic
# helper APIs for various purposes
UTIL_SOURCES = \
@@ -205,6 +214,10 @@
qemu/qemu_security_dac.h \
qemu/qemu_security_dac.c
+XENAPI_DRIVER_SOURCES = \
+ xenapi/xenapi_driver.c xenapi/xenapi_driver.h \
+ xenapi/xenapi_utils.c xenapi/xenapi_utils.h
+
UML_DRIVER_SOURCES = \
uml/uml_conf.c uml/uml_conf.h \
uml/uml_driver.c uml/uml_driver.h
@@ -466,6 +479,28 @@
libvirt_driver_vbox_la_SOURCES = $(VBOX_DRIVER_SOURCES)
endif
+if WITH_XENAPI
+if WITH_DRIVER_MODULES
+mod_LTLIBRARIES += libvirt_driver_xenapi.la
+else
+noinst_LTLIBRARIES += libvirt_driver_xenapi.la
+
+libvirt_la_LIBADD += libvirt_driver_xenapi.la \
+ $(XENAPI_LIBS)
+endif
+#libvirt_driver_xenapi_la_LIBADD = $(XENAPI_LIBS)
+libvirt_driver_xenapi_la_CFLAGS = $(XEN_CFLAGS) \
+ $(shell xml2-config --cflags) \
+ $(shell curl-config --cflags)
+libvirt_driver_xenapi_la_LDFLAGS = -L@top_srcdir@/../libxenserver/ -lxenserver -g $(shell xml2-config --libs) \
+ $(shell curl-config --libs)
+
+if WITH_DRIVER_MODULES
+libvirt_driver_xenapi_la_LDFLAGS += -module -avoid-version
+endif
+libvirt_driver_xenapi_la_SOURCES = $(XENAPI_DRIVER_SOURCES)
+endif
+
if WITH_QEMU
if WITH_DRIVER_MODULES
mod_LTLIBRARIES += libvirt_driver_qemu.la
@@ -722,6 +757,7 @@
$(OPENVZ_DRIVER_SOURCES) \
$(PHYP_DRIVER_SOURCES) \
$(VBOX_DRIVER_SOURCES) \
+ $(XENAPI_DRIVER_SOURCES) \
$(ESX_DRIVER_SOURCES) \
$(NETWORK_DRIVER_SOURCES) \
$(INTERFACE_DRIVER_SOURCES) \
diff -ur ./libvirt_org/tools/Makefile.am ./libvirt/tools/Makefile.am
--- ./libvirt_org/tools/Makefile.am 2010-02-17 17:36:13.000000000 +0000
+++ ./libvirt/tools/Makefile.am 2010-02-18 11:56:30.000000000 +0000
@@ -40,7 +40,8 @@
$(WARN_CFLAGS) \
../src/libvirt.la \
../gnulib/lib/libgnu.la \
- $(VIRSH_LIBS)
+ $(VIRSH_LIBS) \
+ ../../libxenserver/libxenserver.so
virsh_CFLAGS = \
-I$(top_srcdir)/gnulib/lib -I../gnulib/lib \
-I../include -I$(top_srcdir)/include \
2
1
This is an update to / deprecates the patchset I sent last night:
https://www.redhat.com/archives/libvir-list/2010-February/msg00580.html
I have corrected the problem found by Dan Berrange (neglecting to
restore the signal mask when fork() fails). Aside from that, and
corresponding comments in the commit logs, it is unchanged.
Here's the original intro email:
This was partly prompted by DV's suggestion last week.
The first of these patches creates a new function called virFork()
which behaves (almost) like fork() but takes care of some important
details that pretty much any call to fork() should be doing. The 2nd
switches three fork-calling functions in util.c over to using
virFork() instead of fork().
In the future, except for odd circumstances, code that needs to fork
should call virFork() instead, and if there is anything determined to
be universally necessary at fork-time, it should be added to virFork()
rather than to the callers of virFork(); hopefully this will ease
maintenance and reduce replicated bugs.
(Note that, while this is just an overall "code health" patch, a
couple bug fix patches I'll be submitting either tomorrow or Thursday
will assume it as a prerequisite).
2
3
18 Feb '10
Hello,
I would like to use -redir argument for qemu-kvm guest, but I can't find any
mention in docs about this option. Is there any way how to arrange port
redirection with libvirt? I can't use a bridge for networking, because I
can't use an IP address from host's range.
Thank you,
JaromÃr ÄŒervenka
Official openSUSE community member
Web: http://www.cervajz.com/
Jabber: cervajz(a)cervajz.com
MSN: jara.cervenka(a)seznam.cz
Tel.: +420 607 592 687
Alt. e-mails:
jaromir.cervenka(a)opensuse.org,
jaromir.cervenka(a)speel.cz
1
0
How can I set viridian=1 using libvirt? Is it possible?
I haven't seen any reference about it on the xml format documentation
Best Regards,
Diego Dias
1
0
18 Feb '10
Resending patch 3/4 which didn't reach the first time seemingly.
diff -Nur ./libvirt_org/src/xenapi/xenapi_driver.c ./libvirt/src/xenapi/xenapi_driver.c
--- ./libvirt_org/src/xenapi/xenapi_driver.c 1970-01-01 01:00:00.000000000 +0100
+++ ./libvirt/src/xenapi/xenapi_driver.c 2010-02-18 16:26:13.000000000 +0000
@@ -0,0 +1,1774 @@
+
+/*
+ * xenapi_driver.c: Xen API driver.
+ * Copyright (C) 2009 Citrix Ltd.
+ * Sharadha Prabhakar <sharadha.prabhakar(a)citrix.com>
+*/
+
+#include <config.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <libxml/uri.h>
+#include <xen_internal.h>
+#include <libxml/parser.h>
+#include <curl/curl.h>
+#include <xen/api/xen_common.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_all.h>
+#include <xen/api/xen_vm_metrics.h>
+
+#include "libvirt_internal.h"
+#include "libvirt/libvirt.h"
+#include "virterror_internal.h"
+#include "datatypes.h"
+#include "xenapi_driver.h"
+#include "util.h"
+#include "uuid.h"
+#include "memory.h"
+#include "driver.h"
+#include "buf.h"
+#include "xenapi_utils.h"
+
+char *url;
+
+/*
+*XenapiOpen
+*
+*Authenticates and creates a session with the server
+*Return VIR_DRV_OPEN_SUCCESS on success, else VIR_DRV_OPEN_ERROR
+*/
+static virDrvOpenStatus
+xenapiOpen (virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED)
+{
+ char *user,*passwd;
+ char delims[]=":";
+ xen_session *session;
+ struct _xenapiPrivate *privP;
+
+ if (!STREQ(conn->uri->scheme,"XenAPI")) {
+ xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED ,"Check URI format: 'XenAPI://user:password@server'", __FILE__, __FUNCTION__, __LINE__);
+ return VIR_DRV_OPEN_ERROR;
+ }
+ if (conn->uri->server==NULL) {
+ xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED ,"Server name not in URI", __FILE__, __FUNCTION__, __LINE__);
+ return VIR_DRV_OPEN_ERROR;
+ }
+
+ user = strtok(conn->uri->user,delims);
+ passwd = strtok(NULL,delims);
+
+
+
+ url = (char *)malloc(strlen("https://")+strlen(conn->uri->server)+1);
+ strcpy(url,"https://");
+ strcat(url,conn->uri->server);
+ url[strlen("https://")+strlen(conn->uri->server)]='\0';
+
+ xmlInitParser();
+ xmlKeepBlanksDefault(0);
+ xen_init();
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ session = xen_session_login_with_password( call_func, NULL, user, passwd, xen_api_latest_version);
+
+ if ( session != NULL && session->ok ) {
+ privP = malloc(sizeof(struct _xenapiPrivate));
+ privP->session = session;
+ conn->privateData = privP;
+ return VIR_DRV_OPEN_SUCCESS;
+ } else {
+ xenapiSessionErrorHandler(conn, VIR_ERR_AUTH_FAILED ,"", __FILE__, __FUNCTION__, __LINE__);
+ return VIR_DRV_OPEN_ERROR;
+ }
+}
+
+/*
+* xenapiClose:
+*
+* Returns 0 on successful session logout
+*
+*/
+static int
+xenapiClose (virConnectPtr conn)
+{
+ xen_session_logout(((struct _xenapiPrivate *)(conn->privateData))->session);
+ VIR_FREE(conn->privateData);
+ return 0;
+}
+
+/*
+*
+* xenapiSupportsFeature
+*
+* Returns 0
+*/
+static int
+xenapiSupportsFeature (virConnectPtr conn ATTRIBUTE_UNUSED, int feature)
+{
+ switch (feature) {
+ case VIR_DRV_FEATURE_MIGRATION_V2:
+ case VIR_DRV_FEATURE_MIGRATION_P2P:
+ default:
+ return 0;
+ }
+}
+
+/*
+* xenapiType:
+*
+*
+*Returns name of the driver
+*/
+static const char *
+xenapiType (virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ return "XenAPI";
+}
+
+
+/*
+* xenapiGetVersion:
+*
+* Gets the version of XenAPI
+*
+*/
+static int
+xenapiGetVersion (virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *hvVer)
+{
+ *hvVer = 1;
+ return 0;
+}
+
+
+/*
+* xenapiGetHostname:
+*
+*
+* Returns the hostname on success, or NULL on failure
+*/
+static char *
+xenapiGetHostname (virConnectPtr conn)
+{
+ char *result;
+ xen_host host;
+
+ if (!(xen_session_get_this_host(((struct _xenapiPrivate *)(conn->privateData))->session, &host,
+ ((struct _xenapiPrivate *)(conn->privateData))->session))) {
+ if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok))
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__, __FUNCTION__, __LINE__);
+ else
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,"Unable to find host", __FILE__, __FUNCTION__, __LINE__);
+ return NULL;
+ }
+ xen_host_get_hostname(((struct _xenapiPrivate *)(conn->privateData))->session, &result, host);
+ xen_host_free(host);
+ return result;
+}
+
+
+/*
+* xenapiGetMAxVcpus:
+*
+*
+* Returns a hardcoded value for Maximum VCPUS
+*/
+static int
+xenapiGetMaxVcpus (virConnectPtr conn ATTRIBUTE_UNUSED, const char *type ATTRIBUTE_UNUSED)
+{
+ /* this is hardcoded for simplicity and set to a resonable value compared
+ to the actual value */
+ return 16;
+}
+
+
+/*
+* xenapiNodeGetInfo:
+*
+*
+* Returns Node details on success or else -1
+*/
+static int
+xenapiNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info)
+{
+ int64_t memory,mhz;
+ xen_host_cpu_set *host_cpu_set;
+ xen_host_cpu host_cpu;
+ xen_host_metrics_set *xen_met_set;
+ char *modelname;
+ info->nodes = 1;
+ info->threads = 1;
+ info->sockets = 1;
+
+ if (xen_host_metrics_get_all(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &xen_met_set)) {
+ xen_host_metrics_get_memory_total(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &memory, xen_met_set->contents[0]);
+ info->memory = (unsigned long)(memory/1024);
+ xen_host_metrics_set_free(xen_met_set);
+ } else {
+ xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR ,"Unable to get host metric Information",
+ __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ if (xen_host_cpu_get_all(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &host_cpu_set)) {
+ host_cpu = host_cpu_set->contents[0];
+ xen_host_cpu_get_modelname(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &modelname, host_cpu);
+ strncpy(info->model, modelname, LIBVIRT_MODELNAME_LEN-2);
+ info->model[LIBVIRT_MODELNAME_LEN-1]='\0';
+ xen_host_cpu_get_speed(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &mhz, host_cpu);
+ info->mhz = (unsigned long)mhz;
+ info->cpus = host_cpu_set->size;
+ info->cores = host_cpu_set->size;
+
+ xen_host_cpu_set_free(host_cpu_set);
+ free(modelname);
+ return 0;
+ }
+ xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR ,"Unable to get Host CPU set",
+ __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+
+/*
+* xenapiGetCapabilities:
+*
+*
+* Returns capabilities as an XML string
+*/
+static char *
+xenapiGetCapabilities (virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ virBufferAddLit(&buf, "<capabilities>\n");
+ virBufferAddLit(&buf, "<host>\n");
+ virBufferAddLit(&buf, " <cpu></cpu>\n");
+ virBufferAddLit(&buf, "</host>");
+ virBufferAddLit(&buf, "<guest>\n");
+ virBufferAddLit(&buf, "<os_type>hvm</os_type>\n");
+ virBufferAddLit(&buf, "<arch>\n");
+ virBufferAddLit(&buf, "<domain type='xenapi'></domain>\n");
+ virBufferAddLit(&buf, "</arch>\n");
+ virBufferAddLit(&buf, "</guest>\n");
+ virBufferAddLit(&buf, "</capabilities>\n");
+ return virBufferContentAndReset(&buf);
+}
+
+/*
+* xenapiListDomains
+*
+* Collects the list of active domains, and store their ID in @maxids
+* Returns the number of domain found or -1 in case of error
+*/
+static int
+xenapiListDomains (virConnectPtr conn, int *ids, int maxids)
+{
+ /* vm.list */
+ int i,list;
+ xen_host host;
+ xen_vm_set *result=NULL;
+ if (xen_session_get_this_host(((struct _xenapiPrivate *)(conn->privateData))->session, &host,
+ ((struct _xenapiPrivate *)(conn->privateData))->session)) {
+ xen_host_get_resident_vms(((struct _xenapiPrivate *)(conn->privateData))->session, &result, host);
+ xen_host_free(host);
+ } else {
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__, __FUNCTION__, __LINE__);
+ }
+ if (result != NULL) {
+ for ( i=0; (i < (result->size)) && (i<maxids) ; i++ ) {
+ int64_t t0;
+ xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session, &t0, result->contents[i]);
+ ids[i] = (int)(t0 & 0xffffffff);
+ }
+ list = result->size;
+ xen_vm_set_free(result);
+ return list;
+ }
+ return -1;
+}
+
+/*
+* xenapiNumOfDomains
+*
+*
+* Returns the number of domains found or -1 in case of error
+*/
+static int
+xenapiNumOfDomains (virConnectPtr conn)
+{
+ /* #(vm.list) */
+ xen_vm_set *result=NULL;
+ xen_host host=NULL;
+ int numDomains=-1;
+
+ xen_session_get_this_host(((struct _xenapiPrivate *)(conn->privateData))->session, &host,
+ ((struct _xenapiPrivate *)(conn->privateData))->session);
+ if ( host!=NULL ) {
+ xen_host_get_resident_vms(((struct _xenapiPrivate *)(conn->privateData))->session, &result, host);
+ if ( result != NULL) {
+ numDomains = result->size;
+ xen_vm_set_free(result);
+ }
+ xen_host_free(host);
+ }
+ if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok))
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__, __FUNCTION__, __LINE__);
+ return numDomains;
+}
+
+/*
+* xenapiDomainCreateXML
+*
+* Launches a new domain based on the XML description
+* Returns the domain pointer or NULL in case of error
+*/
+static virDomainPtr
+xenapiDomainCreateXML (virConnectPtr conn,
+ const char *xmlDesc, ATTRIBUTE_UNUSED unsigned int flags)
+{
+ xen_vm_record *record=NULL;
+ xen_vm vm=NULL;
+ virDomainPtr domP=NULL;
+ createVMRecordFromXml( conn, xmlDesc, &record, &vm);
+ if (record!=NULL) {
+ unsigned char raw_uuid[RAW_UUID_BUFLEN];
+ virUUIDParse(record->uuid,raw_uuid);
+ if (vm!=NULL) {
+ if (xen_vm_start(((struct _xenapiPrivate *)(conn->privateData))->session,
+ vm, false, false)) {
+ domP = virGetDomain(conn, record->name_label, raw_uuid);
+ xen_vm_free(vm);
+ }
+ else
+ xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ }
+ xen_vm_record_free(record);
+ }
+ else
+ xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return domP;
+}
+
+/*
+* xenapiDomainLookupByID
+*
+*
+* Returns a valid domain pointer of the domain with ID same as the one passed
+* or NULL in case of error
+*/
+static virDomainPtr
+xenapiDomainLookupByID (virConnectPtr conn, int id)
+{
+ int i;
+ int64_t domID;
+ char *uuid;
+ xen_host host;
+ xen_vm_set *result;
+ xen_vm_record *record;
+ unsigned char raw_uuid[RAW_UUID_BUFLEN];
+ virDomainPtr domP=NULL;
+
+ xen_session_get_this_host(((struct _xenapiPrivate *)(conn->privateData))->session, &host,
+ ((struct _xenapiPrivate *)(conn->privateData))->session);
+ if (host!=NULL && ((struct _xenapiPrivate *)(conn->privateData))->session->ok) {
+ xen_host_get_resident_vms(((struct _xenapiPrivate *)(conn->privateData))->session, &result, host);
+ if ( result !=NULL ) {
+ for( i=0; i < (result->size); i++) {
+ xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session, &domID, result->contents[i]);
+ if ( domID == id ) {
+ xen_vm_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &record, result->contents[i]);
+ xen_vm_get_uuid(((struct _xenapiPrivate *)(conn->privateData))->session, &uuid, result->contents[i]);
+ virUUIDParse(uuid,raw_uuid);
+ domP = virGetDomain(conn, record->name_label, raw_uuid);
+ if (domP!=NULL) {
+ int64_t domid=-1;
+ xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &domid, result->contents[i]);
+ domP->id = domid;
+ }
+ xen_uuid_free(uuid);
+ xen_vm_record_free(record);
+ }
+ }
+ xen_vm_set_free(result);
+ } else {
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN ,NULL, __FILE__, __FUNCTION__, __LINE__);
+ }
+ xen_host_free(host);
+ } else {
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE ,NULL, __FILE__, __FUNCTION__, __LINE__);
+ }
+ return domP;
+}
+
+/*
+* xenapiDomainLookupByUUID
+*
+* Returns the domain pointer of domain with matching UUID
+* or -1 in case of error
+*/
+static virDomainPtr
+xenapiDomainLookupByUUID (virConnectPtr conn,
+ const unsigned char *uuid)
+{
+ /* vm.get_by_uuid */
+ xen_vm vm;
+ xen_vm_record *record;
+ unsigned char raw_uuid[RAW_UUID_BUFLEN];
+ virDomainPtr domP=NULL;
+ if (xen_vm_get_by_uuid(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &vm, (char *)uuid)) {
+ xen_vm_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &record, vm);
+ if (record != NULL) {
+ virUUIDParse((char *)uuid,raw_uuid);
+ domP = virGetDomain(conn, record->name_label, raw_uuid);
+ xen_vm_record_free(record);
+ }
+ else
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN ,NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_free(vm);
+ } else
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN ,NULL, __FILE__, __FUNCTION__, __LINE__);
+ return domP;
+}
+
+/*
+* xenapiDomainLookupByName
+*
+* Returns the domain pointer of domain with matching name
+* or -1 in case of error
+*/
+static virDomainPtr
+xenapiDomainLookupByName (virConnectPtr conn,
+ const char *name)
+{
+ /* vm.get_by_name_label */
+ xen_vm_set *vms=NULL;
+ xen_vm vm;
+ char *uuid=NULL;
+ unsigned char raw_uuid[RAW_UUID_BUFLEN];
+ virDomainPtr domP=NULL;
+
+ xen_vm_get_by_name_label(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &vms, (char *)name);
+ if (vms!=NULL && vms->size!=0) {
+ vm = vms->contents[0];
+ xen_vm_get_uuid(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &uuid, vm);
+ if (uuid!=NULL) {
+ virUUIDParse(uuid,raw_uuid);
+ domP = virGetDomain(conn, name, raw_uuid);
+ if (domP != NULL) {
+ int64_t domid=-1;
+ xen_vm_get_domid(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &domid, vm);
+ domP->id = domid;
+ xen_uuid_free(uuid);
+ xen_vm_set_free(vms);
+ return domP;
+ } else {
+ xen_uuid_free(uuid);
+ xen_vm_set_free(vms);
+ if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok)) {
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ }
+ return NULL;
+ }
+ }
+ }
+ if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok)) {
+ xenapiSessionErrorHandler(conn,VIR_ERR_NO_DOMAIN,NULL,__FILE__,__FUNCTION__, __LINE__);
+ } else {
+ xenapiSessionErrorHandler(conn,VIR_ERR_NO_DOMAIN,"Domain name not found",__FILE__,__FUNCTION__, __LINE__);
+ }
+ return NULL;
+}
+
+/*
+* xenapiDomainSuspend
+*
+* a VM is paused
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainSuspend (virDomainPtr dom)
+{
+ /* vm.pause() */
+ xen_vm vm;
+ xen_vm_set *vms;
+ if (!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name)) {
+ xenapiSessionErrorHandler(dom->conn,VIR_ERR_NO_DOMAIN,NULL,__FILE__,__FUNCTION__, __LINE__);
+ return -1;
+ }
+ vm = vms->contents[0];
+ if (!xen_vm_pause(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ return -1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+/*
+* xenapiDomainResume
+*
+* Resumes a VM
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainResume (virDomainPtr dom)
+{
+ /* vm.unpause() */
+ xen_vm vm;
+ xen_vm_set *vms;
+ if (!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ if (vms!=NULL && vms->size!=0) {
+ vm = vms->contents[0];
+ if (!xen_vm_unpause(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ return -1;
+ }
+ xen_vm_set_free(vms);
+ }
+ return 0;
+}
+
+/*
+* xenapiDomainShutdown
+*
+* shutsdown a VM
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainShutdown (virDomainPtr dom)
+{
+ /* vm.clean_shutdown */
+ xen_vm vm;
+ xen_vm_set *vms;
+ if(!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ vm = vms->contents[0];
+ if (!xen_vm_clean_shutdown(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ return -1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+/*
+* xenapiDomainReboot
+*
+* Reboots a VM
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainReboot (virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED)
+{
+ /* vm.clean_reboot */
+ xen_vm vm;
+ struct xen_vm_set *vms;
+ xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name);
+ if (vms==NULL || vms->size==0) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ vm = vms->contents[0];
+ if (!xen_vm_clean_reboot(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ return -1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+/*
+* xenapiDomaindestroy
+*
+* A VM is hard shutdown
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainDestroy (virDomainPtr dom)
+{
+ /* vm.hard_shutdown */
+ xen_vm vm;
+ struct xen_vm_set *vms;
+ xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name);
+ if (vms==NULL || vms->size==0) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ vm = vms->contents[0];
+ if (!xen_vm_hard_shutdown(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ return -1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+/*
+* xenapiDomainGetOSType
+*
+*
+* Returns OS version on success or NULL in case of error
+*/
+static char *
+xenapiDomainGetOSType (virDomainPtr dom)
+{
+ /* vm.get_os-version */
+ int i;
+ xen_vm vm;
+ char *os_version=NULL;
+ xen_vm_record *record;
+ xen_string_string_map *result;
+ char uuid[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid,uuid);
+ if (xen_vm_get_by_uuid(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vm, uuid)) {
+ xen_vm_get_record(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &record, vm);
+ if (record!=NULL) {
+ xen_vm_guest_metrics_get_os_version(((struct _xenapiPrivate *)(dom->conn->privateData))->session, &result,
+ record->guest_metrics->u.handle);
+ if (result != NULL) {
+ for (i=0; i<(result->size); i++) {
+ if (STREQ(result->contents[i].key, "distro")) {
+ if (STREQ(result->contents[i].val, "windows")) {
+ os_version = strdup(result->contents[i].val);
+ } else {
+ os_version = strdup("linux");
+ }
+ }
+ }
+ xen_string_string_map_free(result);
+ } else
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_OS, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_record_free(record);
+ } else
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_free(vm);
+ }
+ else
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ if ( os_version == NULL ) {
+ os_version = strdup("unknown");
+ }
+ return os_version;
+}
+
+/*
+* xenapiDomainGetMaxMemory
+*
+* Returns maximum static memory for VM on success
+* or 0 in case of error
+*/
+static unsigned long
+xenapiDomainGetMaxMemory (virDomainPtr dom)
+{
+ int64_t mem_static_max=0;
+ xen_vm vm;
+ xen_vm_set *vms;
+ xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name);
+ if (vms != NULL && vms->size!=0) {
+ /* vm.get_memory_static_max */
+ vm = vms->contents[0];
+ xen_vm_get_memory_static_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &mem_static_max, vm);
+ xen_vm_set_free(vms);
+ return (unsigned long)(mem_static_max/1024);
+ } else {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return 0;
+ }
+}
+
+/*
+* xenapiDomainSetMaxMemory
+*
+* Sets maximum static memory for VM on success
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainSetMaxMemory (virDomainPtr dom, unsigned long memory)
+{
+ /* vm.set_memory_static_max */
+ xen_vm vm;
+ struct xen_vm_set *vms;
+ xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name);
+ if (vms!=NULL && vms->size!=0) {
+ vm = vms->contents[0];
+ if (!(xen_vm_set_memory_static_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ vm, memory))) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ return -1;
+ }
+ xen_vm_set_free(vms);
+ } else {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ return 0;
+}
+
+static int
+xenapiDomainSetMemory (virDomainPtr dom, unsigned long memory ATTRIBUTE_UNUSED)
+{
+ /* XenAPI doesn't allow this function */
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainGetInfo:
+*
+* Fills a structure with domain information
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)
+{
+ int64_t maxmem=0,memory=0,vcpu=0;
+ xen_vm vm;
+ xen_vm_record *record;
+ xen_vm_set *vms;
+ info->cpuTime = 0; /* CPU time is not advertised */
+ if (xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name)) {
+ vm = vms->contents[0];
+ xen_vm_get_memory_static_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &maxmem, vm);
+ info->maxMem = (maxmem/1024);
+ enum xen_vm_power_state state = XEN_VM_POWER_STATE_UNKNOWN;
+ xen_vm_get_power_state(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &state, vm);
+ info->state = mapPowerState(state);
+ xen_vm_get_record(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &record, vm);
+ if (record!=NULL) {
+ xen_vm_metrics_get_memory_actual(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &memory, record->metrics->u.handle);
+ info->memory = (memory/1024);
+ xen_vm_record_free(record);
+ }
+ xen_vm_get_vcpus_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vcpu, vm);
+ info->nrVirtCpu = vcpu;
+ xen_vm_set_free(vms);
+ return 0;
+ }
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainSave
+*
+* suspends a VM
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainSave (virDomainPtr dom, const char *to ATTRIBUTE_UNUSED)
+{
+ int ret_code = -1;
+ ret_code = xenapiDomainSuspend(dom);
+ return ret_code;
+}
+
+/*
+* xenapiDomainRestore
+*
+* Resumes a VM
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainRestore (virConnectPtr conn, const char *from ATTRIBUTE_UNUSED)
+{
+ /* resume from : NI */
+ xen_vm_set *result=NULL;
+ xen_host host=NULL;
+ xen_vm_record *record = NULL;
+ unsigned char raw_uuid[RAW_UUID_BUFLEN];
+ virDomainPtr domP=NULL;
+ int ret_code=-1;
+
+ xen_session_get_this_host(((struct _xenapiPrivate *)(conn->privateData))->session, &host,
+ ((struct _xenapiPrivate *)(conn->privateData))->session);
+ if ( host!=NULL ) {
+ xen_host_get_resident_vms(((struct _xenapiPrivate *)(conn->privateData))->session, &result, host);
+ if ( result != NULL ) {
+ xen_vm_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &record, result->contents[0]);
+ if (record!=NULL) {
+ virUUIDParse(record->uuid,raw_uuid);
+ domP = virGetDomain(conn, record->name_label, raw_uuid);
+ if (domP!=NULL)
+ ret_code = xenapiDomainResume(domP);
+ else
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_record_free(record);
+ }
+ xen_vm_set_free(result);
+ }
+ xen_host_free(host);
+ }
+ if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok))
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return ret_code;
+}
+
+static int
+xenapiDomainCoreDump (virDomainPtr dom, const char *to ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainSetVcpus
+*
+* Sets the VCPUs on the domain
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
+{
+
+ /* vm.set_vcpus_max */
+ xen_vm vm;
+ xen_vm_set *vms;
+ xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name);
+ if (vms!=NULL && vms->size!=0) {
+ vm = vms->contents[0];
+ if (xen_vm_set_vcpus_number_live(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ vm, (int64_t)nvcpus)) {
+ xen_vm_set_free(vms);
+ return 0;
+ }
+ }
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainPinVcpu
+*
+* Dynamically change the real CPUs which can be allocated to a virtual CPU
+* Returns 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainPinVcpu (virDomainPtr dom, unsigned int vcpu,
+ unsigned char *cpumap, int maplen)
+{
+ char *value;
+ xen_vm vm;
+ xen_vm_set *vms;
+ xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name);
+ if (vms!=NULL && vms->size!=0) {
+ vm = vms->contents[0];
+ value = mapDomainPinVcpu(vcpu, cpumap, maplen);
+ xen_vm_remove_from_vcpus_params(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm, (char *)"mask");
+ if (xen_vm_add_to_vcpus_params(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ vm, (char *)"mask", value)) {
+ xen_vm_set_free(vms);
+ return 0;
+ }
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ }
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainGetVcpus
+*
+* Gets Vcpu information
+* Return number of structures filled on success or -1 in case of error
+*/
+static int
+xenapiDomainGetVcpus (virDomainPtr dom,
+ virVcpuInfoPtr info, int maxinfo,
+ unsigned char *cpumaps, int maplen)
+{
+
+ xen_vm_set *vms=NULL;
+ xen_vm vm=NULL;
+ xen_string_string_map *vcpu_params=NULL;
+ int nvcpus=0,cpus=0,i;
+ virDomainInfoPtr domInfo;
+ virNodeInfo nodeInfo;
+ virVcpuInfoPtr ifptr;
+ char *mask=NULL;
+ if((cpumaps!=NULL) && (maplen < 1))
+ return -1;
+ domInfo =(struct _virDomainInfo *) malloc(sizeof(struct _virDomainInfo));
+ if (virDomainGetInfo(dom,domInfo)==0) {
+ nvcpus = domInfo->nrVirtCpu;
+ free(domInfo);
+ } else {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, "Couldn't fetch Domain Information",
+ __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ if ( virNodeGetInfo(dom->conn,&nodeInfo)==0)
+ cpus = nodeInfo.cpus;
+ else {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, "Couldn't fetch Node Information",
+ __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ if(nvcpus > maxinfo) nvcpus = maxinfo;
+
+ if (cpumaps != NULL)
+ memset(cpumaps, 0, maxinfo * maplen);
+
+ if (!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ vm = vms->contents[0];
+ if (!xen_vm_get_vcpus_params(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vcpu_params, vm)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ for (i=0; i<vcpu_params->size; i++) {
+ if (STREQ(vcpu_params->contents[i].key,"mask")) {
+ mask = strdup(vcpu_params->contents[i].val);
+ }
+ }
+ for (i=0,ifptr=info ;i<nvcpus; i++,ifptr++) {
+ ifptr->number = i;
+ ifptr->state = VIR_VCPU_RUNNING;
+ ifptr->cpuTime = 0;
+ ifptr->cpu = 0;
+ if (mask !=NULL)
+ getCpuBitMapfromString(mask,VIR_GET_CPUMAP(cpumaps,maplen,i),maplen);
+ }
+ return i;
+}
+
+/*
+* xenapiDomainGetMaxVcpus
+*
+*
+* Returns maximum number of Vcpus on success or -1 in case of error
+*/
+static int
+xenapiDomainGetMaxVcpus (virDomainPtr dom)
+{
+ xen_vm vm;
+ xen_vm_set *vms;
+ int64_t maxvcpu=0;
+ enum xen_vm_power_state state;
+
+ if (xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name)) {
+ vm = vms->contents[0];
+ xen_vm_get_power_state(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &state, vm);
+ if(state == XEN_VM_POWER_STATE_RUNNING) {
+ xen_vm_get_vcpus_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &maxvcpu, vm);
+ } else {
+ maxvcpu = xenapiGetMaxVcpus(dom->conn, NULL);
+ }
+ xen_vm_set_free(vms);
+ return (int)maxvcpu;
+ }
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainDumpXML
+*
+*
+* Returns XML string of the domain configuration on success or -1 in case of error
+*/
+static char *
+xenapiDomainDumpXML (virDomainPtr dom, ATTRIBUTE_UNUSED int flags)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char uuid_string[VIR_UUID_STRING_BUFLEN];
+ xen_vm vm=NULL;
+ xen_vm_set *vms;
+ xen_string_string_map *result=NULL;
+
+ xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name);
+ if (vms==NULL || vms->size==0) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return NULL;
+ }
+
+ vm = vms->contents[0];
+ virBufferAddLit(&buf, "<domain type='xenapi'>\n");
+ virBufferEscapeString(&buf, " <name>%s</name>\n", "testVM");
+ virUUIDFormat(dom->uuid,uuid_string);
+ virBufferEscapeString(&buf, " <uuid>%s</uuid>\n",uuid_string);
+
+
+ virBufferAddLit(&buf, " <os>\n");
+ char *boot_policy=NULL;
+ xen_vm_get_hvm_boot_policy(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &boot_policy, vm);
+ if (STREQ(boot_policy,"BIOS order")) {
+ virBufferAddLit(&buf, " <type>hvm</type>\n");
+ xen_vm_get_hvm_boot_params(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &result, vm);
+ if (result!=NULL) {
+ int i;
+ for (i=0; i<(result->size); i++) {
+ if (STREQ(result->contents[i].key,"order")) {
+ int j=0;
+ while(result->contents[i].val[j]!='\0') {
+ virBufferEscapeString(&buf, " <boot dev='%s' />\n",
+ mapXmlBootOrder(result->contents[i].val[j]));
+ j++;
+ }
+ }
+ }
+ xen_string_string_map_free(result);
+ }
+ VIR_FREE(boot_policy);
+ } else {
+ virBufferAddLit(&buf, " <type>linux</type>\n");
+ virBufferAddLit(&buf, " <loader>pygrub</loader>\n");
+ char *value=NULL;
+ xen_vm_get_pv_kernel(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &value, vm);
+ if (!STREQ(value,"")) {
+ virBufferEscapeString(&buf," <kernel>%s</kernel>\n",value);
+ VIR_FREE(value);
+ }
+ xen_vm_get_pv_ramdisk(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &value, vm);
+ if (!STREQ(value,"")) {
+ virBufferEscapeString(&buf," <initrd>%s</initrd>\n",value);
+ VIR_FREE(value);
+ }
+ xen_vm_get_pv_args(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &value, vm);
+ if (!STREQ(value,"")) {
+ virBufferEscapeString(&buf," <cmdline>%s</cmdline>\n",value);
+ VIR_FREE(value);
+ }
+ VIR_FREE(boot_policy);
+ }
+ virBufferAddLit(&buf, " </os>\n");
+ virBufferAddLit(&buf, " <bootloader>pygrub</bootloader>\n");
+ char *val=NULL;
+ xen_vm_get_pv_bootloader_args(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &val, vm);
+ if (!STREQ(val,"")) {
+ virBufferEscapeString(&buf," <bootloader_args>%s</bootloader_args>\n",val);
+ VIR_FREE(val);
+ }
+ unsigned long memory=0;
+ memory = xenapiDomainGetMaxMemory(dom);
+ virBufferVSprintf(&buf," <memory>%lu</memory>\n",memory);
+ int64_t dynamic_mem=0;
+ if (xen_vm_get_memory_dynamic_max(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &dynamic_mem, vm)) {
+ virBufferVSprintf(&buf," <currentmemory>%lld</currentmemory>\n",(dynamic_mem/1024));
+ } else {
+ virBufferVSprintf(&buf," <currentmemory>%lu</currentmemory>\n",memory);
+ }
+ virBufferVSprintf(&buf," <vcpu>%d</vcpu>\n",xenapiDomainGetMaxVcpus(dom));
+ enum xen_on_normal_exit action;
+ if (xen_vm_get_actions_after_shutdown(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &action, vm)) {
+ virBufferEscapeString(&buf," <on_poweroff>%s</on_poweroff>\n",xen_on_normal_exit_to_string(action));
+ }
+ if (xen_vm_get_actions_after_reboot(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &action, vm)) {
+ virBufferEscapeString(&buf," <on_reboot>%s</on_reboot>\n",xen_on_normal_exit_to_string(action));
+ }
+ enum xen_on_crash_behaviour crash;
+ if (xen_vm_get_actions_after_crash(((struct _xenapiPrivate *)(dom->conn->privateData))->session, &crash, vm)) {
+ virBufferEscapeString(&buf," <on_crash>%s</on_crash>\n",xen_on_crash_behaviour_to_string(crash));
+ }
+ xen_vm_get_platform(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &result, vm);
+ if (result!=NULL) {
+ int i;
+ virBufferAddLit(&buf, " <features>\n");
+ for(i=0; i< (result->size); i++) {
+ if (STREQ(result->contents[i].val,"true")) {
+ virBufferVSprintf(&buf," <%s/>\n",result->contents[i].key);
+ }
+ }
+ virBufferAddLit(&buf, " </features>\n");
+ xen_string_string_map_free(result);
+ }
+ struct xen_vif_set *vif_set=NULL;
+ xen_vm_get_vifs(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vif_set, vm);
+ if (vif_set) {
+ int i;
+ xen_vif vif;
+ xen_vif_record *vif_rec=NULL;
+ xen_network network;
+ char *bridge=NULL;
+ for (i=0; i<vif_set->size; i++) {
+ virBufferAddLit(&buf, " <interface type='bridge'>\n");
+ vif = vif_set->contents[i];
+ xen_vif_get_network(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &network, vif);
+ if (network!=NULL) {
+ xen_network_get_bridge(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &bridge, network);
+ if (bridge!=NULL) {
+ virBufferEscapeString(&buf," <source bridge='%s' />\n",bridge);
+ VIR_FREE(bridge);
+ }
+ xen_network_free(network);
+ }
+ xen_vif_get_record(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vif_rec, vif);
+ if (vif_rec!=NULL) {
+ virBufferEscapeString(&buf," <mac address='%s' />\n", vif_rec->mac);
+ xen_vif_record_free(vif_rec);
+ }
+ virBufferAddLit(&buf, " </interface>\n");
+ }
+ xen_vif_set_free(vif_set);
+ }
+ virBufferAddLit(&buf, "</domain>");
+ if (vms) xen_vm_set_free(vms);
+ return virBufferContentAndReset(&buf);
+}
+
+static char *
+xenapiDomainXMLFromNative(virConnectPtr conn,
+ const char *format ATTRIBUTE_UNUSED,
+ const char *config ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return NULL;
+}
+
+
+static char *
+xenapiDomainXMLToNative(virConnectPtr conn,
+ const char *format ATTRIBUTE_UNUSED,
+ const char *xmlData ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return NULL;
+}
+
+/*
+* xenapiListDefinedDomains
+*
+* list the defined but inactive domains, stores the pointers to the names in @names
+* Returns number of names provided in the array or -1 in case of error
+*/
+static int
+xenapiListDefinedDomains (virConnectPtr conn, char **const names,
+ int maxnames)
+{
+ int i,j=0,doms;
+ xen_vm_set *result;
+ xen_vm_record *record;
+ xen_vm_get_all(((struct _xenapiPrivate *)(conn->privateData))->session, &result);
+ if (result != NULL) {
+ for (i=0; i< (result->size) && j< maxnames; i++) {
+ xen_vm_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &record, result->contents[i]);
+ if ( record!=NULL ) {
+ if ( record->is_a_template == 0 ) {
+ char *usenames;
+ usenames = strdup(record->name_label);
+ names[j++]=usenames;
+ }
+ xen_vm_record_free(record);
+ } else {
+ xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get VM record", __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(result);
+ return -1;
+ }
+ }
+ doms=j;
+ xen_vm_set_free(result);
+ return doms;
+ }
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiNumOfDefinedDomains
+*
+* Provides the number of defined but inactive domains
+* Returns number of domains found on success or -1 in case of error
+*/
+static int
+xenapiNumOfDefinedDomains (virConnectPtr conn)
+{
+ xen_vm_set *result;
+ xen_vm_record *record;
+ int DomNum=0,i;
+ xen_vm_get_all(((struct _xenapiPrivate *)(conn->privateData))->session, &result);
+ if ( result != NULL) {
+ for ( i=0; i< (result->size); i++ ) {
+ xen_vm_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &record, result->contents[i]);
+ if (record==NULL && !(((struct _xenapiPrivate *)(conn->privateData))->session->ok)) {
+ xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(result);
+ return -1;
+ }
+ if (record->is_a_template == 0)
+ DomNum++;
+ xen_vm_record_free(record);
+ }
+ xen_vm_set_free(result);
+ return DomNum;
+ }
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DEVICE, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainCreate
+*
+* starts a VM
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainCreate (virDomainPtr dom)
+{
+ xen_vm_set *vms;
+ xen_vm vm;
+ xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name);
+ if (vms!=NULL && vms->size!=0) {
+ vm = vms->contents[0];
+ if (!xen_vm_start(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm, false, false)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ return -1;
+ }
+ xen_vm_set_free(vms);
+ } else {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ return 0;
+}
+
+/*
+* xenapiDomainDefineXML
+*
+* Defines a domain from the given XML but does not start it
+* Returns 0 on success or -1 in case of error
+*/
+static virDomainPtr
+xenapiDomainDefineXML (virConnectPtr conn, const char *xml)
+{
+ xen_vm_record *record=NULL;
+ xen_vm vm=NULL;
+ virDomainPtr domP=NULL;
+ if(createVMRecordFromXml( conn, xml, &record, &vm)!=0) {
+ if (!(((struct _xenapiPrivate *)(conn->privateData))->session->ok))
+ xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ else
+ xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get VM information from XML",
+ __FILE__, __FUNCTION__, __LINE__);
+ return NULL;
+ }
+ if (record!=NULL) {
+ unsigned char raw_uuid[RAW_UUID_BUFLEN];
+ virUUIDParse(record->uuid,raw_uuid);
+ domP = virGetDomain(conn, record->name_label, raw_uuid);
+ if (domP==NULL && !(((struct _xenapiPrivate *)(conn->privateData))->session->ok))
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_record_free(record);
+ }
+ else if (vm!=NULL)
+ xen_vm_free(vm);
+ return domP;
+}
+
+/*
+* xenapiDomainUndefine
+*
+* destroys a domain
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainUndefine (virDomainPtr dom)
+{
+ struct xen_vm_set *vms;
+ xen_vm vm;
+ if (!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ vm = vms->contents[0];
+ if (!xen_vm_destroy(((struct _xenapiPrivate *)(dom->conn->privateData))->session, vm)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ return -1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+static int
+xenapiDomainAttachDevice (virDomainPtr dom, const char *xml ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainDetachDevice (virDomainPtr dom, const char *xml ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiDomainGetAutostart
+*
+* Provides a boolean value indicating whether the domain configured
+* to be automatically started when the host machine boots
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainGetAutostart (virDomainPtr dom, int *autostart)
+{
+ int i,flag=0;
+ xen_vm_set *vms;
+ xen_vm vm;
+ xen_string_string_map *result;
+ if(!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ vm = vms->contents[0];
+ if (!xen_vm_get_other_config(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &result, vm)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ return -1;
+ }
+ for (i=0; i < result->size; i++) {
+ if (STREQ(result->contents[i].key, "auto_poweron")) {
+ flag=1;
+ if (STREQ(result->contents[i].val, "true"))
+ *autostart = 1;
+ else
+ *autostart = 0;
+ }
+ }
+ xen_vm_set_free(vms);
+ xen_string_string_map_free(result);
+ if (flag==0) return -1;
+ return 0;
+}
+
+/*
+* xenapiDomainSetAutostart
+*
+* Configure the domain to be automatically started when the host machine boots
+* Return 0 on success or -1 in case of error
+*/
+static int
+xenapiDomainSetAutostart (virDomainPtr dom, int autostart)
+{
+ xen_vm_set *vms;
+ xen_vm vm;
+ char *value;
+ if (!xen_vm_get_by_name_label(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ &vms, dom->name)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ vm = vms->contents[0];
+ xen_vm_remove_from_other_config(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ vm, (char *)"auto_poweron");
+ if (autostart==1)
+ value = (char *)"true";
+ else
+ value = (char *)"false";
+ if (!xen_vm_add_to_other_config(((struct _xenapiPrivate *)(dom->conn->privateData))->session,
+ vm, (char *)"auto_poweron", value)) {
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR, NULL, __FILE__, __FUNCTION__, __LINE__);
+ xen_vm_set_free(vms);
+ return -1;
+ }
+ xen_vm_set_free(vms);
+ return 0;
+}
+
+static char *
+xenapiDomainGetSchedulerType (virDomainPtr dom ATTRIBUTE_UNUSED, int *nparams)
+{
+ *nparams = 0;
+ return (char *)"credit";
+}
+
+static int
+xenapiDomainGetSchedulerParameters (virDomainPtr dom,
+ virSchedParameterPtr params ATTRIBUTE_UNUSED,
+ int *nparams ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainSetSchedulerParameters (virDomainPtr dom,
+ virSchedParameterPtr params ATTRIBUTE_UNUSED,
+ int nparams ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainMigratePrepare (virConnectPtr dconn,
+ char **cookie ATTRIBUTE_UNUSED,
+ int *cookielen ATTRIBUTE_UNUSED,
+ const char *uri_in ATTRIBUTE_UNUSED,
+ char **uri_out ATTRIBUTE_UNUSED,
+ unsigned long flags ATTRIBUTE_UNUSED,
+ const char *dname ATTRIBUTE_UNUSED,
+ unsigned long resource ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dconn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainMigratePerform (virDomainPtr dom,
+ const char *cookie ATTRIBUTE_UNUSED,
+ int cookielen ATTRIBUTE_UNUSED,
+ const char *uri ATTRIBUTE_UNUSED,
+ unsigned long flags ATTRIBUTE_UNUSED,
+ const char *dname ATTRIBUTE_UNUSED,
+ unsigned long resource ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static virDomainPtr
+xenapiDomainMigrateFinish (virConnectPtr dconn,
+ const char *dname,
+ const char *cookie ATTRIBUTE_UNUSED,
+ int cookielen ATTRIBUTE_UNUSED,
+ const char *uri ATTRIBUTE_UNUSED,
+ unsigned long flags ATTRIBUTE_UNUSED)
+{
+ return xenapiDomainLookupByName (dconn, dname);
+}
+
+static int
+xenapiDomainBlockStats (virDomainPtr dom, const char *path ATTRIBUTE_UNUSED,
+ struct _virDomainBlockStats *stats ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainInterfaceStats (virDomainPtr dom, const char *path ATTRIBUTE_UNUSED,
+ struct _virDomainInterfaceStats *stats ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainBlockPeek (virDomainPtr dom, const char *path ATTRIBUTE_UNUSED,
+ unsigned long long offset ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED,
+ void *buffer ATTRIBUTE_UNUSED, unsigned int flags ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/*
+* xenapiNodeGetFreeMemory
+*
+* provides the free memory available on the Node
+* Returns memory size on success or 0 in case of error
+*/
+static unsigned long long
+xenapiNodeGetFreeMemory (virConnectPtr conn)
+{
+ xen_host_metrics_set *xen_met_set;
+ unsigned long long freeMem=0;
+ xen_host_metrics_get_all(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &xen_met_set);
+ if (xen_met_set != NULL) {
+ if (!xen_host_metrics_get_memory_free(((struct _xenapiPrivate *)(conn->privateData))->session,
+ (int64_t *)&freeMem, xen_met_set->contents[0])) {
+ xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get host metrics - memory information",
+ __FILE__, __FUNCTION__, __LINE__);
+ freeMem=0;
+ }
+ xen_host_metrics_set_free(xen_met_set);
+ } else {
+ xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, "Couldn't get host metrics",
+ __FILE__, __FUNCTION__, __LINE__);
+ }
+ return freeMem;
+}
+
+/*
+* xenapiNodeGetCellsFreeMemory
+*
+*
+* Returns the number of entries filled in freeMems, or -1 in case of error.
+*/
+static int
+xenapiNodeGetCellsFreeMemory (virConnectPtr conn, unsigned long long *freeMems ATTRIBUTE_UNUSED,
+ int startCell, int maxCells)
+{
+ if (maxCells >1 && startCell >0) {
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ } else {
+ freeMems[0] = xenapiNodeGetFreeMemory(conn);
+ return 1;
+ }
+}
+
+
+static int
+xenapiDomainEventRegister (virConnectPtr conn,
+ virConnectDomainEventCallback callback ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED,
+ void (*freefunc)(void *) ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiDomainEventDeregister (virConnectPtr conn,
+ virConnectDomainEventCallback callback ATTRIBUTE_UNUSED)
+{
+ xenapiSessionErrorHandler(conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiNodeDeviceDettach (virNodeDevicePtr dev)
+{
+ xenapiSessionErrorHandler(dev->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiNodeDeviceReAttach (virNodeDevicePtr dev)
+{
+ xenapiSessionErrorHandler(dev->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+static int
+xenapiNodeDeviceReset (virNodeDevicePtr dev)
+{
+ xenapiSessionErrorHandler(dev->conn, VIR_ERR_NO_SUPPORT, "", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+}
+
+/* The interface which we export upwards to libvirt.c. */
+static virDriver xenapiDriver = {
+ VIR_DRV_XENAPI,
+ "XenAPI",
+ xenapiOpen, /* open */
+ xenapiClose, /* close */
+ xenapiSupportsFeature, /* supports_feature */
+ xenapiType, /* type */
+ xenapiGetVersion, /* version */
+ NULL, /*getlibvirtVersion */
+ xenapiGetHostname, /* getHostname */
+ xenapiGetMaxVcpus, /* getMaxVcpus */
+ xenapiNodeGetInfo, /* nodeGetInfo */
+ xenapiGetCapabilities, /* getCapabilities */
+ xenapiListDomains, /* listDomains */
+ xenapiNumOfDomains, /* numOfDomains */
+ xenapiDomainCreateXML, /* domainCreateXML */
+ xenapiDomainLookupByID, /* domainLookupByID */
+ xenapiDomainLookupByUUID, /* domainLookupByUUID */
+ xenapiDomainLookupByName, /* domainLookupByName */
+ xenapiDomainSuspend, /* domainSuspend */
+ xenapiDomainResume, /* domainResume */
+ xenapiDomainShutdown, /* domainShutdown */
+ xenapiDomainReboot, /* domainReboot */
+ xenapiDomainDestroy, /* domainDestroy */
+ xenapiDomainGetOSType, /* domainGetOSType */
+ xenapiDomainGetMaxMemory, /* domainGetMaxMemory */
+ xenapiDomainSetMaxMemory, /* domainSetMaxMemory */
+ xenapiDomainSetMemory, /* domainSetMemory */
+ xenapiDomainGetInfo, /* domainGetInfo */
+ xenapiDomainSave, /* domainSave */
+ xenapiDomainRestore, /* domainRestore */
+ xenapiDomainCoreDump, /* domainCoreDump */
+ xenapiDomainSetVcpus, /* domainSetVcpus */
+ xenapiDomainPinVcpu, /* domainPinVcpu */
+ xenapiDomainGetVcpus, /* domainGetVcpus */
+ xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel */
+ NULL, /* nodeGetSecurityModel */
+ xenapiDomainDumpXML, /* domainDumpXML */
+ xenapiDomainXMLFromNative, /* domainXmlFromNative */
+ xenapiDomainXMLToNative, /* domainXmlToNative */
+ xenapiListDefinedDomains, /* listDefinedDomains */
+ xenapiNumOfDefinedDomains, /* numOfDefinedDomains */
+ xenapiDomainCreate, /* domainCreate */
+ xenapiDomainDefineXML, /* domainDefineXML */
+ xenapiDomainUndefine, /* domainUndefine */
+ xenapiDomainAttachDevice, /* domainAttachDevice */
+ NULL,
+ xenapiDomainDetachDevice, /* domainDetachDevice */
+ NULL,
+ xenapiDomainGetAutostart, /* domainGetAutostart */
+ xenapiDomainSetAutostart, /* domainSetAutostart */
+ xenapiDomainGetSchedulerType, /* domainGetSchedulerType */
+ xenapiDomainGetSchedulerParameters, /* domainGetSchedulerParameters */
+ xenapiDomainSetSchedulerParameters, /* domainSetSchedulerParameters */
+ xenapiDomainMigratePrepare, /* domainMigratePrepare */
+ xenapiDomainMigratePerform, /* domainMigratePerform */
+ xenapiDomainMigrateFinish, /* domainMigrateFinish */
+ xenapiDomainBlockStats, /* domainBlockStats */
+ xenapiDomainInterfaceStats, /* domainInterfaceStats */
+ NULL,
+ xenapiDomainBlockPeek, /* domainBlockPeek */
+ NULL, /* domainMemoryPeek */
+ xenapiNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
+ xenapiNodeGetFreeMemory, /* getFreeMemory */
+ xenapiDomainEventRegister, /* domainEventRegister */
+ xenapiDomainEventDeregister, /* domainEventDeregister */
+ NULL, /* domainMigratePrepare2 */
+ NULL, /* domainMigrateFinish2 */
+ xenapiNodeDeviceDettach, /* nodeDeviceDettach */
+ xenapiNodeDeviceReAttach, /* nodeDeviceReAttach */
+ xenapiNodeDeviceReset, /* nodeDeviceReset */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+/**
+ * xenapiRegister:
+ *
+ *
+ * Returns the driver priority or -1 in case of error.
+ */
+int
+xenapiRegister (void)
+{
+ return virRegisterDriver (&xenapiDriver);
+}
+
+/*
+* write_func
+* used by curl to read data from the server
+*/
+size_t
+write_func(void *ptr, size_t size, size_t nmemb, void *comms_)
+{
+ xen_comms *comms = comms_;
+ size_t n = size * nmemb;
+ #ifdef PRINT_XML
+ printf("\n\n---Result from server -----------------------\n");
+ printf("%s\n",((char*) ptr));
+ fflush(stdout);
+ #endif
+ return (size_t) (comms->func(ptr, n, comms->handle) ? n : 0);
+}
+
+/*
+* call_func
+* sets curl options, used with xen_session_login_with_password
+*/
+int
+call_func(const void *data, size_t len, void *user_handle,
+ void *result_handle, xen_result_func result_func)
+{
+ (void)user_handle;
+ #ifdef PRINT_XML
+
+ printf("\n\n---Data to server: -----------------------\n");
+ printf("%s\n",((char*) data));
+ fflush(stdout);
+ #endif
+ CURL *curl = curl_easy_init();
+ if (!curl) {
+ return -1;
+ }
+ xen_comms comms = {
+ .func = result_func,
+ .handle = result_handle
+ };
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+ //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+ #ifdef CURLOPT_MUTE
+ curl_easy_setopt(curl, CURLOPT_MUTE, 1);
+ #endif
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);
+ curl_easy_setopt(curl, CURLOPT_POST, 1);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
+ CURLcode result = curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+ return result;
+}
+
+
+
+
diff -Nur ./libvirt_org/src/xenapi/xenapi_driver.h ./libvirt/src/xenapi/xenapi_driver.h
--- ./libvirt_org/src/xenapi/xenapi_driver.h 1970-01-01 01:00:00.000000000 +0100
+++ ./libvirt/src/xenapi/xenapi_driver.h 2010-02-18 15:37:49.000000000 +0000
@@ -0,0 +1,44 @@
+/*
+ * xenapi.c: Xen API driver.
+ * Copyright (C) 2009 Citrix Ltd.
+ * Sharadha Prabhakar <sharadha.prabhakar(a)citrix.com>
+ */
+
+
+#ifndef __VIR_XENAPI_H__
+#define __VIR_XENAPI_H__
+
+#include <xen/api/xen_common.h>
+#include <libxml/tree.h>
+
+//#define PRINT_XML
+#define RAW_UUID_BUFLEN (16)
+#define LIBVIRT_MODELNAME_LEN (32)
+
+
+extern int xenapiRegister (void);
+
+typedef struct
+{
+ xen_result_func func;
+ void *handle;
+} xen_comms;
+
+
+
+int
+call_func(const void *data, size_t len, void *user_handle,
+ void *result_handle, xen_result_func result_func);
+size_t
+write_func(void *ptr, size_t size, size_t nmemb, void *comms);
+
+/* xenAPI driver's private data structure */
+struct _xenapiPrivate {
+ xen_session *session;
+ void *handle;
+ char *uname;
+ char *pwd;
+ xen_api_version version;
+};
+
+#endif /* __VIR_XENAPI_H__ */
1
0
18 Feb '10
diff -Nur ./libvirt_org/src/xenapi/xenapi_utils.c ./libvirt/src/xenapi/xenapi_utils.c
--- ./libvirt_org/src/xenapi/xenapi_utils.c 1970-01-01 01:00:00.000000000 +0100
+++ ./libvirt/src/xenapi/xenapi_utils.c 2010-02-18 16:26:52.000000000 +0000
@@ -0,0 +1,507 @@
+/*
+ * xenapi_utils.c: Xen API driver -- utils parts.
+ * Copyright (C) 2009 Citrix Ltd.
+ * Sharadha Prabhakar <sharadha.prabhakar(a)citrix.com>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <config.h>
+
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <libxml/uri.h>
+#include <xen_internal.h>
+#include <libxml/parser.h>
+#include <curl/curl.h>
+#include <xen/api/xen_common.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_all.h>
+#include <xen/api/xen_vm_metrics.h>
+
+#include "libvirt_internal.h"
+#include "libvirt/libvirt.h"
+#include "virterror_internal.h"
+#include "datatypes.h"
+#include "xenapi_driver.h"
+#include "util.h"
+#include "uuid.h"
+#include "memory.h"
+#include "driver.h"
+#include "buf.h"
+#include "xenapi_utils.h"
+
+/* returns 'file' or 'block' for the storage type */
+int
+getStorageVolumeType(char *type)
+{
+ if((STREQ(type,"lvmoiscsi")) ||
+ (STREQ(type,"lvmohba")) ||
+ (STREQ(type,"lvm")) ||
+ (STREQ(type,"file")) ||
+ (STREQ(type,"iso")) ||
+ (STREQ(type,"ext")) ||
+ (STREQ(type,"nfs")))
+ return (int)VIR_STORAGE_VOL_FILE;
+ else if((STREQ(type,"iscsi")) ||
+ (STREQ(type,"equal")) ||
+ (STREQ(type,"hba")) ||
+ (STREQ(type,"cslg")) ||
+ (STREQ(type,"udev")) ||
+ (STREQ(type,"netapp")))
+ return (int)VIR_STORAGE_VOL_BLOCK;
+ return -1;
+}
+
+/* returns error description if any received from the server */
+char *
+returnErrorFromSession(xen_session *session)
+{
+ int i;
+ char *buf = NULL;
+ for (i=0; i<session->error_description_count-1; i++) {
+ if (buf==NULL) {
+ buf = (char *)realloc(buf,strlen(session->error_description[i])+1);
+ strcpy(buf,session->error_description[i]);
+ } else {
+ buf = (char *)realloc(buf,strlen(buf)+strlen(session->error_description[i])+2);
+ strcat(buf,":");
+ strcat(buf,session->error_description[i]);
+ }
+ }
+ return buf;
+}
+
+/* XenAPI error handler - internally calls libvirt error handler after clearing error
+flag in session */
+void xenapiSessionErrorHandler(virConnectPtr conn, virErrorNumber errNum,
+ const char *buf, const char *filename, const char *func, size_t lineno)
+{
+ if (buf==NULL) {
+ char *ret=NULL;
+ ret = returnErrorFromSession(((struct _xenapiPrivate *)(conn->privateData))->session);
+ virReportErrorHelper (conn, VIR_FROM_XENAPI, errNum, filename, func, lineno, _("%s\n"), ret);
+ xen_session_clear_error(((struct _xenapiPrivate *)(conn->privateData))->session);
+ VIR_FREE(ret);
+ } else {
+ virReportErrorHelper (conn, VIR_FROM_XENAPI, errNum, filename, func, lineno, _("%s\n"), buf);
+ }
+}
+
+/* converts bitmap to string of the form '1,2...' */
+char *
+mapDomainPinVcpu(unsigned int vcpu, unsigned char *cpumap, int maplen)
+{
+ char buf[VIR_UUID_BUFLEN], mapstr[sizeof(cpumap_t) * 64];
+ char *ret=NULL;
+ int i, j;
+ mapstr[0] = 0;
+ for (i = 0; i < maplen; i++) {
+ for (j = 0; j < 8; j++) {
+ if (cpumap[i] & (1 << j)) {
+ snprintf(buf, sizeof(buf), "%d,", (8 * i) + j);
+ strcat(mapstr, buf);
+ }
+ }
+ }
+ mapstr[strlen(mapstr) - 1] = 0;
+ snprintf(buf, sizeof(buf), "%d", vcpu);
+ ret = strdup(mapstr);
+ return ret;
+}
+
+/* obtains the CPU bitmap from the string passed */
+void
+getCpuBitMapfromString(char *mask, unsigned char *cpumap, int maplen)
+{
+ int pos;
+ int max_bits = maplen * 8;
+ char *num = NULL;
+ bzero(cpumap, maplen);
+ num = strtok (mask, ",");
+ while (num != NULL) {
+ sscanf (num, "%d", &pos);
+ if (pos<0 || pos>max_bits-1)
+ printf ("number in str %d exceeds cpumap's max bits %d\n", pos, max_bits);
+ else
+ (cpumap)[pos/8] |= (1<<(pos%8));
+ num = strtok (NULL, ",");
+ }
+}
+
+
+/* mapping XenServer power state to Libvirt power state */
+virDomainState
+mapPowerState(enum xen_vm_power_state state)
+{
+ virDomainState virState;
+ switch (state) {
+ case (XEN_VM_POWER_STATE_HALTED):
+ case (XEN_VM_POWER_STATE_SUSPENDED):
+ virState = VIR_DOMAIN_SHUTOFF;
+ break;
+ case (XEN_VM_POWER_STATE_PAUSED):
+ virState = VIR_DOMAIN_PAUSED;
+ break;
+ case (XEN_VM_POWER_STATE_RUNNING):
+ virState = VIR_DOMAIN_RUNNING;
+ break;
+ case (XEN_VM_POWER_STATE_UNKNOWN):
+ case (XEN_VM_POWER_STATE_UNDEFINED):
+ virState = VIR_DOMAIN_NOSTATE;
+ break;
+ default:
+ virState = VIR_DOMAIN_NOSTATE;
+ break;
+ }
+ return virState;
+}
+
+/* Gets the value of the child for the current node passed */
+char *
+getXmlChildValue(xmlDocPtr doc, xmlNodePtr cur, const char *tag)
+{
+ char *key = NULL;
+ cur = cur->xmlChildrenNode;
+ while (cur != NULL) {
+ if ((!xmlStrcmp(cur->name, (const xmlChar *)tag))){
+ cur = cur->xmlChildrenNode;
+ key = (char *)xmlNodeListGetString(doc,cur,1);
+ }
+ cur = cur->next;
+ }
+ return key;
+}
+
+/* allocate a flexible array and fill values(key,val) */
+int
+allocStringMap (xen_string_string_map **strings, char *key, char *val)
+{
+ int sz = ((*strings) == NULL)?0:(*strings)->size;
+ sz++;
+ *strings = realloc(*strings,sizeof(xen_string_string_map)+
+ sizeof(xen_string_string_map_contents)*sz);
+ (*strings)->size = sz;
+ (*strings)->contents[sz-1].key = strdup(key);
+ (*strings)->contents[sz-1].val = strdup(val);
+ return 0;
+}
+
+/* create boot order string as understood by libvirt */
+void
+createXmlBootOrderString(char **order, char *key)
+{
+ int sz = ((*order)==NULL)?0:(strlen(*order)+1);
+ const char *temp=NULL;
+ if (strcmp(key,"fd")==0)
+ temp="a";
+ else if (strcmp(key,"hd")==0)
+ temp="c";
+ else if (strcmp(key,"cdrom")==0)
+ temp="d";
+ else if (strcmp(key,"network")==0)
+ temp="n";
+ if (temp!=NULL) {
+ *order = (char *)realloc(*order,sz+strlen(temp)+1);
+ if(sz==0) strcpy(*order,temp);
+ else strcat(*order,temp);
+ }
+}
+
+enum xen_on_normal_exit
+actionShutdownStringtoEnum(char *str)
+{
+ enum xen_on_normal_exit code = XEN_ON_NORMAL_EXIT_UNDEFINED;
+ if (STREQ(str, "destroy"))
+ code = XEN_ON_NORMAL_EXIT_DESTROY;
+ else if (STREQ(str, "restart"))
+ code = XEN_ON_NORMAL_EXIT_RESTART;
+ return code;
+}
+
+enum xen_on_crash_behaviour
+actionCrashStringtoEnum(char *str)
+{
+ enum xen_on_crash_behaviour code = XEN_ON_CRASH_BEHAVIOUR_UNDEFINED;
+ if (STREQ(str, "destroy"))
+ code = XEN_ON_CRASH_BEHAVIOUR_DESTROY;
+ else if (STREQ(str, "restart"))
+ code = XEN_ON_CRASH_BEHAVIOUR_RESTART;
+ else if (STREQ(str, "preserve"))
+ code = XEN_ON_CRASH_BEHAVIOUR_PRESERVE;
+ else if (STREQ(str, "rename-restart"))
+ code = XEN_ON_CRASH_BEHAVIOUR_RENAME_RESTART;
+ return code;
+}
+
+/* convert boot order string libvirt format to XenServer format */
+const char *
+mapXmlBootOrder(char c) {
+ switch(c) {
+ case 'a':
+ return "fd";
+ case 'c':
+ return "hd";
+ case 'd':
+ return "cdrom";
+ case 'n':
+ return "network";
+ default:
+ return NULL;
+ }
+}
+
+/* creates network intereface for VM */
+int
+createVifNetwork (virConnectPtr conn, xen_vm vm, char *device,
+ char *bridge, char *mac)
+{
+ xen_vm xvm = NULL;
+ char *uuid = NULL;
+ xen_vm_get_uuid(((struct _xenapiPrivate *)(conn->privateData))->session, &uuid, vm);
+ if (uuid) {
+ if(!xen_vm_get_by_uuid(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &xvm, uuid))
+ return -1;
+ VIR_FREE(uuid);
+ }
+ xen_vm_record_opt *vm_opt = xen_vm_record_opt_alloc();
+ vm_opt->is_record = 0;
+ vm_opt->u.handle = xvm;
+ xen_network_set *net_set = NULL;
+ xen_network_record *net_rec = NULL;
+ int cnt=0;
+ if (xen_network_get_all(((struct _xenapiPrivate *)(conn->privateData))->session, &net_set)) {
+ for(cnt=0;cnt<(net_set->size);cnt++) {
+ if (xen_network_get_record(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &net_rec, net_set->contents[cnt])) {
+ if (STREQ(net_rec->bridge,bridge)) {
+ break;
+ } else {
+ xen_network_record_free(net_rec);
+ }
+ }
+ }
+ }
+ if ( (cnt<net_set->size) && net_rec) {
+ xen_network network = NULL;
+ xen_network_get_by_uuid(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &network, net_rec->uuid);
+ xen_network_record_opt *network_opt = xen_network_record_opt_alloc();
+ network_opt->is_record = 0;
+ network_opt->u.handle = network;
+ xen_vif_record *vif_record = xen_vif_record_alloc();
+ vif_record->mac = mac;
+ vif_record->vm = vm_opt;
+ vif_record->network = network_opt;
+ xen_vif vif=NULL;
+
+ vif_record->other_config = xen_string_string_map_alloc(0);
+ vif_record->runtime_properties = xen_string_string_map_alloc(0);
+ vif_record->qos_algorithm_params = xen_string_string_map_alloc(0);
+ vif_record->device = strdup(device);
+ xen_vif_create(((struct _xenapiPrivate *)(conn->privateData))->session,
+ &vif, vif_record);
+ if (vif!=NULL) {
+ xen_vif_free(vif);
+ xen_vif_record_free(vif_record);
+ xen_network_record_free(net_rec);
+ xen_network_set_free(net_set);
+ return 0;
+ }
+ xen_vif_record_free(vif_record);
+ xen_network_record_free(net_rec);
+ }
+ if (net_set!=NULL) xen_network_set_free(net_set);
+ return -1;
+}
+
+/* Create a VM record from the XML description */
+int
+createVMRecordFromXml (virConnectPtr conn, const char *xmlDesc,
+ xen_vm_record **record, xen_vm *vm)
+{
+ xmlDocPtr doc;
+ xmlNodePtr cur,child,temp;
+ doc = xmlParseMemory(xmlDesc,strlen(xmlDesc));
+ if (doc == NULL) {
+ xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"", __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ cur = xmlDocGetRootElement(doc);
+ if (cur == NULL) {
+ xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"", __FILE__, __FUNCTION__, __LINE__);
+ xmlFreeDoc(doc);
+ return -1;
+ }
+ if (xmlStrcmp(cur->name, (const xmlChar *) "domain")) {
+ xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"root node not domain", __FILE__, __FUNCTION__, __LINE__);
+ xmlFreeDoc(doc);
+ return -1;
+ }
+ *record = xen_vm_record_alloc();
+ char *name = getXmlChildValue(doc,cur,"name");
+ (*record)->name_label = strdup(name);
+ child = cur->xmlChildrenNode;
+ while (child!=NULL) {
+ if ((!xmlStrcmp(child->name, (const xmlChar *)"os"))) {
+ char *ostype = getXmlChildValue(doc,child,"type");
+ if (ostype!=NULL) {
+ if (STREQ(ostype,"hvm")) {
+ (*record)->hvm_boot_policy = strdup("BIOS order");
+ temp = child;
+ child = child->xmlChildrenNode;
+ char *boot_order = NULL;
+ while (child != NULL) {
+ if ((!xmlStrcmp(child->name, (const xmlChar *)"boot"))){
+ xmlChar *key;
+ key = xmlGetProp(child, (const xmlChar *)"dev");
+ if (key!=NULL) {
+ createXmlBootOrderString(&boot_order,(char *)key);
+ xmlFree(key);
+ }
+ }
+ child = child->next;
+ }
+ if (boot_order!=NULL) {
+ xen_string_string_map *hvm_boot_params=NULL;
+ allocStringMap(&hvm_boot_params, (char *)"order",boot_order);
+ //int size = sizeof(xen_string_string_map) +
+ // (hvm_boot_params->size * sizeof(xen_string_string_map_contents));
+ //(*record)->hvm_boot_params = (xen_string_string_map *) malloc(size);
+ //memcpy((char *)(*record)->hvm_boot_params, (char *)hvm_boot_params, size);
+ (*record)->hvm_boot_params = hvm_boot_params;
+ VIR_FREE(boot_order);
+ //freeStringMap(hvm_boot_params);
+ }
+ child = temp;
+ } else if (STREQ(ostype,"linux")) {
+ (*record)->pv_bootloader = strdup("pygrub");
+ char *kernel = getXmlChildValue(doc,child,"kernel");
+ if (kernel != NULL){
+ (*record)->pv_kernel = kernel;
+ //strcpy((*record)->pv_kernel,kernel);
+ //free(kernel);
+ }
+ char *initrd = getXmlChildValue(doc,child,"initrd");
+ if (initrd != NULL) {
+ (*record)->pv_ramdisk = initrd;//(char *)malloc(strlen(initrd)+1);
+ //strcpy((*record)->pv_ramdisk,initrd);
+ //free(initrd);
+ }
+ char *cmdline = getXmlChildValue(doc,child,"cmdline");
+ if (cmdline != NULL) {
+ (*record)->pv_args = cmdline; //(char *)malloc(strlen(cmdline)+1);
+ //strcpy((*record)->pv_args,cmdline);
+ //free(cmdline);
+ }
+ (*record)->hvm_boot_params = xen_string_string_map_alloc(0);
+ }
+ VIR_FREE(ostype);
+ }
+ }
+ child = child->next;
+ }
+ char *bootload_args = getXmlChildValue(doc,cur,"bootloader_args");
+ if (bootload_args!=NULL) {
+ (*record)->pv_bootloader_args =bootload_args; //(char *)malloc(strlen(bootload_args)+1);
+ //strcpy((*record)->pv_bootloader_args,bootload_args);
+ //free(bootload_args);
+ }
+ char *memory = getXmlChildValue(doc,cur,"memory");
+ if (memory!=NULL) {
+ int64_t static_max=0;
+ static_max = atoll(memory);
+ (*record)->memory_static_max = static_max * 1024;
+ VIR_FREE(memory);
+ }
+ char *curmemory = getXmlChildValue(doc,cur,"currentmemory");
+ if (curmemory!=NULL) {
+ int64_t dy_max=0;
+ dy_max = atoll(curmemory);
+ (*record)->memory_dynamic_max = dy_max * 1024;
+ VIR_FREE(curmemory);
+ } else {
+ (*record)->memory_dynamic_max = (*record)->memory_static_max;
+ }
+ char *vcpu = getXmlChildValue(doc, cur, "vcpu");
+ if (vcpu!=NULL) {
+ (*record)->vcpus_max = atoll(vcpu);
+ (*record)->vcpus_at_startup = atoll(vcpu);
+ VIR_FREE(vcpu);
+ }
+ char *on_poweroff = getXmlChildValue(doc,cur,"on_poweroff");
+ if (on_poweroff!=NULL) {
+ (*record)->actions_after_shutdown = actionShutdownStringtoEnum(on_poweroff);
+ VIR_FREE(on_poweroff);
+ }
+ char *on_reboot = getXmlChildValue(doc,cur,"on_reboot");
+ if (on_reboot!=NULL) {
+ (*record)->actions_after_reboot = actionShutdownStringtoEnum(on_reboot);
+ VIR_FREE(on_reboot);
+ }
+ char *on_crash = getXmlChildValue(doc,cur,"on_crash");
+ if (on_crash!=NULL) {
+ (*record)->actions_after_crash = actionCrashStringtoEnum(on_crash);
+ VIR_FREE(on_crash);
+ }
+ temp = cur;
+ cur = cur->xmlChildrenNode;
+ xen_string_string_map *strings=NULL;
+ while (cur != NULL) {
+ if ((!xmlStrcmp(cur->name, (const xmlChar *)"features"))){
+ for (child=cur->children;child!=NULL;child=child->next) {
+ allocStringMap(&strings,(char *)child->name,(char *)"true");
+ }
+ }
+ cur = cur->next;
+ }
+ cur = temp;
+ if (strings!=NULL) {
+ //int size = sizeof(xen_string_string_map)+ sizeof(xen_string_string_map_contents)*strings->size;
+ (*record)->platform = strings; //(xen_string_string_map *)malloc(size);
+ //memcpy((void *)(*record)->platform,(void *)strings,size);
+ }
+ (*record)->vcpus_params = xen_string_string_map_alloc(0);
+ (*record)->other_config = xen_string_string_map_alloc(0);
+ (*record)->last_boot_cpu_flags = xen_string_string_map_alloc(0);
+ (*record)->xenstore_data = xen_string_string_map_alloc(0);
+ (*record)->hvm_shadow_multiplier = 1.000;
+ if (!xen_vm_create(((struct _xenapiPrivate *)(conn->privateData))->session,
+ vm, *record)) {
+ xmlFreeDoc(doc);
+ xenapiSessionErrorHandler(conn,VIR_ERR_INTERNAL_ERROR ,NULL, __FILE__, __FUNCTION__, __LINE__);
+ return -1;
+ }
+ cur = cur->xmlChildrenNode;
+ int device_number=0;
+ xmlChar *bridge=NULL,*mac=NULL;
+ while (cur != NULL) {
+ if ((!xmlStrcmp(cur->name, (const xmlChar *)"interface"))){
+ for (child=cur->children;child!=NULL;child=child->next) {
+ if ((!xmlStrcmp(child->name, (const xmlChar *)"source"))) {
+ bridge = xmlGetProp(child, (const xmlChar *)"bridge");
+ }
+ if ((!xmlStrcmp(child->name, (const xmlChar *)"mac"))) {
+ mac = xmlGetProp(child, (const xmlChar *)"address");
+ }
+ }
+ if (mac!=NULL && bridge!=NULL) {
+ char device[NETWORK_DEVID_SIZE]="\0";
+ sprintf(device,"%d",device_number);
+ createVifNetwork(conn, *vm, device, (char *)bridge, (char *)mac);
+ xmlFree(bridge);
+ device_number++;
+ }
+ }
+ cur = cur->next;
+ }
+ xmlFreeDoc(doc);
+ return 0;
+}
+
diff -Nur ./libvirt_org/src/xenapi/xenapi_utils.h ./libvirt/src/xenapi/xenapi_utils.h
--- ./libvirt_org/src/xenapi/xenapi_utils.h 1970-01-01 01:00:00.000000000 +0100
+++ ./libvirt/src/xenapi/xenapi_utils.h 2010-02-18 16:28:10.000000000 +0000
@@ -0,0 +1,94 @@
+/*
+ * xenapi_utils.h: Xen API driver -- utils header
+ * Copyright (C) 2009 Citrix Ltd.
+ * Sharadha Prabhakar <sharadha.prabhakar(a)citrix.com>
+ */
+
+#ifndef _VIR_XENAPI_UTILS_
+#define _VIR_XENAPI_UTILS_
+
+#include <stdio.h>
+#include <string.h>
+#include <config.h>
+
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <libxml/uri.h>
+#include <xen_internal.h>
+#include <libxml/parser.h>
+#include <curl/curl.h>
+#include <xen/api/xen_common.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_vm.h>
+#include <xen/api/xen_all.h>
+#include <xen/api/xen_vm_metrics.h>
+//#include <xen/dom0_ops.h>
+
+#include "libvirt_internal.h"
+#include "libvirt/libvirt.h"
+#include "virterror_internal.h"
+#include "datatypes.h"
+#include "xenapi_driver.h"
+#include "util.h"
+#include "uuid.h"
+#include "memory.h"
+#include "driver.h"
+#include "buf.h"
+
+#define NETWORK_DEVID_SIZE (10)
+
+typedef uint64_t cpumap_t;
+
+void getCpuBitMapfromString(char *mask, unsigned char *cpumap, int maplen);
+
+int getStorageVolumeType(char *type);
+
+char *returnErrorFromSession(xen_session *session);
+
+void xenapiSessionErrorHandler(virConnectPtr conn, virErrorNumber errNum,
+ const char *buf, const char *filename, const char *func, size_t lineno);
+
+
+virDomainState
+mapPowerState(enum xen_vm_power_state state);
+
+char *
+mapDomainPinVcpu(unsigned int vcpu, unsigned char *cpumap, int maplen);
+
+char *
+getXmlChildValue(xmlDocPtr doc, xmlNodePtr cur, const char *tag);
+
+int
+createVMRecordFromXml (virConnectPtr conn, const char *xmlDesc,
+ xen_vm_record **record, xen_vm *vm);
+
+int
+allocStringMap (xen_string_string_map **strings, char *key, char *val);
+
+void
+createXmlBootOrderString(char **order, char *key);
+
+enum xen_on_normal_exit
+actionShutdownStringtoEnum(char *str);
+
+enum xen_on_crash_behaviour
+actionCrashStringtoEnum(char *str);
+
+int
+createVifNetwork(virConnectPtr conn, xen_vm vm, char *device,
+ char *bridge, char *mac);
+
+const char *
+mapXmlBootOrder(char c);
+
+
+
+
+
+
+
+#endif //_VIR_XENAPI_UTILS_
1
0