mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
Add libxenlight driver
Add a new xen driver based on libxenlight [1], which is the primary toolstack starting with Xen 4.1.0. The driver is stateful and runs privileged only. Like the existing xen-unified driver, the libxenlight driver is accessed with xen:// URI. Driver selection is based on the status of xend. If xend is running, the libxenlight driver will not load and xen:// connections are handled by xen-unified. If xend is not running *and* the libxenlight driver is available, xen:// connections are deferred to the libxenlight driver. V6: - Address several code style issues noted by Daniel Veillard - Make drive work with xen:/// URI - Hold domain object reference while domain is injected in libvirt event loop. Race found and fixed by Markus Groß. V5: - Ensure events are unregistered when domain private data is destroyed. Discovered and fixed by Markus Groß. V4: - Handle restart of libvirtd, reconnecting to previously started domains - Rebased to current master - Tested against Xen 4.1 RC7-pre (c/s 22961:c5d121fd35c0) V3: - Reserve vnc port within driver when autoport=yes V2: - Update to Xen 4.1 RC6-pre (c/s 22940:5a4710640f81) - Rebased to current master - Plug memory leaks found by Stefano Stabellini and valgrind - Handle SHUTDOWN_crash domain death event [1] http://lists.xensource.com/archives/html/xen-devel/2009-11/msg00436.html
This commit is contained in:
parent
fba550f651
commit
2b84e445d5
1
cfg.mk
1
cfg.mk
@ -403,6 +403,7 @@ msg_gen_function += virXenStoreError
|
||||
msg_gen_function += virXendError
|
||||
msg_gen_function += vmwareError
|
||||
msg_gen_function += xenapiSessionErrorHandler
|
||||
msg_gen_function += libxlError
|
||||
msg_gen_function += xenUnifiedError
|
||||
msg_gen_function += xenXMError
|
||||
msg_gen_function += VIR_ERROR
|
||||
|
48
configure.ac
48
configure.ac
@ -263,6 +263,8 @@ 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=check@:>@]),[],[with_xenapi=check])
|
||||
AC_ARG_WITH([libxl],
|
||||
AC_HELP_STRING([--with-libxl], [add libxenlight support @<:@default=check@:>@]),[],[with_libxl=check])
|
||||
AC_ARG_WITH([vbox],
|
||||
AC_HELP_STRING([--with-vbox=@<:@PFX@:>@],
|
||||
[VirtualBox XPCOMC location @<:@default=yes@:>@]),[],
|
||||
@ -497,6 +499,46 @@ fi
|
||||
AC_SUBST([LIBXENSERVER_CFLAGS])
|
||||
AC_SUBST([LIBXENSERVER_LIBS])
|
||||
|
||||
old_LIBS="$LIBS"
|
||||
old_CFLAGS="$CFLAGS"
|
||||
LIBXL_LIBS=""
|
||||
LIBXL_CFLAGS=""
|
||||
dnl search for libxl, aka libxenlight
|
||||
fail=0
|
||||
if test "$with_libxl" != "no" ; then
|
||||
if test "$with_libxl" != "yes" && test "$with_libxl" != "check" ; then
|
||||
LIBXL_CFLAGS="-I$with_libxl/include"
|
||||
LIBXL_LIBS="-L$with_libxl"
|
||||
fi
|
||||
CFLAGS="$CFLAGS $LIBXL_CFLAGS"
|
||||
LIBS="$LIBS $LIBXL_LIBS"
|
||||
AC_CHECK_LIB([xenlight], [libxl_ctx_init], [
|
||||
with_libxl=yes
|
||||
LIBXL_LIBS="$LIBXL_LIBS -lxenlight -lxenstore -lxenctrl -lxenguest -luuid -lutil -lblktapctl"
|
||||
],[
|
||||
if test "$with_libxl" = "yes"; then
|
||||
fail=1
|
||||
fi
|
||||
with_libxl=no
|
||||
],[
|
||||
-lxenstore -lxenctrl -lxenguest -luuid -lutil -lblktapctl
|
||||
])
|
||||
fi
|
||||
|
||||
LIBS="$old_LIBS"
|
||||
CFLAGS="$old_CFLAGS"
|
||||
|
||||
if test $fail = 1; then
|
||||
AC_MSG_ERROR([You must install the libxl Library to compile libxenlight driver with -lxl])
|
||||
fi
|
||||
|
||||
if test "$with_libxl" = "yes"; then
|
||||
AC_DEFINE_UNQUOTED([WITH_LIBXL], 1, [whether libxenlight driver is enabled])
|
||||
fi
|
||||
AM_CONDITIONAL([WITH_LIBXL], [test "$with_libxl" = "yes"])
|
||||
|
||||
AC_SUBST([LIBXL_CFLAGS])
|
||||
AC_SUBST([LIBXL_LIBS])
|
||||
|
||||
old_LIBS="$LIBS"
|
||||
old_CFLAGS="$CFLAGS"
|
||||
@ -2370,6 +2412,7 @@ AC_MSG_NOTICE([ OpenVZ: $with_openvz])
|
||||
AC_MSG_NOTICE([ VMware: $with_vmware])
|
||||
AC_MSG_NOTICE([ VBox: $with_vbox])
|
||||
AC_MSG_NOTICE([ XenAPI: $with_xenapi])
|
||||
AC_MSG_NOTICE([xenlight: $with_libxl])
|
||||
AC_MSG_NOTICE([ LXC: $with_lxc])
|
||||
AC_MSG_NOTICE([ PHYP: $with_phyp])
|
||||
AC_MSG_NOTICE([ ONE: $with_one])
|
||||
@ -2479,6 +2522,11 @@ AC_MSG_NOTICE([ xenapi: $LIBXENSERVER_CFLAGS $LIBXENSERVER_LIBS])
|
||||
else
|
||||
AC_MSG_NOTICE([ xenapi: no])
|
||||
fi
|
||||
if test "$with_libxl" = "yes" ; then
|
||||
AC_MSG_NOTICE([ libxenlight: $LIBXL_CFLAGS $LIBXL_LIBS])
|
||||
else
|
||||
AC_MSG_NOTICE([ libxenlight: no])
|
||||
fi
|
||||
if test "$with_hal" = "yes" ; then
|
||||
AC_MSG_NOTICE([ hal: $HAL_CFLAGS $HAL_LIBS])
|
||||
else
|
||||
|
@ -106,6 +106,10 @@ if WITH_LXC
|
||||
libvirtd_LDADD += ../src/libvirt_driver_lxc.la
|
||||
endif
|
||||
|
||||
if WITH_LIBXL
|
||||
libvirtd_LDADD += ../src/libvirt_driver_libxl.la
|
||||
endif
|
||||
|
||||
if WITH_UML
|
||||
libvirtd_LDADD += ../src/libvirt_driver_uml.la
|
||||
endif
|
||||
|
@ -81,6 +81,9 @@
|
||||
# ifdef WITH_LXC
|
||||
# include "lxc/lxc_driver.h"
|
||||
# endif
|
||||
# ifdef WITH_LIBXL
|
||||
# include "libxl/libxl_driver.h"
|
||||
# endif
|
||||
# ifdef WITH_UML
|
||||
# include "uml/uml_driver.h"
|
||||
# endif
|
||||
@ -943,6 +946,9 @@ static struct qemud_server *qemudInitialize(void) {
|
||||
# ifdef WITH_NWFILTER
|
||||
nwfilterRegister();
|
||||
# endif
|
||||
# ifdef WITH_LIBXL
|
||||
libxlRegister();
|
||||
# endif
|
||||
# ifdef WITH_QEMU
|
||||
qemuRegister();
|
||||
# endif
|
||||
|
@ -80,6 +80,7 @@ typedef enum {
|
||||
VIR_FROM_STREAMS = 38, /* Error from I/O streams */
|
||||
VIR_FROM_VMWARE = 39, /* Error from VMware driver */
|
||||
VIR_FROM_EVENT = 40, /* Error from event loop impl */
|
||||
VIR_FROM_LIBXL = 41, /* Error from libxenlight driver */
|
||||
} virErrorDomain;
|
||||
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
%define with_vbox 0%{!?_without_vbox:%{server_drivers}}
|
||||
%define with_uml 0%{!?_without_uml:%{server_drivers}}
|
||||
%define with_xenapi 0%{!?_without_xenapi:%{server_drivers}}
|
||||
%define with_libxl 0%{!?_without_libxl:%{server_drivers}}
|
||||
# XXX this shouldn't be here, but it mistakenly links into libvirtd
|
||||
%define with_one 0%{!?_without_one:%{server_drivers}}
|
||||
|
||||
@ -96,7 +97,7 @@
|
||||
%endif
|
||||
|
||||
# RHEL doesn't ship OpenVZ, VBox, UML, OpenNebula, PowerHypervisor,
|
||||
# VMWare, or libxenserver (xenapi)
|
||||
# VMWare, libxenserver (xenapi), or libxenlight (Xen 4.1 and newer)
|
||||
%if 0%{?rhel}
|
||||
%define with_openvz 0
|
||||
%define with_vbox 0
|
||||
@ -105,6 +106,7 @@
|
||||
%define with_phyp 0
|
||||
%define with_vmware 0
|
||||
%define with_xenapi 0
|
||||
%define with_libxl 0
|
||||
%endif
|
||||
|
||||
# RHEL-5 has restricted QEMU to x86_64 only and is too old for LXC
|
||||
@ -493,6 +495,10 @@ of recent versions of Linux (and other OSes).
|
||||
%define _without_xenapi --without-xenapi
|
||||
%endif
|
||||
|
||||
%if ! %{with_libxl}
|
||||
%define _without_libxl --without-libxl
|
||||
%endif
|
||||
|
||||
%if ! %{with_sasl}
|
||||
%define _without_sasl --without-sasl
|
||||
%endif
|
||||
@ -872,6 +878,9 @@ fi
|
||||
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/
|
||||
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/lxc/
|
||||
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/uml/
|
||||
%if %{with_libxl}
|
||||
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/libxl/
|
||||
%endif
|
||||
|
||||
%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd
|
||||
%if %{with_qemu}
|
||||
@ -912,6 +921,10 @@ fi
|
||||
%dir %{_localstatedir}/run/libvirt/uml/
|
||||
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/uml/
|
||||
%endif
|
||||
%if %{with_libxl}
|
||||
%dir %{_localstatedir}/run/libvirt/libxl/
|
||||
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/libxl/
|
||||
%endif
|
||||
%if %{with_network}
|
||||
%dir %{_localstatedir}/run/libvirt/network/
|
||||
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/network/
|
||||
|
@ -34,6 +34,8 @@ src/lxc/lxc_conf.c
|
||||
src/lxc/lxc_controller.c
|
||||
src/lxc/lxc_driver.c
|
||||
src/lxc/veth.c
|
||||
src/libxl/libxl_driver.c
|
||||
src/libxl/libxl_conf.c
|
||||
src/network/bridge_driver.c
|
||||
src/node_device/node_device_driver.c
|
||||
src/node_device/node_device_hal.c
|
||||
|
@ -298,6 +298,10 @@ XENAPI_DRIVER_SOURCES = \
|
||||
xenapi/xenapi_driver_private.h \
|
||||
xenapi/xenapi_utils.c xenapi/xenapi_utils.h
|
||||
|
||||
LIBXL_DRIVER_SOURCES = \
|
||||
libxl/libxl_conf.c libxl/libxl_conf.h \
|
||||
libxl/libxl_driver.c libxl/libxl_driver.h
|
||||
|
||||
UML_DRIVER_SOURCES = \
|
||||
uml/uml_conf.c uml/uml_conf.h \
|
||||
uml/uml_driver.c uml/uml_driver.h
|
||||
@ -692,6 +696,25 @@ endif
|
||||
libvirt_driver_xenapi_la_SOURCES = $(XENAPI_DRIVER_SOURCES)
|
||||
endif
|
||||
|
||||
if WITH_LIBXL
|
||||
if WITH_DRIVER_MODULES
|
||||
mod_LTLIBRARIES += libvirt_driver_libxl.la
|
||||
else
|
||||
noinst_LTLIBRARIES += libvirt_driver_libxl.la
|
||||
# Stateful, so linked to daemon instead
|
||||
#libvirt_la_BUILT_LIBADD += libvirt_driver_libxl.la
|
||||
endif
|
||||
libvirt_driver_libxl_la_CFLAGS = $(LIBXL_CFLAGS) \
|
||||
-I@top_srcdir@/src/conf $(AM_CFLAGS)
|
||||
libvirt_driver_libxl_la_LDFLAGS = $(AM_LDFLAGS)
|
||||
libvirt_driver_libxl_la_LIBADD = $(LIBXL_LIBS)
|
||||
if WITH_DRIVER_MODULES
|
||||
libvirt_driver_libxl_la_LIBADD += ../gnulib/lib/libgnu.la
|
||||
libvirt_driver_libxl_la_LDFLAGS += -module -avoid-version
|
||||
endif
|
||||
libvirt_driver_libxl_la_SOURCES = $(LIBXL_DRIVER_SOURCES)
|
||||
endif
|
||||
|
||||
if WITH_QEMU
|
||||
if WITH_DRIVER_MODULES
|
||||
mod_LTLIBRARIES += libvirt_driver_qemu.la
|
||||
@ -1005,6 +1028,7 @@ EXTRA_DIST += \
|
||||
$(PHYP_DRIVER_SOURCES) \
|
||||
$(VBOX_DRIVER_SOURCES) \
|
||||
$(XENAPI_DRIVER_SOURCES) \
|
||||
$(LIBXL_DRIVER_SOURCES) \
|
||||
$(ESX_DRIVER_SOURCES) \
|
||||
$(ESX_DRIVER_EXTRA_DIST) \
|
||||
$(NETWORK_DRIVER_SOURCES) \
|
||||
@ -1259,6 +1283,10 @@ if WITH_LXC
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/lxc"
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/lxc"
|
||||
endif
|
||||
if WITH_LIBXL
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/libxl"
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/libxl"
|
||||
endif
|
||||
if WITH_UML
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/uml"
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/uml"
|
||||
@ -1296,6 +1324,10 @@ if WITH_LXC
|
||||
rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/lxc" ||:
|
||||
rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/lxc" ||:
|
||||
endif
|
||||
if WITH_LIBXL
|
||||
rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/libxl" ||:
|
||||
rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/libxl" ||:
|
||||
endif
|
||||
if WITH_UML
|
||||
rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/uml" ||:
|
||||
rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/uml" ||:
|
||||
|
@ -27,7 +27,8 @@ typedef enum {
|
||||
VIR_DRV_ESX = 10,
|
||||
VIR_DRV_PHYP = 11,
|
||||
VIR_DRV_XENAPI = 12,
|
||||
VIR_DRV_VMWARE = 13
|
||||
VIR_DRV_VMWARE = 13,
|
||||
VIR_DRV_LIBXL = 14,
|
||||
} virDrvNo;
|
||||
|
||||
|
||||
|
@ -912,6 +912,10 @@ virGetVersion(unsigned long *libVer, const char *type,
|
||||
if (STRCASEEQ(type, "LXC"))
|
||||
*typeVer = LIBVIR_VERSION_NUMBER;
|
||||
# endif
|
||||
# if WITH_LIBXL
|
||||
if (STRCASEEQ(type, "xenlight"))
|
||||
*typeVer = LIBVIR_VERSION_NUMBER;
|
||||
# endif
|
||||
# if WITH_PHYP
|
||||
if (STRCASEEQ(type, "phyp"))
|
||||
*typeVer = LIBVIR_VERSION_NUMBER;
|
||||
|
898
src/libxl/libxl_conf.c
Normal file
898
src/libxl/libxl_conf.c
Normal file
@ -0,0 +1,898 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <regex.h>
|
||||
#include <libxl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "logging.h"
|
||||
#include "virterror_internal.h"
|
||||
#include "datatypes.h"
|
||||
#include "files.h"
|
||||
#include "memory.h"
|
||||
#include "uuid.h"
|
||||
#include "capabilities.h"
|
||||
#include "libxl_driver.h"
|
||||
#include "libxl_conf.h"
|
||||
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_LIBXL
|
||||
|
||||
/* see xen-unstable.hg/xen/include/asm-x86/cpufeature.h */
|
||||
#define LIBXL_X86_FEATURE_PAE_MASK 0x40
|
||||
|
||||
|
||||
struct guest_arch {
|
||||
const char *model;
|
||||
int bits;
|
||||
int hvm;
|
||||
int pae;
|
||||
int nonpae;
|
||||
int ia64_be;
|
||||
};
|
||||
|
||||
static const char *xen_cap_re = "(xen|hvm)-[[:digit:]]+\\.[[:digit:]]+-(x86_32|x86_64|ia64|powerpc64)(p|be)?";
|
||||
static regex_t xen_cap_rec;
|
||||
|
||||
|
||||
static int
|
||||
libxlNextFreeVncPort(libxlDriverPrivatePtr driver, int startPort)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = startPort ; i < LIBXL_VNC_PORT_MAX; i++) {
|
||||
int fd;
|
||||
int reuse = 1;
|
||||
struct sockaddr_in addr;
|
||||
bool used = false;
|
||||
|
||||
if (virBitmapGetBit(driver->reservedVNCPorts,
|
||||
i - LIBXL_VNC_PORT_MIN, &used) < 0)
|
||||
VIR_DEBUG("virBitmapGetBit failed on bit %d", i - LIBXL_VNC_PORT_MIN);
|
||||
|
||||
if (used)
|
||||
continue;
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(i);
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse, sizeof(reuse)) < 0) {
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
break;
|
||||
}
|
||||
|
||||
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
|
||||
/* Not in use, lets grab it */
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
/* Add port to bitmap of reserved ports */
|
||||
if (virBitmapSetBit(driver->reservedVNCPorts,
|
||||
i - LIBXL_VNC_PORT_MIN) < 0) {
|
||||
VIR_DEBUG("virBitmapSetBit failed on bit %d",
|
||||
i - LIBXL_VNC_PORT_MIN);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
|
||||
if (errno == EADDRINUSE) {
|
||||
/* In use, try next */
|
||||
continue;
|
||||
}
|
||||
/* Some other bad failure, get out.. */
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static virCapsPtr
|
||||
libxlBuildCapabilities(const char *hostmachine,
|
||||
int host_pae,
|
||||
struct guest_arch *guest_archs,
|
||||
int nr_guest_archs)
|
||||
{
|
||||
virCapsPtr caps;
|
||||
int i;
|
||||
|
||||
if ((caps = virCapabilitiesNew(hostmachine, 1, 1)) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x16, 0x3e });
|
||||
|
||||
if (host_pae &&
|
||||
virCapabilitiesAddHostFeature(caps, "pae") < 0)
|
||||
goto no_memory;
|
||||
|
||||
for (i = 0; i < nr_guest_archs; ++i) {
|
||||
virCapsGuestPtr guest;
|
||||
char const *const xen_machines[] = {guest_archs[i].hvm ? "xenfv" : "xenpv"};
|
||||
virCapsGuestMachinePtr *machines;
|
||||
|
||||
if ((machines = virCapabilitiesAllocMachines(xen_machines, 1)) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
if ((guest = virCapabilitiesAddGuest(caps,
|
||||
guest_archs[i].hvm ? "hvm" : "xen",
|
||||
guest_archs[i].model,
|
||||
guest_archs[i].bits,
|
||||
(STREQ(hostmachine, "x86_64") ?
|
||||
"/usr/lib64/xen/bin/qemu-dm" :
|
||||
"/usr/lib/xen/bin/qemu-dm"),
|
||||
(guest_archs[i].hvm ?
|
||||
"/usr/lib/xen/boot/hvmloader" :
|
||||
NULL),
|
||||
1,
|
||||
machines)) == NULL) {
|
||||
virCapabilitiesFreeMachines(machines, 1);
|
||||
goto no_memory;
|
||||
}
|
||||
machines = NULL;
|
||||
|
||||
if (virCapabilitiesAddGuestDomain(guest,
|
||||
"xen",
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
if (guest_archs[i].pae &&
|
||||
virCapabilitiesAddGuestFeature(guest,
|
||||
"pae",
|
||||
1,
|
||||
0) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
if (guest_archs[i].nonpae &&
|
||||
virCapabilitiesAddGuestFeature(guest,
|
||||
"nonpae",
|
||||
1,
|
||||
0) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
if (guest_archs[i].ia64_be &&
|
||||
virCapabilitiesAddGuestFeature(guest,
|
||||
"ia64_be",
|
||||
1,
|
||||
0) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
if (guest_archs[i].hvm) {
|
||||
if (virCapabilitiesAddGuestFeature(guest,
|
||||
"acpi",
|
||||
1,
|
||||
1) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
if (virCapabilitiesAddGuestFeature(guest, "apic",
|
||||
1,
|
||||
0) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
if (virCapabilitiesAddGuestFeature(guest,
|
||||
"hap",
|
||||
0,
|
||||
1) == NULL)
|
||||
goto no_memory;
|
||||
}
|
||||
}
|
||||
|
||||
caps->defaultConsoleTargetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;
|
||||
|
||||
return caps;
|
||||
|
||||
no_memory:
|
||||
virCapabilitiesFree(caps);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static virCapsPtr
|
||||
libxlMakeCapabilitiesInternal(const char *hostmachine,
|
||||
libxl_physinfo *phy_info,
|
||||
char *capabilities)
|
||||
{
|
||||
char *str, *token;
|
||||
regmatch_t subs[4];
|
||||
char *saveptr = NULL;
|
||||
int i;
|
||||
|
||||
int host_pae = 0;
|
||||
struct guest_arch guest_archs[32];
|
||||
int nr_guest_archs = 0;
|
||||
virCapsPtr caps = NULL;
|
||||
|
||||
memset(guest_archs, 0, sizeof(guest_archs));
|
||||
|
||||
/* hw_caps is an array of 32-bit words whose meaning is listed in
|
||||
* xen-unstable.hg/xen/include/asm-x86/cpufeature.h. Each feature
|
||||
* is defined in the form X*32+Y, corresponding to the Y'th bit in
|
||||
* the X'th 32-bit word of hw_cap.
|
||||
*/
|
||||
host_pae = phy_info->hw_cap[0] & LIBXL_X86_FEATURE_PAE_MASK;
|
||||
|
||||
/* Format of capabilities string is documented in the code in
|
||||
* xen-unstable.hg/xen/arch/.../setup.c.
|
||||
*
|
||||
* It is a space-separated list of supported guest architectures.
|
||||
*
|
||||
* For x86:
|
||||
* TYP-VER-ARCH[p]
|
||||
* ^ ^ ^ ^
|
||||
* | | | +-- PAE supported
|
||||
* | | +------- x86_32 or x86_64
|
||||
* | +----------- the version of Xen, eg. "3.0"
|
||||
* +--------------- "xen" or "hvm" for para or full virt respectively
|
||||
*
|
||||
* For IA64:
|
||||
* TYP-VER-ARCH[be]
|
||||
* ^ ^ ^ ^
|
||||
* | | | +-- Big-endian supported
|
||||
* | | +------- always "ia64"
|
||||
* | +----------- the version of Xen, eg. "3.0"
|
||||
* +--------------- "xen" or "hvm" for para or full virt respectively
|
||||
*/
|
||||
|
||||
/* Split capabilities string into tokens. strtok_r is OK here because
|
||||
* we "own" the buffer. Parse out the features from each token.
|
||||
*/
|
||||
for (str = capabilities, nr_guest_archs = 0;
|
||||
nr_guest_archs < sizeof(guest_archs) / sizeof(guest_archs[0])
|
||||
&& (token = strtok_r(str, " ", &saveptr)) != NULL;
|
||||
str = NULL) {
|
||||
if (regexec(&xen_cap_rec, token, sizeof(subs) / sizeof(subs[0]),
|
||||
subs, 0) == 0) {
|
||||
int hvm = STRPREFIX(&token[subs[1].rm_so], "hvm");
|
||||
const char *model;
|
||||
int bits, pae = 0, nonpae = 0, ia64_be = 0;
|
||||
|
||||
if (STRPREFIX(&token[subs[2].rm_so], "x86_32")) {
|
||||
model = "i686";
|
||||
bits = 32;
|
||||
if (subs[3].rm_so != -1 &&
|
||||
STRPREFIX(&token[subs[3].rm_so], "p"))
|
||||
pae = 1;
|
||||
else
|
||||
nonpae = 1;
|
||||
}
|
||||
else if (STRPREFIX(&token[subs[2].rm_so], "x86_64")) {
|
||||
model = "x86_64";
|
||||
bits = 64;
|
||||
}
|
||||
else if (STRPREFIX(&token[subs[2].rm_so], "ia64")) {
|
||||
model = "ia64";
|
||||
bits = 64;
|
||||
if (subs[3].rm_so != -1 &&
|
||||
STRPREFIX(&token[subs[3].rm_so], "be"))
|
||||
ia64_be = 1;
|
||||
}
|
||||
else if (STRPREFIX(&token[subs[2].rm_so], "powerpc64")) {
|
||||
model = "ppc64";
|
||||
bits = 64;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Search for existing matching (model,hvm) tuple */
|
||||
for (i = 0 ; i < nr_guest_archs ; i++) {
|
||||
if (STREQ(guest_archs[i].model, model) &&
|
||||
guest_archs[i].hvm == hvm) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Too many arch flavours - highly unlikely ! */
|
||||
if (i >= ARRAY_CARDINALITY(guest_archs))
|
||||
continue;
|
||||
/* Didn't find a match, so create a new one */
|
||||
if (i == nr_guest_archs)
|
||||
nr_guest_archs++;
|
||||
|
||||
guest_archs[i].model = model;
|
||||
guest_archs[i].bits = bits;
|
||||
guest_archs[i].hvm = hvm;
|
||||
|
||||
/* Careful not to overwrite a previous positive
|
||||
setting with a negative one here - some archs
|
||||
can do both pae & non-pae, but Xen reports
|
||||
separately capabilities so we're merging archs */
|
||||
if (pae)
|
||||
guest_archs[i].pae = pae;
|
||||
if (nonpae)
|
||||
guest_archs[i].nonpae = nonpae;
|
||||
if (ia64_be)
|
||||
guest_archs[i].ia64_be = ia64_be;
|
||||
}
|
||||
}
|
||||
|
||||
if ((caps = libxlBuildCapabilities(hostmachine,
|
||||
host_pae,
|
||||
guest_archs,
|
||||
nr_guest_archs)) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
return caps;
|
||||
|
||||
no_memory:
|
||||
virReportOOMError();
|
||||
virCapabilitiesFree(caps);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlMakeDomCreateInfo(virDomainDefPtr def, libxl_domain_create_info *c_info)
|
||||
{
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
|
||||
libxl_init_create_info(c_info);
|
||||
|
||||
c_info->hvm = STREQ(def->os.type, "hvm");
|
||||
if ((c_info->name = strdup(def->name)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
virUUIDFormat(def->uuid, uuidstr);
|
||||
if (libxl_uuid_from_string(&c_info->uuid, uuidstr) ) {
|
||||
libxlError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("libxenlight failed to parse UUID '%s'"), uuidstr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
libxl_domain_create_info_destroy(c_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
|
||||
{
|
||||
libxl_domain_build_info *b_info = &d_config->b_info;
|
||||
int hvm = STREQ(def->os.type, "hvm");
|
||||
|
||||
libxl_init_build_info(b_info, &d_config->c_info);
|
||||
|
||||
b_info->hvm = hvm;
|
||||
b_info->max_vcpus = def->maxvcpus;
|
||||
b_info->cur_vcpus = def->vcpus;
|
||||
if (def->clock.ntimers > 0 &&
|
||||
def->clock.timers[0]->name == VIR_DOMAIN_TIMER_NAME_TSC) {
|
||||
switch (def->clock.timers[0]->mode) {
|
||||
case VIR_DOMAIN_TIMER_MODE_NATIVE:
|
||||
b_info->tsc_mode = 2;
|
||||
break;
|
||||
case VIR_DOMAIN_TIMER_MODE_PARAVIRT:
|
||||
b_info->tsc_mode = 3;
|
||||
break;
|
||||
default:
|
||||
b_info->tsc_mode = 1;
|
||||
}
|
||||
}
|
||||
b_info->max_memkb = def->mem.max_balloon;
|
||||
b_info->target_memkb = def->mem.cur_balloon;
|
||||
if (hvm) {
|
||||
b_info->u.hvm.pae = def->features & (1 << VIR_DOMAIN_FEATURE_PAE);
|
||||
b_info->u.hvm.apic = def->features & (1 << VIR_DOMAIN_FEATURE_APIC);
|
||||
b_info->u.hvm.acpi = def->features & (1 << VIR_DOMAIN_FEATURE_ACPI);
|
||||
/*
|
||||
* The following comment and calculation were taken directly from
|
||||
* libxenlight's internal function libxl_get_required_shadow_memory():
|
||||
*
|
||||
* 256 pages (1MB) per vcpu, plus 1 page per MiB of RAM for the P2M map,
|
||||
* plus 1 page per MiB of RAM to shadow the resident processes.
|
||||
*/
|
||||
b_info->shadow_memkb = 4 * (256 * b_info->cur_vcpus +
|
||||
2 * (b_info->max_memkb / 1024));
|
||||
} else {
|
||||
if (def->os.bootloader) {
|
||||
if ((b_info->u.pv.bootloader = strdup(def->os.bootloader)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (def->os.bootloaderArgs) {
|
||||
if ((b_info->u.pv.bootloader_args = strdup(def->os.bootloaderArgs)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (def->os.cmdline) {
|
||||
if ((b_info->u.pv.cmdline = strdup(def->os.cmdline)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (def->os.kernel) {
|
||||
/* libxl_init_build_info() sets kernel.path = strdup("hvmloader") */
|
||||
free(b_info->kernel.path);
|
||||
if ((b_info->kernel.path = strdup(def->os.kernel)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (def->os.initrd) {
|
||||
if ((b_info->u.pv.ramdisk.path = strdup(def->os.initrd)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
libxl_domain_build_info_destroy(b_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlMakeDiskList(virDomainDefPtr def, libxl_domain_config *d_config)
|
||||
{
|
||||
virDomainDiskDefPtr *l_disks = def->disks;
|
||||
int ndisks = def->ndisks;
|
||||
libxl_device_disk *x_disks;
|
||||
int i;
|
||||
|
||||
if (VIR_ALLOC_N(x_disks, ndisks) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < ndisks; i++) {
|
||||
if (l_disks[i]->src &&
|
||||
(x_disks[i].pdev_path = strdup(l_disks[i]->src)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (l_disks[i]->dst &&
|
||||
(x_disks[i].vdev = strdup(l_disks[i]->dst)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (l_disks[i]->driverName) {
|
||||
if (STREQ(l_disks[i]->driverName, "tap") ||
|
||||
STREQ(l_disks[i]->driverName, "tap2")) {
|
||||
if (l_disks[i]->driverType) {
|
||||
if (STREQ(l_disks[i]->driverType, "qcow")) {
|
||||
x_disks[i].format = DISK_FORMAT_QCOW;
|
||||
x_disks[i].backend = DISK_BACKEND_QDISK;
|
||||
} else if (STREQ(l_disks[i]->driverType, "qcow2")) {
|
||||
x_disks[i].format = DISK_FORMAT_QCOW2;
|
||||
x_disks[i].backend = DISK_BACKEND_QDISK;
|
||||
} else if (STREQ(l_disks[i]->driverType, "vhd")) {
|
||||
x_disks[i].format = DISK_FORMAT_VHD;
|
||||
x_disks[i].backend = DISK_BACKEND_TAP;
|
||||
} else if (STREQ(l_disks[i]->driverType, "aio") ||
|
||||
STREQ(l_disks[i]->driverType, "raw")) {
|
||||
x_disks[i].format = DISK_FORMAT_RAW;
|
||||
x_disks[i].backend = DISK_BACKEND_TAP;
|
||||
}
|
||||
} else {
|
||||
/* No subtype specified, default to raw/tap */
|
||||
x_disks[i].format = DISK_FORMAT_RAW;
|
||||
x_disks[i].backend = DISK_BACKEND_TAP;
|
||||
}
|
||||
} else if (STREQ(l_disks[i]->driverName, "file")) {
|
||||
x_disks[i].format = DISK_FORMAT_RAW;
|
||||
x_disks[i].backend = DISK_BACKEND_TAP;
|
||||
} else if (STREQ(l_disks[i]->driverName, "phy")) {
|
||||
x_disks[i].format = DISK_FORMAT_RAW;
|
||||
x_disks[i].backend = DISK_BACKEND_PHY;
|
||||
} else {
|
||||
libxlError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("libxenlight does not support disk driver %s"),
|
||||
l_disks[i]->driverName);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
/* No driverName - default to raw/tap?? */
|
||||
x_disks[i].format = DISK_FORMAT_RAW;
|
||||
x_disks[i].backend = DISK_BACKEND_TAP;
|
||||
}
|
||||
|
||||
/* How to set unpluggable? */
|
||||
x_disks[i].unpluggable = 1;
|
||||
x_disks[i].readwrite = !l_disks[i]->readonly;
|
||||
x_disks[i].is_cdrom =
|
||||
l_disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM ? 1 : 0;
|
||||
}
|
||||
|
||||
d_config->disks = x_disks;
|
||||
d_config->num_disks = ndisks;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
for (i = 0; i < ndisks; i++)
|
||||
libxl_device_disk_destroy(&x_disks[i]);
|
||||
VIR_FREE(x_disks);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlMakeNicList(virDomainDefPtr def, libxl_domain_config *d_config)
|
||||
{
|
||||
virDomainNetDefPtr *l_nics = def->nets;
|
||||
int nnics = def->nnets;
|
||||
libxl_device_nic *x_nics;
|
||||
int i;
|
||||
|
||||
if (VIR_ALLOC_N(x_nics, nnics) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < nnics; i++) {
|
||||
x_nics[i].devid = i;
|
||||
|
||||
// TODO: Where is mtu stored?
|
||||
//x_nics[i].mtu = 1492;
|
||||
|
||||
memcpy(x_nics[i].mac, l_nics[i]->mac, sizeof(libxl_mac));
|
||||
|
||||
if (l_nics[i]->model && !STREQ(l_nics[i]->model, "netfront")) {
|
||||
if ((x_nics[i].model = strdup(l_nics[i]->model)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
x_nics[i].nictype = NICTYPE_IOEMU;
|
||||
} else {
|
||||
x_nics[i].nictype = NICTYPE_VIF;
|
||||
}
|
||||
|
||||
if (l_nics[i]->ifname &&
|
||||
(x_nics[i].ifname = strdup(l_nics[i]->ifname)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (l_nics[i]->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
|
||||
if (l_nics[i]->data.bridge.brname &&
|
||||
(x_nics[i].bridge =
|
||||
strdup(l_nics[i]->data.bridge.brname)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
if (l_nics[i]->data.bridge.script &&
|
||||
(x_nics[i].script =
|
||||
strdup(l_nics[i]->data.bridge.script)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d_config->vifs = x_nics;
|
||||
d_config->num_vifs = nnics;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
for (i = 0; i < nnics; i++)
|
||||
libxl_device_nic_destroy(&x_nics[i]);
|
||||
VIR_FREE(x_nics);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlMakeVfbList(libxlDriverPrivatePtr driver,
|
||||
virDomainDefPtr def, libxl_domain_config *d_config)
|
||||
{
|
||||
virDomainGraphicsDefPtr *l_vfbs = def->graphics;
|
||||
int nvfbs = def->ngraphics;
|
||||
libxl_device_vfb *x_vfbs;
|
||||
libxl_device_vkb *x_vkbs;
|
||||
int i;
|
||||
int port;
|
||||
|
||||
if (nvfbs == 0)
|
||||
return 0;
|
||||
|
||||
if (VIR_ALLOC_N(x_vfbs, nvfbs) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
if (VIR_ALLOC_N(x_vkbs, nvfbs) < 0) {
|
||||
virReportOOMError();
|
||||
VIR_FREE(x_vfbs);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < nvfbs; i++) {
|
||||
libxl_device_vfb_init(&x_vfbs[i], i);
|
||||
libxl_device_vkb_init(&x_vkbs[i], i);
|
||||
|
||||
switch (l_vfbs[i]->type) {
|
||||
case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
|
||||
x_vfbs[i].sdl = 1;
|
||||
if (l_vfbs[i]->data.sdl.display &&
|
||||
(x_vfbs[i].display =
|
||||
strdup(l_vfbs[i]->data.sdl.display)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
if (l_vfbs[i]->data.sdl.xauth &&
|
||||
(x_vfbs[i].xauthority =
|
||||
strdup(l_vfbs[i]->data.sdl.xauth)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
|
||||
x_vfbs[i].vnc = 1;
|
||||
/* driver handles selection of free port */
|
||||
x_vfbs[i].vncunused = 0;
|
||||
if (l_vfbs[i]->data.vnc.autoport) {
|
||||
port = libxlNextFreeVncPort(driver, LIBXL_VNC_PORT_MIN);
|
||||
if (port < 0) {
|
||||
libxlError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("Unable to find an unused VNC port"));
|
||||
goto error;
|
||||
}
|
||||
l_vfbs[i]->data.vnc.port = port;
|
||||
}
|
||||
x_vfbs[i].vncdisplay = l_vfbs[i]->data.vnc.port -
|
||||
LIBXL_VNC_PORT_MIN;
|
||||
|
||||
if (l_vfbs[i]->data.vnc.listenAddr) {
|
||||
/* libxl_device_vfb_init() does strdup("127.0.0.1") */
|
||||
free(x_vfbs[i].vnclisten);
|
||||
if ((x_vfbs[i].vnclisten =
|
||||
strdup(l_vfbs[i]->data.vnc.listenAddr)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (l_vfbs[i]->data.vnc.keymap &&
|
||||
(x_vfbs[i].keymap =
|
||||
strdup(l_vfbs[i]->data.vnc.keymap)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
d_config->vfbs = x_vfbs;
|
||||
d_config->vkbs = x_vkbs;
|
||||
d_config->num_vfbs = d_config->num_vkbs = nvfbs;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
for (i = 0; i < nvfbs; i++) {
|
||||
libxl_device_vfb_destroy(&x_vfbs[i]);
|
||||
libxl_device_vkb_destroy(&x_vkbs[i]);
|
||||
}
|
||||
VIR_FREE(x_vfbs);
|
||||
VIR_FREE(x_vkbs);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
|
||||
{
|
||||
const char *type = virDomainChrTypeToString(def->source.type);
|
||||
|
||||
if (!type) {
|
||||
libxlError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("unexpected chr device type"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (def->source.type) {
|
||||
case VIR_DOMAIN_CHR_TYPE_NULL:
|
||||
case VIR_DOMAIN_CHR_TYPE_STDIO:
|
||||
case VIR_DOMAIN_CHR_TYPE_VC:
|
||||
case VIR_DOMAIN_CHR_TYPE_PTY:
|
||||
if (virAsprintf(buf, "%s", type) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_CHR_TYPE_FILE:
|
||||
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
||||
if (virAsprintf(buf, "%s:%s", type,
|
||||
def->source.data.file.path) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_CHR_TYPE_DEV:
|
||||
if (virAsprintf(buf, "%s", def->source.data.file.path) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
libxlMakeDeviceModelInfo(virDomainDefPtr def, libxl_domain_config *d_config)
|
||||
{
|
||||
libxl_device_model_info *dm_info = &d_config->dm_info;
|
||||
int i;
|
||||
char b_order[VIR_DOMAIN_BOOT_LAST+1];
|
||||
|
||||
libxl_init_dm_info(dm_info, &d_config->c_info, &d_config->b_info);
|
||||
|
||||
if (d_config->b_info.hvm) {
|
||||
/* HVM-specific device model info */
|
||||
dm_info->type = XENFV;
|
||||
if (def->os.nBootDevs > 0) {
|
||||
free(dm_info->boot);
|
||||
for (i = 0; i < def->os.nBootDevs; i++) {
|
||||
switch (def->os.bootDevs[i]) {
|
||||
case VIR_DOMAIN_BOOT_FLOPPY:
|
||||
b_order[i] = 'a';
|
||||
break;
|
||||
default:
|
||||
case VIR_DOMAIN_BOOT_DISK:
|
||||
b_order[i] = 'c';
|
||||
break;
|
||||
case VIR_DOMAIN_BOOT_CDROM:
|
||||
b_order[i] = 'd';
|
||||
break;
|
||||
case VIR_DOMAIN_BOOT_NET:
|
||||
b_order[i] = 'n';
|
||||
break;
|
||||
}
|
||||
}
|
||||
b_order[def->os.nBootDevs] = '\0';
|
||||
if ((dm_info->boot = strdup(b_order)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (def->serials &&
|
||||
(libxlMakeChrdevStr(def->serials[0], &dm_info->serial) < 0))
|
||||
goto error;
|
||||
} else {
|
||||
/* PV-specific device model info */
|
||||
dm_info->type = XENPV;
|
||||
}
|
||||
|
||||
/* Build qemu graphics options from previously parsed vfb */
|
||||
if (d_config->num_vfbs > 0) {
|
||||
if (d_config->vfbs[0].vnc) {
|
||||
dm_info->vnc = 1;
|
||||
/* driver handles selection of free port */
|
||||
dm_info->vncunused = 0;
|
||||
if (d_config->vfbs[0].vnclisten) {
|
||||
free(dm_info->vnclisten);
|
||||
if ((dm_info->vnclisten =
|
||||
strdup(d_config->vfbs[0].vnclisten)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (d_config->vfbs[0].keymap &&
|
||||
(dm_info->keymap = strdup(d_config->vfbs[0].keymap)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
dm_info->vncdisplay = d_config->vfbs[0].vncdisplay;
|
||||
if (d_config->vfbs[0].vncpasswd &&
|
||||
(dm_info->vncpasswd =
|
||||
strdup(d_config->vfbs[0].vncpasswd)) == NULL) {
|
||||
virReportOOMError();
|
||||
goto error;
|
||||
}
|
||||
} else if (d_config->vfbs[0].sdl) {
|
||||
dm_info->sdl = 1;
|
||||
dm_info->vnc = 0;
|
||||
}
|
||||
} else if (d_config->num_vfbs == 0) {
|
||||
dm_info->nographic = 1;
|
||||
dm_info->vnc = 0;
|
||||
}
|
||||
|
||||
// TODO
|
||||
//dm_info->usb = ;
|
||||
//dm_info->usbdevice = ;
|
||||
//dm_info->soundhw = ;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
libxl_device_model_info_destroy(dm_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
virCapsPtr
|
||||
libxlMakeCapabilities(libxl_ctx *ctx)
|
||||
{
|
||||
libxl_physinfo phy_info;
|
||||
const libxl_version_info *ver_info;
|
||||
struct utsname utsname;
|
||||
|
||||
regcomp (&xen_cap_rec, xen_cap_re, REG_EXTENDED);
|
||||
|
||||
if (libxl_get_physinfo(ctx, &phy_info) != 0) {
|
||||
libxlError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to get node physical info from libxenlight"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ver_info = libxl_get_version_info(ctx)) == NULL) {
|
||||
libxlError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to get version info from libxenlight"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uname(&utsname);
|
||||
|
||||
return libxlMakeCapabilitiesInternal(utsname.machine,
|
||||
&phy_info,
|
||||
ver_info->capabilities);
|
||||
}
|
||||
|
||||
int
|
||||
libxlBuildDomainConfig(libxlDriverPrivatePtr driver,
|
||||
virDomainDefPtr def, libxl_domain_config *d_config)
|
||||
{
|
||||
|
||||
if (libxlMakeDomCreateInfo(def, &d_config->c_info) < 0)
|
||||
return -1;
|
||||
|
||||
if (libxlMakeDomBuildInfo(def, d_config) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (libxlMakeDiskList(def, d_config) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (libxlMakeNicList(def, d_config) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (libxlMakeVfbList(driver, def, d_config) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (libxlMakeDeviceModelInfo(def, d_config) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
d_config->on_reboot = def->onReboot;
|
||||
d_config->on_poweroff = def->onPoweroff;
|
||||
d_config->on_crash = def->onCrash;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
libxl_domain_config_destroy(d_config);
|
||||
return -1;
|
||||
}
|
91
src/libxl/libxl_conf.h
Normal file
91
src/libxl/libxl_conf.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef LIBXL_CONF_H
|
||||
# define LIBXL_CONF_H
|
||||
|
||||
# include <config.h>
|
||||
|
||||
# include <libxl.h>
|
||||
|
||||
# include "internal.h"
|
||||
# include "domain_conf.h"
|
||||
# include "capabilities.h"
|
||||
# include "configmake.h"
|
||||
# include "bitmap.h"
|
||||
|
||||
|
||||
# define LIBXL_VNC_PORT_MIN 5900
|
||||
# define LIBXL_VNC_PORT_MAX 65535
|
||||
|
||||
# define LIBXL_CONFIG_DIR SYSCONFDIR "/libvirt/libxl"
|
||||
# define LIBXL_AUTOSTART_DIR LIBXL_CONFIG_DIR "/autostart"
|
||||
# define LIBXL_STATE_DIR LOCALSTATEDIR "/run/libvirt/libxl"
|
||||
# define LIBXL_LOG_DIR LOCALSTATEDIR "/log/libvirt/libxl"
|
||||
# define LIBXL_LIB_DIR LOCALSTATEDIR "/lib/libvirt/libxl"
|
||||
# define LIBXL_SAVE_DIR LIBXL_LIB_DIR "/save"
|
||||
|
||||
|
||||
typedef struct _libxlDriverPrivate libxlDriverPrivate;
|
||||
typedef libxlDriverPrivate *libxlDriverPrivatePtr;
|
||||
struct _libxlDriverPrivate {
|
||||
virMutex lock;
|
||||
virCapsPtr caps;
|
||||
unsigned int version;
|
||||
|
||||
FILE *logger_file;
|
||||
xentoollog_logger *logger;
|
||||
/* libxl ctx for driver wide ops; getVersion, getNodeInfo, ... */
|
||||
libxl_ctx ctx;
|
||||
|
||||
virBitmapPtr reservedVNCPorts;
|
||||
virDomainObjList domains;
|
||||
|
||||
char *configDir;
|
||||
char *autostartDir;
|
||||
char *logDir;
|
||||
char *stateDir;
|
||||
char *libDir;
|
||||
char *saveDir;
|
||||
};
|
||||
|
||||
typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate;
|
||||
typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr;
|
||||
struct _libxlDomainObjPrivate {
|
||||
/* per domain libxl ctx */
|
||||
libxl_ctx ctx;
|
||||
libxl_waiter *dWaiter;
|
||||
int waiterFD;
|
||||
int eventHdl;
|
||||
};
|
||||
|
||||
|
||||
# define libxlError(code, ...) \
|
||||
virReportErrorHelper(NULL, VIR_FROM_LIBXL, code, __FILE__, \
|
||||
__FUNCTION__, __LINE__, __VA_ARGS__)
|
||||
|
||||
virCapsPtr
|
||||
libxlMakeCapabilities(libxl_ctx *ctx);
|
||||
|
||||
int
|
||||
libxlBuildDomainConfig(libxlDriverPrivatePtr driver,
|
||||
virDomainDefPtr def, libxl_domain_config *d_config);
|
||||
|
||||
|
||||
#endif /* LIBXL_CONF_H */
|
1453
src/libxl/libxl_driver.c
Normal file
1453
src/libxl/libxl_driver.c
Normal file
File diff suppressed because it is too large
Load Diff
27
src/libxl/libxl_driver.h
Normal file
27
src/libxl/libxl_driver.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef LIBXL_DRIVER_H
|
||||
# define LIBXL_DRIVER_H
|
||||
|
||||
# include <config.h>
|
||||
|
||||
int libxlRegister(void);
|
||||
|
||||
#endif /* LIBXL_DRIVER_H */
|
@ -89,6 +89,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
|
||||
case VIR_FROM_XENAPI:
|
||||
dom = "XenAPI ";
|
||||
break;
|
||||
case VIR_FROM_LIBXL:
|
||||
dom = "xenlight ";
|
||||
break;
|
||||
case VIR_FROM_XML:
|
||||
dom = "XML ";
|
||||
break;
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "uuid.h"
|
||||
#include "fdstream.h"
|
||||
#include "files.h"
|
||||
#include "command.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_XEN
|
||||
|
||||
@ -229,6 +230,23 @@ xenUnifiedProbe (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WITH_LIBXL
|
||||
static int
|
||||
xenUnifiedXendProbe (void)
|
||||
{
|
||||
virCommandPtr cmd;
|
||||
int status;
|
||||
int ret = 0;
|
||||
|
||||
cmd = virCommandNewArgList("/usr/sbin/xend", "status", NULL);
|
||||
if (virCommandRun(cmd, &status) == 0 && status == 0)
|
||||
ret = 1;
|
||||
virCommandFree(cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static virDrvOpenStatus
|
||||
xenUnifiedOpen (virConnectPtr conn, virConnectAuthPtr auth, int flags)
|
||||
{
|
||||
@ -292,6 +310,13 @@ xenUnifiedOpen (virConnectPtr conn, virConnectAuthPtr auth, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_LIBXL
|
||||
/* Decline xen:// URI if xend is not running and libxenlight
|
||||
* driver is potentially available. */
|
||||
if (!xenUnifiedXendProbe())
|
||||
return VIR_DRV_OPEN_DECLINED;
|
||||
#endif
|
||||
|
||||
/* We now know the URI is definitely for this driver, so beyond
|
||||
* here, don't return DECLINED, always use ERROR */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user