[libvirt] [PATCH v6 1/9] pvs: add driver skeleton

Dmitry Guryanov dguryanov at parallels.com
Wed May 2 18:32:36 UTC 2012


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

Current name of this product is Parallels Server Bare Metal and
more information about it can be found here -
http://www.parallels.com/products/server/baremetal/sp/.

This first patch adds driver, which can report node info only.

Signed-off-by: Dmitry Guryanov <dguryanov at parallels.com>
---

changes in v6:
  * Add info about PVS to commit message
  * fixed issue with POTFILES.in
  * fixed check in configure
  * check for prlctl command existence moved to pvsRegister
changes in v5:
  * add me to AUTHORS
  * fix indent in preprocessor directives in pvs_driver.h
  * remove unneded include
  * remove pvs_driver.c from po/POTFILES.in

 AUTHORS                     |    1 +
 cfg.mk                      |    1 +
 configure.ac                |   23 ++++
 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        |  271 +++++++++++++++++++++++++++++++++++++++++++
 src/pvs/pvs_driver.h        |   51 ++++++++
 src/util/virterror.c        |    3 +
 16 files changed, 430 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/AUTHORS b/AUTHORS
index 06b830a..0750512 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -234,6 +234,7 @@ Patches have also been contributed by:
   Jan Kiszka           <jan.kiszka at siemens.com>
   Ryan Woodsmall       <rwoodsmall at gmail.com>
   Wido den Hollander   <wido at widodh.nl>
+  Dmitry Guryanov      <dguryanov at parallels.com>
 
   [....send patches to get your name here....]
 
diff --git a/cfg.mk b/cfg.mk
index 9dab3c3..f940c29 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -513,6 +513,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 a819898..35519af 100644
--- a/configure.ac
+++ b/configure.ac
@@ -331,6 +331,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],
@@ -795,6 +797,26 @@ 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
+    if test ! $host_cpu = 'x86_64'; then
+        with_pvs=no
+    fi
+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
@@ -2706,6 +2728,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@example.com/default (remote access, SSH tunnelled)
+</pre>
+</body></html>
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 7283207..b4cc821 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -88,6 +88,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_PVS = 48,          /* 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 4ea544b..9fc809f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -60,6 +60,7 @@ src/nwfilter/nwfilter_learnipaddr.c
 src/openvz/openvz_conf.c
 src/openvz/openvz_driver.c
 src/phyp/phyp_driver.c
+src/pvs/pvs_driver.c
 src/qemu/qemu_agent.c
 src/qemu/qemu_bridge_filter.c
 src/qemu/qemu_capabilities.c
diff --git a/src/Makefile.am b/src/Makefile.am
index e48dfa5..ec9b1d0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -466,6 +466,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
 
@@ -932,6 +936,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
@@ -1132,6 +1152,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 184ff23..8b5f650 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 5aa8fc1..ac486d4 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 cfd7711..0c73eca 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..3898ba8
--- /dev/null
+++ b/src/pvs/pvs_driver.c
@@ -0,0 +1,271 @@
+/*
+ * 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 <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.12 */
+    .close = pvsClose,          /* 0.9.12 */
+    .version = pvsGetVersion,   /* 0.9.12 */
+    .getHostname = virGetHostname,      /* 0.9.12 */
+    .nodeGetInfo = nodeGetInfo,      /* 0.9.12 */
+    .getCapabilities = pvsGetCapabilities,      /* 0.9.12 */
+};
+
+/**
+ * pvsRegister:
+ *
+ * Registers the pvs driver
+ */
+int
+pvsRegister(void)
+{
+    char *prlctl_path;
+
+    prlctl_path = virFindFileInPath(PRLCTL);
+    if (!prlctl_path) {
+        pvsError(VIR_ERR_INTERNAL_ERROR, "%s",
+                 _("Can't find prlctl command in the PATH env"));
+        return VIR_DRV_OPEN_ERROR;
+    }
+
+    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..f5021e3
--- /dev/null
+++ b/src/pvs/pvs_driver.h
@@ -0,0 +1,51 @@
+/*
+ * 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
+ *
+ */
+
+#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__)
+# define PRLCTL      "prlctl"
+
+
+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 b1a5d2b..8559a8d 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -187,6 +187,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
         case VIR_FROM_DBUS:
             dom = "DBus ";
             break;
+        case VIR_FROM_PVS:
+            dom = "Parallels Virtuozzo Server ";
+            break;
     }
     return dom;
 }
-- 
1.7.1




More information about the libvir-list mailing list