parallels: add driver skeleton

Parallels Cloud Server is a cloud-ready virtualization
solution that allows users to simultaneously run multiple virtual
machines and containers on the same physical server.

More information can be found here: http://www.parallels.com/products/pcs/
Also beta version of Parallels Cloud Server can be downloaded there.

Signed-off-by: Dmitry Guryanov <dguryanov@parallels.com>
This commit is contained in:
Dmitry Guryanov 2012-07-31 22:56:05 +04:00 committed by Daniel Veillard
parent 2beed2daaf
commit cafc26ff5f
14 changed files with 415 additions and 22 deletions

View File

@ -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([parallels],
AC_HELP_STRING([--with-parallels], [add Parallels Cloud Server support @<:@default=check@:>@]),[],[with_parallels=check])
AC_ARG_WITH([test],
AC_HELP_STRING([--with-test], [add test driver support @<:@default=yes@:>@]),[],[with_test=yes])
AC_ARG_WITH([remote],
@ -787,6 +789,26 @@ if test "$with_lxc" = "yes" ; then
fi
AM_CONDITIONAL([WITH_LXC], [test "$with_lxc" = "yes"])
dnl
dnl Checks for the Parallels driver
dnl
if test "$with_parallels" = "check"; then
with_parallels=$with_linux
if test ! $host_cpu = 'x86_64'; then
with_parallels=no
fi
fi
if test "$with_parallels" = "yes" && test "$with_linux" = "no"; then
AC_MSG_ERROR([The Parallels driver can be enabled on Linux only.])
fi
if test "$with_parallels" = "yes"; then
AC_DEFINE_UNQUOTED([WITH_PARALLELS], 1, [whether Parallels driver is enabled])
fi
AM_CONDITIONAL([WITH_PARALLELS], [test "$with_parallels" = "yes"])
dnl
dnl check for shell that understands <> redirection without truncation,
dnl needed by src/qemu/qemu_monitor_{text,json}.c.
@ -2824,25 +2846,26 @@ AC_MSG_NOTICE([=====================])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Drivers])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([ Xen: $with_xen])
AC_MSG_NOTICE([ QEMU: $with_qemu])
AC_MSG_NOTICE([ UML: $with_uml])
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([ ESX: $with_esx])
AC_MSG_NOTICE([ Hyper-V: $with_hyperv])
AC_MSG_NOTICE([ Test: $with_test])
AC_MSG_NOTICE([ Remote: $with_remote])
AC_MSG_NOTICE([ Network: $with_network])
AC_MSG_NOTICE([Libvirtd: $with_libvirtd])
AC_MSG_NOTICE([ netcf: $with_netcf])
AC_MSG_NOTICE([ macvtap: $with_macvtap])
AC_MSG_NOTICE([virtport: $with_virtualport])
AC_MSG_NOTICE([ Xen: $with_xen])
AC_MSG_NOTICE([ QEMU: $with_qemu])
AC_MSG_NOTICE([ UML: $with_uml])
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([ ESX: $with_esx])
AC_MSG_NOTICE([ Hyper-V: $with_hyperv])
AC_MSG_NOTICE([Parallels: $with_parallels])
AC_MSG_NOTICE([ Test: $with_test])
AC_MSG_NOTICE([ Remote: $with_remote])
AC_MSG_NOTICE([ Network: $with_network])
AC_MSG_NOTICE([ Libvirtd: $with_libvirtd])
AC_MSG_NOTICE([ netcf: $with_netcf])
AC_MSG_NOTICE([ macvtap: $with_macvtap])
AC_MSG_NOTICE([ virtport: $with_virtualport])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Storage Drivers])
AC_MSG_NOTICE([])

28
docs/drvparallels.html.in Normal file
View File

@ -0,0 +1,28 @@
<html><body>
<h1>Parallels Cloud Server driver</h1>
<ul id="toc"></ul>
<p>
The libvirt Parallels driver can manage Parallels Cloud Server starting from version 6.0.
</p>
<h2><a name="project">Project Links</a></h2>
<ul>
<li>
The <a href="http://www.parallels.com/products/server/baremetal/sp/">Parallels Cloud Server</a> Virtualization Solution.
</li>
</ul>
<h2><a name="uri">Connections to the Parallels Cloud Server driver</a></h2>
<p>
The libvirt Parallels driver is a single-instance privileged driver, with a driver name of 'parallels'. Some example connection URIs for the libvirt driver are:
</p>
<pre>
parallels:///default (local access)
parallels+unix:///default (local access)
parallels://example.com/default (remote access, TLS/x509)
parallels+tcp://example.com/default (remote access, SASl/Kerberos)
parallels+ssh://root@example.com/default (remote access, SSH tunnelled)
</pre>
</body></html>

