Signed-off-by: Dmitry Guryanov <dguryanov@xxxxxxxxxxxxx> --- cfg.mk | 1 + configure.ac | 20 ++++ docs/drvpvs.html.in | 28 +++++ include/libvirt/virterror.h | 1 + libvirt.spec.in | 7 + mingw32-libvirt.spec.in | 6 + po/POTFILES.in | 1 + src/Makefile.am | 21 ++++ src/conf/domain_conf.c | 3 +- src/conf/domain_conf.h | 1 + src/driver.h | 1 + src/libvirt.c | 12 ++ src/pvs/pvs_driver.c | 263 +++++++++++++++++++++++++++++++++++++++++++ src/pvs/pvs_driver.h | 49 ++++++++ src/util/virterror.c | 3 + 15 files changed, 416 insertions(+), 1 deletions(-) create mode 100644 docs/drvpvs.html.in create mode 100644 src/pvs/pvs_driver.c create mode 100644 src/pvs/pvs_driver.h diff --git a/cfg.mk b/cfg.mk index 71e9a1d..ca6c0a5 100644 --- a/cfg.mk +++ b/cfg.mk @@ -502,6 +502,7 @@ msg_gen_function += PHYP_ERROR msg_gen_function += VIR_ERROR msg_gen_function += VMX_ERROR msg_gen_function += XENXS_ERROR +msg_gen_function += PVS_ERROR msg_gen_function += eventReportError msg_gen_function += ifaceError msg_gen_function += interfaceReportError diff --git a/configure.ac b/configure.ac index 3f5b3ff..214f450 100644 --- a/configure.ac +++ b/configure.ac @@ -330,6 +330,8 @@ AC_ARG_WITH([esx], AC_HELP_STRING([--with-esx], [add ESX support @<:@default=check@:>@]),[],[with_esx=check]) AC_ARG_WITH([hyperv], AC_HELP_STRING([--with-hyperv], [add Hyper-V support @<:@default=check@:>@]),[],[with_hyperv=check]) +AC_ARG_WITH([pvs], + AC_HELP_STRING([--with-pvs], [add Parallels Virtuozzo Server support @<:@default=check@:>@]),[],[with_pvs=check]) AC_ARG_WITH([test], AC_HELP_STRING([--with-test], [add test driver support @<:@default=yes@:>@]),[],[with_test=yes]) AC_ARG_WITH([remote], @@ -794,6 +796,23 @@ fi AM_CONDITIONAL([WITH_LXC], [test "$with_lxc" = "yes"]) dnl +dnl Checks for the PVS driver +dnl + +if test "$with_pvs" = "check"; then + with_pvs=$with_linux +fi + +if test "$with_pvs" = "yes" && test "$with_linux" = "no"; then + AC_MSG_ERROR([The PVS driver can be enabled on Linux only.]) +fi + +if test "$with_pvs" = "yes"; then + AC_DEFINE_UNQUOTED([WITH_PVS], 1, [whether PVS driver is enabled]) +fi +AM_CONDITIONAL([WITH_PVS], [test "$with_pvs" = "yes"]) + +dnl dnl check for shell that understands <> redirection without truncation, dnl needed by src/qemu/qemu_monitor_{text,json}.c. dnl @@ -2680,6 +2699,7 @@ AC_MSG_NOTICE([ LXC: $with_lxc]) AC_MSG_NOTICE([ PHYP: $with_phyp]) AC_MSG_NOTICE([ ESX: $with_esx]) AC_MSG_NOTICE([ Hyper-V: $with_hyperv]) +AC_MSG_NOTICE([ PVS: $with_pvs]) AC_MSG_NOTICE([ Test: $with_test]) AC_MSG_NOTICE([ Remote: $with_remote]) AC_MSG_NOTICE([ Network: $with_network]) diff --git a/docs/drvpvs.html.in b/docs/drvpvs.html.in new file mode 100644 index 0000000..dae3c77 --- /dev/null +++ b/docs/drvpvs.html.in @@ -0,0 +1,28 @@ +<html><body> + <h1>Parallels Virtuozzo Server driver</h1> + <ul id="toc"></ul> + <p> + The libvirt PVS driver can manage Parallels Virtuozzo Server starting from 6.0 version. + </p> + + + <h2><a name="project">Project Links</a></h2> + <ul> + <li> + The <a href="http://www.parallels.com/products/server/baremetal/sp/">Parallels Virtuozzo Server</a> Virtualization Solution. + </li> + </ul> + + + <h2><a name="uri">Connections to the Parallels Virtuozzo Server driver</a></h2> + <p> + The libvirt PVS driver is a single-instance privileged driver, with a driver name of 'pvs'. Some example connection URIs for the libvirt driver are: + </p> +<pre> +pvs:///default (local access) +pvs+unix:///default (local access) +pvs://example.com/default (remote access, TLS/x509) +pvs+tcp://example.com/default (remote access, SASl/Kerberos) +pvs+ssh://root@xxxxxxxxxxx/default (remote access, SSH tunnelled) +</pre> +</body></html> diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index e04d29e..8a7e8ba 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -87,6 +87,7 @@ typedef enum { VIR_FROM_CAPABILITIES = 44, /* Error from capabilities */ VIR_FROM_URI = 45, /* Error from URI handling */ VIR_FROM_AUTH = 46, /* Error from auth handling */ + VIR_FROM_PVS = 47, /* Error from PVS */ } virErrorDomain; diff --git a/libvirt.spec.in b/libvirt.spec.in index e7e0a55..a4e2460 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -65,6 +65,7 @@ %define with_esx 0%{!?_without_esx:1} %define with_hyperv 0%{!?_without_hyperv:1} %define with_xenapi 0%{!?_without_xenapi:1} +%define with_pvs 0%{!?_without_pvs:1} # Then the secondary host drivers, which run inside libvirtd %define with_network 0%{!?_without_network:%{server_drivers}} @@ -124,6 +125,7 @@ %define with_xenapi 0 %define with_libxl 0 %define with_hyperv 0 +%define with_pvs 0 %endif # Although earlier Fedora has systemd, libvirt still used sysvinit @@ -790,6 +792,10 @@ of recent versions of Linux (and other OSes). %define _without_vmware --without-vmware %endif +%if ! %{with_pvs} +%define _without_pvs --without-pvs +%endif + %if ! %{with_polkit} %define _without_polkit --without-polkit %endif @@ -920,6 +926,7 @@ autoreconf -if %{?_without_esx} \ %{?_without_hyperv} \ %{?_without_vmware} \ + %{?_without_pvs} \ %{?_without_network} \ %{?_with_rhel5_api} \ %{?_without_storage_fs} \ diff --git a/mingw32-libvirt.spec.in b/mingw32-libvirt.spec.in index 4d23c75..7d82bc2 100644 --- a/mingw32-libvirt.spec.in +++ b/mingw32-libvirt.spec.in @@ -18,6 +18,7 @@ # missing libwsman, so can't build hyper-v %define with_hyperv 0%{!?_without_hyperv:0} %define with_xenapi 0%{!?_without_xenapi:1} +%define with_pvs 0%{!?_without_pvs:0} # RHEL ships ESX but not PowerHypervisor, HyperV, or libxenserver (xenapi) %if 0%{?rhel} @@ -92,6 +93,10 @@ MinGW Windows libvirt virtualization library. %define _without_xenapi --without-xenapi %endif +%if ! %{with_pvs} +%define _without_pvs --without-pvs +%endif + %if 0%{?enable_autotools} autoreconf -if %endif @@ -113,6 +118,7 @@ autoreconf -if %{?_without_esx} \ %{?_without_hyperv} \ --without-vmware \ + --without-pvs \ --without-netcf \ --without-audit \ --without-dtrace diff --git a/po/POTFILES.in b/po/POTFILES.in index 5d5739a..ddfd3e3 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -163,6 +163,7 @@ src/xenapi/xenapi_driver.c src/xenapi/xenapi_utils.c src/xenxs/xen_sxpr.c src/xenxs/xen_xm.c +src/pvs/pvs_driver.c tools/console.c tools/libvirt-guests.init.sh tools/virsh.c diff --git a/src/Makefile.am b/src/Makefile.am index a2aae9d..3cbd385 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -465,6 +465,10 @@ HYPERV_DRIVER_EXTRA_DIST = \ hyperv/hyperv_wmi_generator.py \ $(HYPERV_DRIVER_GENERATED) +PVS_DRIVER_SOURCES = \ + pvs/pvs_driver.h \ + pvs/pvs_driver.c + NETWORK_DRIVER_SOURCES = \ network/bridge_driver.h network/bridge_driver.c @@ -930,6 +934,22 @@ endif libvirt_driver_hyperv_la_SOURCES = $(HYPERV_DRIVER_SOURCES) endif +if WITH_PVS +if WITH_DRIVER_MODULES +mod_LTLIBRARIES += libvirt_driver_pvs.la +else +noinst_LTLIBRARIES += libvirt_driver_pvs.la +libvirt_la_BUILT_LIBADD += libvirt_driver_pvs.la +endif +libvirt_driver_pvs_la_CFLAGS = -I$(top_srcdir)/src/conf $(AM_CFLAGS) +libvirt_driver_pvs_la_LDFLAGS = $(AM_LDFLAGS) +if WITH_DRIVER_MODULES +libvirt_driver_pvs_la_LIBADD = ../gnulib/lib/libgnu.la +libvirt_driver_pvs_la_LDFLAGS += -module -avoid-version +endif +libvirt_driver_pvs_la_SOURCES = $(PVS_DRIVER_SOURCES) +endif + if WITH_NETWORK if WITH_DRIVER_MODULES mod_LTLIBRARIES += libvirt_driver_network.la @@ -1130,6 +1150,7 @@ EXTRA_DIST += \ $(ESX_DRIVER_EXTRA_DIST) \ $(HYPERV_DRIVER_SOURCES) \ $(HYPERV_DRIVER_EXTRA_DIST) \ + $(PVS_DRIVER_SOURCES) \ $(NETWORK_DRIVER_SOURCES) \ $(INTERFACE_DRIVER_SOURCES) \ $(STORAGE_DRIVER_SOURCES) \ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c6b97e1..4385fc7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -93,7 +93,8 @@ VIR_ENUM_IMPL(virDomainVirt, VIR_DOMAIN_VIRT_LAST, "vmware", "hyperv", "vbox", - "phyp") + "phyp", + "pvs") VIR_ENUM_IMPL(virDomainBoot, VIR_DOMAIN_BOOT_LAST, "fd", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 0eed60e..7983e11 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -157,6 +157,7 @@ enum virDomainVirtType { VIR_DOMAIN_VIRT_HYPERV, VIR_DOMAIN_VIRT_VBOX, VIR_DOMAIN_VIRT_PHYP, + VIR_DOMAIN_VIRT_PVS, VIR_DOMAIN_VIRT_LAST, }; diff --git a/src/driver.h b/src/driver.h index 03d249b..1bcbd46 100644 --- a/src/driver.h +++ b/src/driver.h @@ -31,6 +31,7 @@ typedef enum { VIR_DRV_VMWARE = 13, VIR_DRV_LIBXL = 14, VIR_DRV_HYPERV = 15, + VIR_DRV_PVS = 16, } virDrvNo; diff --git a/src/libvirt.c b/src/libvirt.c index 16d1fd5..881dfb6 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -76,6 +76,9 @@ # ifdef WITH_XENAPI # include "xenapi/xenapi_driver.h" # endif +# ifdef WITH_PVS +# include "pvs/pvs_driver.h" +# endif #endif #define VIR_FROM_THIS VIR_FROM_NONE @@ -454,6 +457,9 @@ virInitialize(void) # ifdef WITH_XENAPI virDriverLoadModule("xenapi"); # endif +# ifdef WITH_PVS + virDriverLoadModule("pvs"); +# endif # ifdef WITH_REMOTE virDriverLoadModule("remote"); # endif @@ -485,6 +491,9 @@ virInitialize(void) # ifdef WITH_XENAPI if (xenapiRegister() == -1) return -1; # endif +# ifdef WITH_PVS + if (pvsRegister() == -1) return -1; +# endif # ifdef WITH_REMOTE if (remoteRegister () == -1) return -1; # endif @@ -1214,6 +1223,9 @@ do_open (const char *name, #ifndef WITH_XENAPI STRCASEEQ(ret->uri->scheme, "xenapi") || #endif +#ifndef WITH_PVS + STRCASEEQ(ret->uri->scheme, "pvs") || +#endif false)) { virReportErrorHelper(VIR_FROM_NONE, VIR_ERR_INVALID_ARG, __FILE__, __FUNCTION__, __LINE__, diff --git a/src/pvs/pvs_driver.c b/src/pvs/pvs_driver.c new file mode 100644 index 0000000..33bfa21 --- /dev/null +++ b/src/pvs/pvs_driver.c @@ -0,0 +1,263 @@ +/* + * pvs_driver.c: core driver functions for managing + * Parallels Virtuozzo Server hosts + * + * Copyright (C) 2012 Parallels, 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. + * + * 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 <sys/types.h> +#include <sys/poll.h> +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <sys/utsname.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <paths.h> +#include <pwd.h> +#include <stdio.h> +#include <sys/wait.h> +#include <sys/time.h> +#include <dirent.h> +#include <sys/statvfs.h> + +#include "datatypes.h" +#include "virterror_internal.h" +#include "memory.h" +#include "util.h" +#include "logging.h" +#include "command.h" +#include "configmake.h" +#include "storage_file.h" +#include "nodeinfo.h" +#include "json.h" + +#include "pvs_driver.h" + +#define VIR_FROM_THIS VIR_FROM_PVS + +static virCapsPtr pvsBuildCapabilities(void); +static int pvsClose(virConnectPtr conn); + +static void +pvsDriverLock(pvsConnPtr driver) +{ + virMutexLock(&driver->lock); +} + +static void +pvsDriverUnlock(pvsConnPtr driver) +{ + virMutexUnlock(&driver->lock); +} + +static int +pvsDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED) +{ + return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL; +} + +static virCapsPtr +pvsBuildCapabilities(void) +{ + virCapsPtr caps; + virCapsGuestPtr guest; + struct utsname utsname; + uname(&utsname); + + if ((caps = virCapabilitiesNew(utsname.machine, 0, 0)) == NULL) + goto no_memory; + + if (nodeCapsInitNUMA(caps) < 0) + goto no_memory; + + virCapabilitiesSetMacPrefix(caps, (unsigned char[]) { + 0x42, 0x1C, 0x00}); + + if ((guest = virCapabilitiesAddGuest(caps, "hvm", "x86_64", + 64, "parallels", + NULL, 0, NULL)) == NULL) + goto no_memory; + + if (virCapabilitiesAddGuestDomain(guest, + "pvs", NULL, NULL, 0, NULL) == NULL) + goto no_memory; + + caps->defaultConsoleTargetType = pvsDefaultConsoleType; + return caps; + + no_memory: + virReportOOMError(); + virCapabilitiesFree(caps); + return NULL; +} + +static char * +pvsGetCapabilities(virConnectPtr conn) +{ + pvsConnPtr privconn = conn->privateData; + char *xml; + + pvsDriverLock(privconn); + if ((xml = virCapabilitiesFormatXML(privconn->caps)) == NULL) + virReportOOMError(); + pvsDriverUnlock(privconn); + return xml; +} + +static int +pvsOpenDefault(virConnectPtr conn) +{ + pvsConnPtr privconn; + + if (VIR_ALLOC(privconn) < 0) { + virReportOOMError(); + return VIR_DRV_OPEN_ERROR; + } + if (virMutexInit(&privconn->lock) < 0) { + pvsError(VIR_ERR_INTERNAL_ERROR, + "%s", _("cannot initialize mutex")); + goto error; + } + + pvsDriverLock(privconn); + conn->privateData = privconn; + pvsDriverUnlock(privconn); + + if (!(privconn->caps = pvsBuildCapabilities())) + goto error; + + if (virDomainObjListInit(&privconn->domains) < 0) + goto error; + + return VIR_DRV_OPEN_SUCCESS; + + error: + virDomainObjListDeinit(&privconn->domains); + virCapabilitiesFree(privconn->caps); + virStoragePoolObjListFree(&privconn->pools); + pvsDriverUnlock(privconn); + conn->privateData = NULL; + VIR_FREE(privconn); + return VIR_DRV_OPEN_ERROR; +} + +static virDrvOpenStatus +pvsOpen(virConnectPtr conn, + virConnectAuthPtr auth ATTRIBUTE_UNUSED, unsigned int flags) +{ + int ret; + pvsConnPtr privconn; + virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); + + if (!conn->uri) + return VIR_DRV_OPEN_DECLINED; + + if (!conn->uri->scheme || STRNEQ(conn->uri->scheme, "pvs")) + return VIR_DRV_OPEN_DECLINED; + + /* Remote driver should handle these. */ + if (conn->uri->server) + return VIR_DRV_OPEN_DECLINED; + + /* From this point on, the connection is for us. */ + if (!conn->uri->path + || conn->uri->path[0] == '\0' + || (conn->uri->path[0] == '/' && conn->uri->path[1] == '\0')) { + pvsError(VIR_ERR_INVALID_ARG, + "%s", _("pvsOpen: supply a path or use pvs:///default")); + return VIR_DRV_OPEN_ERROR; + } + + if (STREQ(conn->uri->path, "/default")) + ret = pvsOpenDefault(conn); + else + return VIR_DRV_OPEN_DECLINED; + + if (ret != VIR_DRV_OPEN_SUCCESS) + return ret; + + privconn = conn->privateData; + pvsDriverLock(privconn); + privconn->domainEventState = virDomainEventStateNew(); + if (!privconn->domainEventState) { + pvsDriverUnlock(privconn); + pvsClose(conn); + return VIR_DRV_OPEN_ERROR; + } + + pvsDriverUnlock(privconn); + return VIR_DRV_OPEN_SUCCESS; +} + +static int +pvsClose(virConnectPtr conn) +{ + pvsConnPtr privconn = conn->privateData; + + pvsDriverLock(privconn); + virCapabilitiesFree(privconn->caps); + virDomainObjListDeinit(&privconn->domains); + virDomainEventStateFree(privconn->domainEventState); + conn->privateData = NULL; + + pvsDriverUnlock(privconn); + virMutexDestroy(&privconn->lock); + + VIR_FREE(privconn); + return 0; +} + +static int +pvsGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *hvVer) +{ + /* TODO */ + *hvVer = 6; + return 0; +} + +static virDriver pvsDriver = { + .no = VIR_DRV_PVS, + .name = "PVS", + .open = pvsOpen, /* 0.9.11 */ + .close = pvsClose, /* 0.9.11 */ + .version = pvsGetVersion, /* 0.9.11 */ + .getHostname = virGetHostname, /* 0.9.11 */ + .nodeGetInfo = nodeGetInfo, /* 0.9.11 */ + .getCapabilities = pvsGetCapabilities, /* 0.9.11 */ +}; + +/** + * pvsRegister: + * + * Registers the pvs driver + */ +int +pvsRegister(void) +{ + if (virRegisterDriver(&pvsDriver) < 0) + return -1; + + return 0; +} diff --git a/src/pvs/pvs_driver.h b/src/pvs/pvs_driver.h new file mode 100644 index 0000000..289cc28 --- /dev/null +++ b/src/pvs/pvs_driver.h @@ -0,0 +1,49 @@ +/* + * pvs_driver.h: core driver functions for managing + * Parallels Virtuozzo Server hosts + * + * Copyright (C) 2012 Parallels, 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. + * + * 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 PVS_DRIVER_H +# define PVS_DRIVER_H + + +#include "domain_conf.h" +#include "storage_conf.h" +#include "domain_event.h" + +#define pvsError(code, ...) \ + virReportErrorHelper(VIR_FROM_TEST, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) + +struct _pvsConn { + virMutex lock; + virDomainObjList domains; + virStoragePoolObjList pools; + virCapsPtr caps; + virDomainEventStatePtr domainEventState; +}; + +typedef struct _pvsConn pvsConn; + +typedef struct _pvsConn *pvsConnPtr; + +int pvsRegister(void); + +#endif diff --git a/src/util/virterror.c b/src/util/virterror.c index ff9a36f..4976c08 100644 --- a/src/util/virterror.c +++ b/src/util/virterror.c @@ -175,6 +175,9 @@ static const char *virErrorDomainName(virErrorDomain domain) { case VIR_FROM_HYPERV: dom = "Hyper-V "; break; + case VIR_FROM_PVS: + dom = "Parallels Virtuozzo Server "; + break; case VIR_FROM_CAPABILITIES: dom = "Capabilities "; break; -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list