View File

@ -109,6 +109,7 @@ typedef enum {
VIR_FROM_URI = 45, /* Error from URI handling */
VIR_FROM_AUTH = 46, /* Error from auth handling */
VIR_FROM_DBUS = 47, /* Error from DBus */
VIR_FROM_PARALLELS = 48, /* Error from Parallels */
# ifdef VIR_ENUM_SENTINELS
VIR_ERR_DOMAIN_LAST

View File

@ -67,6 +67,7 @@
%define with_esx 0%{!?_without_esx:1}
%define with_hyperv 0%{!?_without_hyperv:1}
%define with_xenapi 0%{!?_without_xenapi:1}
%define with_parallels 0%{!?_without_parallels:1}
# Then the secondary host drivers, which run inside libvirtd
%define with_network 0%{!?_without_network:%{server_drivers}}
@ -136,6 +137,7 @@
%define with_xenapi 0
%define with_libxl 0
%define with_hyperv 0
%define with_parallels 0
%endif
# Fedora 17 / RHEL-7 are first where we use systemd. Although earlier
@ -1068,6 +1070,10 @@ of recent versions of Linux (and other OSes).
%define _without_vmware --without-vmware
%endif
%if ! %{with_parallels}
%define _without_parallels --without-parallels
%endif
%if ! %{with_polkit}
%define _without_polkit --without-polkit
%endif
@ -1210,6 +1216,7 @@ autoreconf -if
%{?_without_esx} \
%{?_without_hyperv} \
%{?_without_vmware} \
%{?_without_parallels} \
%{?_without_network} \
%{?_with_rhel5_api} \
%{?_without_storage_fs} \
@ -1401,7 +1408,7 @@ fi
/sbin/chkconfig --add libvirtd
if [ "$1" -ge "1" ]; then
/sbin/service libvirtd condrestart > /dev/null 2>&1
/sbin/service libvirtd condrestart > /dev/null 2>&1
fi
%endif

View File

@ -13,6 +13,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_parallels 0%{!?_without_parallels:0}
# RHEL ships ESX but not PowerHypervisor, HyperV, or libxenserver (xenapi)
%if 0%{?rhel}
@ -125,6 +126,10 @@ MinGW Windows libvirt virtualization library, static version.
%define _without_xenapi --without-xenapi
%endif
%if ! %{with_parallels}
%define _without_parallels --without-parallels
%endif
%if 0%{?enable_autotools}
autoreconf -if
%endif
@ -148,6 +153,7 @@ autoreconf -if
%{?_without_esx} \
%{?_without_hyperv} \
--without-vmware \
--without-parallels \
--without-netcf \
--without-audit \
--without-dtrace

View File

@ -65,6 +65,7 @@ src/nwfilter/nwfilter_learnipaddr.c
src/openvz/openvz_conf.c
src/openvz/openvz_driver.c
src/openvz/openvz_util.c
src/parallels/parallels_driver.c
src/phyp/phyp_driver.c
src/qemu/qemu_agent.c
src/qemu/qemu_bridge_filter.c

View File

@ -529,6 +529,10 @@ HYPERV_DRIVER_EXTRA_DIST = \
hyperv/hyperv_wmi_generator.py \
$(HYPERV_DRIVER_GENERATED)
PARALLELS_DRIVER_SOURCES = \
parallels/parallels_driver.h \
parallels/parallels_driver.c
NETWORK_DRIVER_SOURCES = \
network/bridge_driver.h network/bridge_driver.c
@ -967,6 +971,14 @@ libvirt_driver_hyperv_la_LIBADD = $(OPENWSMAN_LIBS)
libvirt_driver_hyperv_la_SOURCES = $(HYPERV_DRIVER_SOURCES)
endif
if WITH_PARALLELS
noinst_LTLIBRARIES += libvirt_driver_parallels.la
libvirt_la_BUILT_LIBADD += libvirt_driver_parallels.la
libvirt_driver_parallels_la_CFLAGS = \
-I$(top_srcdir)/src/conf $(AM_CFLAGS)
libvirt_driver_parallels_la_SOURCES = $(PARALLELS_DRIVER_SOURCES)
endif
if WITH_NETWORK
noinst_LTLIBRARIES += libvirt_driver_network_impl.la
libvirt_driver_network_la_SOURCES =
@ -1180,6 +1192,7 @@ EXTRA_DIST += \
$(ESX_DRIVER_EXTRA_DIST) \
$(HYPERV_DRIVER_SOURCES) \
$(HYPERV_DRIVER_EXTRA_DIST) \
$(PARALLELS_DRIVER_SOURCES) \
$(NETWORK_DRIVER_SOURCES) \
$(INTERFACE_DRIVER_SOURCES) \
$(STORAGE_DRIVER_SOURCES) \

View File

@ -93,7 +93,8 @@ VIR_ENUM_IMPL(virDomainVirt, VIR_DOMAIN_VIRT_LAST,
"vmware",
"hyperv",
"vbox",
"phyp")
"phyp",
"parallels")
VIR_ENUM_IMPL(virDomainBoot, VIR_DOMAIN_BOOT_LAST,
"fd",

View File

@ -160,6 +160,7 @@ enum virDomainVirtType {
VIR_DOMAIN_VIRT_HYPERV,
VIR_DOMAIN_VIRT_VBOX,
VIR_DOMAIN_VIRT_PHYP,
VIR_DOMAIN_VIRT_PARALLELS,
VIR_DOMAIN_VIRT_LAST,
};

View File

@ -31,6 +31,7 @@ typedef enum {
VIR_DRV_VMWARE = 13,
VIR_DRV_LIBXL = 14,
VIR_DRV_HYPERV = 15,
VIR_DRV_PARALLELS = 16,
} virDrvNo;

View File

@ -84,6 +84,9 @@
#ifdef WITH_XENAPI
# include "xenapi/xenapi_driver.h"
#endif
#ifdef WITH_PARALLELS
# include "parallels/parallels_driver.h"
#endif
#define VIR_FROM_THIS VIR_FROM_NONE
@ -455,6 +458,9 @@ virInitialize(void)
#ifdef WITH_XENAPI
if (xenapiRegister() == -1) return -1;
#endif
#ifdef WITH_PARALLELS
if (parallelsRegister() == -1) return -1;
#endif
#ifdef WITH_REMOTE
if (remoteRegister () == -1) return -1;
#endif
@ -1155,6 +1161,9 @@ do_open (const char *name,
#endif
#ifndef WITH_XENAPI
STRCASEEQ(ret->uri->scheme, "xenapi") ||
#endif
#ifndef WITH_PARALLELS
STRCASEEQ(ret->uri->scheme, "parallels") ||
#endif
false)) {
virReportErrorHelper(VIR_FROM_NONE, VIR_ERR_CONFIG_UNSUPPORTED,

View File

@ -0,0 +1,273 @@
/*
* parallels_driver.c: core driver functions for managing
* Parallels Cloud 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, see
* <http://www.gnu.org/licenses/>.
*
*/
#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 <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 "storage_conf.h"
#include "nodeinfo.h"
#include "json.h"
#include "domain_conf.h"
#include "parallels_driver.h"
#define VIR_FROM_THIS VIR_FROM_PARALLELS
#define PRLCTL "prlctl"
#define PARALLELS_DEFAULT_ARCH "x86_64"
struct _parallelsConn {
virMutex lock;
virDomainObjList domains;
virStoragePoolObjList pools;
virCapsPtr caps;
};
typedef struct _parallelsConn parallelsConn;
typedef struct _parallelsConn *parallelsConnPtr;
static int parallelsClose(virConnectPtr conn);
static void
parallelsDriverLock(parallelsConnPtr driver)
{
virMutexLock(&driver->lock);
}
static void
parallelsDriverUnlock(parallelsConnPtr driver)
{
virMutexUnlock(&driver->lock);
}
static int
parallelsDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED)
{
return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
}
static virCapsPtr
parallelsBuildCapabilities(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", PARALLELS_DEFAULT_ARCH,
64, "parallels",
NULL, 0, NULL)) == NULL)
goto no_memory;
if (virCapabilitiesAddGuestDomain(guest,
"parallels", NULL, NULL, 0, NULL) == NULL)
goto no_memory;
caps->defaultConsoleTargetType = parallelsDefaultConsoleType;
return caps;
no_memory:
virReportOOMError();
virCapabilitiesFree(caps);
return NULL;
}
static char *
parallelsGetCapabilities(virConnectPtr conn)
{
parallelsConnPtr privconn = conn->privateData;
char *xml;
parallelsDriverLock(privconn);
if ((xml = virCapabilitiesFormatXML(privconn->caps)) == NULL)
virReportOOMError();
parallelsDriverUnlock(privconn);
return xml;
}
static int
parallelsOpenDefault(virConnectPtr conn)
{
parallelsConnPtr privconn;
if (VIR_ALLOC(privconn) < 0) {
virReportOOMError();
return VIR_DRV_OPEN_ERROR;
}
if (virMutexInit(&privconn->lock) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot initialize mutex"));
goto error;
}
if (!(privconn->caps = parallelsBuildCapabilities()))
goto error;
if (virDomainObjListInit(&privconn->domains) < 0)
goto error;
conn->privateData = privconn;
return VIR_DRV_OPEN_SUCCESS;
error:
virDomainObjListDeinit(&privconn->domains);
virCapabilitiesFree(privconn->caps);
virStoragePoolObjListFree(&privconn->pools);
VIR_FREE(privconn);
return VIR_DRV_OPEN_ERROR;
}
static virDrvOpenStatus
parallelsOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
unsigned int flags)
{
int ret;
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
if (!conn->uri)
return VIR_DRV_OPEN_DECLINED;
if (!conn->uri->scheme || STRNEQ(conn->uri->scheme, "parallels"))
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[0] == '\0' ||
(conn->uri->path[0] == '/' && conn->uri->path[1] == '\0')) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("parallelsOpen: supply a path or use "
"parallels:///session"));
return VIR_DRV_OPEN_ERROR;
}
if (STREQ(conn->uri->path, "/session"))
ret = parallelsOpenDefault(conn);
else
return VIR_DRV_OPEN_DECLINED;
if (ret != VIR_DRV_OPEN_SUCCESS)
return ret;
return VIR_DRV_OPEN_SUCCESS;
}
static int
parallelsClose(virConnectPtr conn)
{
parallelsConnPtr privconn = conn->privateData;
parallelsDriverLock(privconn);
virCapabilitiesFree(privconn->caps);
virDomainObjListDeinit(&privconn->domains);
conn->privateData = NULL;
parallelsDriverUnlock(privconn);
virMutexDestroy(&privconn->lock);
VIR_FREE(privconn);
return 0;
}
static int
parallelsGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *hvVer)
{
/* TODO */
*hvVer = 6;
return 0;
}
static virDriver parallelsDriver = {
.no = VIR_DRV_PARALLELS,
.name = "Parallels",
.open = parallelsOpen, /* 0.10.0 */
.close = parallelsClose, /* 0.10.0 */
.version = parallelsGetVersion, /* 0.10.0 */
.getHostname = virGetHostname, /* 0.10.0 */
.nodeGetInfo = nodeGetInfo, /* 0.10.0 */
.getCapabilities = parallelsGetCapabilities, /* 0.10.0 */
};
/**
* parallelsRegister:
*
* Registers the parallels driver
*/
int
parallelsRegister(void)
{
char *prlctl_path;
prlctl_path = virFindFileInPath(PRLCTL);
if (!prlctl_path) {
VIR_DEBUG("%s", _("Can't find prlctl command in the PATH env"));
return 0;
}
VIR_FREE(prlctl_path);
if (virRegisterDriver(&parallelsDriver) < 0)
return -1;
return 0;
}

View File

@ -0,0 +1,28 @@
/*
* parallels_driver.c: core driver functions for managing
* Parallels Cloud 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, see
* <http://www.gnu.org/licenses/>.
*
*/
#ifndef PARALLELS_DRIVER_H
# define PARALLELS_DRIVER_H
int parallelsRegister(void);
#endif

View File

@ -111,7 +111,8 @@ VIR_ENUM_IMPL(virErrorDomain, VIR_ERR_DOMAIN_LAST,
"URI Utils", /* 45 */
"Authentication Utils",
"DBus Utils"
"DBus Utils",
"Parallels Cloud Server"
)