2012-07-31 18:56:05 +00:00
|
|
|
/*
|
2015-06-10 07:50:00 +00:00
|
|
|
* vz_driver.c: core driver functions for managing
|
2012-07-31 18:56:05 +00:00
|
|
|
* Parallels Cloud Server hosts
|
|
|
|
*
|
2015-01-15 14:02:44 +00:00
|
|
|
* Copyright (C) 2014-2015 Red Hat, Inc.
|
2012-07-31 18:56:05 +00:00
|
|
|
* 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
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-31 18:56:05 +00:00
|
|
|
* <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/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <paths.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/statvfs.h>
|
|
|
|
|
|
|
|
#include "datatypes.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
2012-12-12 16:27:01 +00:00
|
|
|
#include "vircommand.h"
|
2012-07-31 18:56:05 +00:00
|
|
|
#include "configmake.h"
|
2013-05-09 18:59:04 +00:00
|
|
|
#include "virfile.h"
|
2012-12-13 15:25:48 +00:00
|
|
|
#include "virstoragefile.h"
|
2012-07-31 18:56:05 +00:00
|
|
|
#include "nodeinfo.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2014-06-05 05:50:05 +00:00
|
|
|
#include "cpu/cpu.h"
|
2015-06-09 07:35:53 +00:00
|
|
|
#include "virtypedparam.h"
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
#include "vz_driver.h"
|
|
|
|
#include "vz_utils.h"
|
|
|
|
#include "vz_sdk.h"
|
2012-07-31 18:56:05 +00:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_PARALLELS
|
|
|
|
|
2014-02-28 12:16:17 +00:00
|
|
|
VIR_LOG_INIT("parallels.parallels_driver");
|
|
|
|
|
2012-07-31 18:56:05 +00:00
|
|
|
#define PRLCTL "prlctl"
|
2012-07-31 18:56:07 +00:00
|
|
|
#define PRLSRVCTL "prlsrvctl"
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzConnectClose(virConnectPtr conn);
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2012-08-01 03:46:22 +00:00
|
|
|
void
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(vzConnPtr driver)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
|
|
|
virMutexLock(&driver->lock);
|
|
|
|
}
|
|
|
|
|
2012-08-01 03:46:22 +00:00
|
|
|
void
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(vzConnPtr driver)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
|
|
|
virMutexUnlock(&driver->lock);
|
|
|
|
}
|
|
|
|
|
2015-07-03 17:26:00 +00:00
|
|
|
static int
|
|
|
|
vzCapsAddGuestDomain(virCapsPtr caps,
|
|
|
|
virDomainOSType ostype,
|
|
|
|
virArch arch,
|
|
|
|
const char * emulator,
|
|
|
|
virDomainVirtType virt_type)
|
|
|
|
{
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
if ((guest = virCapabilitiesAddGuest(caps, ostype, arch, emulator,
|
|
|
|
NULL, 0, NULL)) == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
if (virCapabilitiesAddGuestDomain(guest, virt_type,
|
|
|
|
NULL, NULL, 0, NULL) == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-07-31 18:56:05 +00:00
|
|
|
static virCapsPtr
|
2015-06-10 07:50:00 +00:00
|
|
|
vzBuildCapabilities(void)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
2014-06-05 05:50:06 +00:00
|
|
|
virCapsPtr caps = NULL;
|
|
|
|
virCPUDefPtr cpu = NULL;
|
|
|
|
virCPUDataPtr data = NULL;
|
|
|
|
virNodeInfo nodeinfo;
|
2015-07-03 17:26:00 +00:00
|
|
|
virDomainOSType ostypes[] = {
|
|
|
|
VIR_DOMAIN_OSTYPE_HVM,
|
|
|
|
VIR_DOMAIN_OSTYPE_EXE
|
|
|
|
};
|
|
|
|
virArch archs[] = { VIR_ARCH_I686, VIR_ARCH_X86_64 };
|
|
|
|
const char *const emulators[] = { "parallels", "vz" };
|
|
|
|
virDomainVirtType virt_types[] = {
|
|
|
|
VIR_DOMAIN_VIRT_PARALLELS,
|
|
|
|
VIR_DOMAIN_VIRT_VZ
|
|
|
|
};
|
|
|
|
size_t i, j, k;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2012-12-10 22:28:09 +00:00
|
|
|
if ((caps = virCapabilitiesNew(virArchFromHost(),
|
2014-07-14 12:56:13 +00:00
|
|
|
false, false)) == NULL)
|
2013-07-04 10:13:24 +00:00
|
|
|
return NULL;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2015-07-07 21:22:28 +00:00
|
|
|
if (nodeCapsInitNUMA(NULL, caps) < 0)
|
2013-07-04 10:13:24 +00:00
|
|
|
goto error;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2015-07-03 17:26:00 +00:00
|
|
|
for (i = 0; i < 2; i++)
|
|
|
|
for (j = 0; j < 2; j++)
|
|
|
|
for (k = 0; k < 2; k++)
|
|
|
|
if (vzCapsAddGuestDomain(caps, ostypes[i], archs[j],
|
|
|
|
emulators[k], virt_types[k]) < 0)
|
|
|
|
goto error;
|
2015-05-26 17:12:00 +00:00
|
|
|
|
2015-07-07 11:27:53 +00:00
|
|
|
if (nodeGetInfo(NULL, &nodeinfo))
|
2014-06-05 05:50:06 +00:00
|
|
|
goto error;
|
|
|
|
|
2014-06-09 07:36:30 +00:00
|
|
|
if (VIR_ALLOC(cpu) < 0)
|
2014-06-05 05:50:06 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
cpu->arch = caps->host.arch;
|
|
|
|
cpu->type = VIR_CPU_TYPE_HOST;
|
|
|
|
cpu->sockets = nodeinfo.sockets;
|
|
|
|
cpu->cores = nodeinfo.cores;
|
|
|
|
cpu->threads = nodeinfo.threads;
|
|
|
|
|
|
|
|
caps->host.cpu = cpu;
|
|
|
|
|
|
|
|
if (!(data = cpuNodeData(cpu->arch))
|
|
|
|
|| cpuDecode(cpu, data, NULL, 0, NULL) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
cpuDataFree(data);
|
2012-07-31 18:56:05 +00:00
|
|
|
return caps;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
error:
|
2013-02-01 12:26:18 +00:00
|
|
|
virObjectUnref(caps);
|
2014-06-05 05:50:06 +00:00
|
|
|
goto cleanup;
|
2012-07-31 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectGetCapabilities(virConnectPtr conn)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-07-31 18:56:05 +00:00
|
|
|
char *xml;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2014-06-27 07:55:44 +00:00
|
|
|
xml = virCapabilitiesFormatXML(privconn->caps);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2012-07-31 18:56:05 +00:00
|
|
|
return xml;
|
|
|
|
}
|
|
|
|
|
2014-10-06 15:28:46 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainDefPostParse(virDomainDefPtr def,
|
2015-06-25 07:56:56 +00:00
|
|
|
virCapsPtr caps ATTRIBUTE_UNUSED,
|
|
|
|
void *opaque ATTRIBUTE_UNUSED)
|
2014-10-06 15:28:46 +00:00
|
|
|
{
|
2014-08-11 15:40:32 +00:00
|
|
|
/* memory hotplug tunables are not supported by this driver */
|
|
|
|
if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2014-10-06 15:28:46 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
2015-06-25 07:56:56 +00:00
|
|
|
const virDomainDef *def,
|
|
|
|
virCapsPtr caps ATTRIBUTE_UNUSED,
|
|
|
|
void *opaque ATTRIBUTE_UNUSED)
|
2014-10-06 15:28:46 +00:00
|
|
|
{
|
2015-03-18 08:33:55 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (dev->type == VIR_DOMAIN_DEVICE_NET &&
|
|
|
|
(dev->data.net->type == VIR_DOMAIN_NET_TYPE_NETWORK ||
|
|
|
|
dev->data.net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) &&
|
|
|
|
!dev->data.net->model &&
|
2015-04-17 00:11:06 +00:00
|
|
|
def->os.type == VIR_DOMAIN_OSTYPE_HVM &&
|
2015-03-18 08:33:55 +00:00
|
|
|
VIR_STRDUP(dev->data.net->model, "e1000") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
2014-10-06 15:28:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
virDomainDefParserConfig vzDomainDefParserConfig = {
|
2013-03-15 14:44:12 +00:00
|
|
|
.macPrefix = {0x42, 0x1C, 0x00},
|
2015-06-10 07:50:00 +00:00
|
|
|
.devicesPostParseCallback = vzDomainDeviceDefPostParse,
|
|
|
|
.domainPostParseCallback = vzDomainDefPostParse,
|
2013-03-15 14:44:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-07-31 18:56:05 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzOpenDefault(virConnectPtr conn)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2013-07-04 10:13:24 +00:00
|
|
|
if (VIR_ALLOC(privconn) < 0)
|
2012-07-31 18:56:05 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
if (virMutexInit(&privconn->lock) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("cannot initialize mutex"));
|
2014-09-11 16:24:03 +00:00
|
|
|
goto err_free;
|
|
|
|
}
|
|
|
|
|
2015-05-26 17:12:00 +00:00
|
|
|
privconn->drivername = conn->driver->name;
|
|
|
|
|
2015-05-13 14:23:00 +00:00
|
|
|
if (prlsdkInit()) {
|
2014-09-11 16:24:03 +00:00
|
|
|
VIR_DEBUG("%s", _("Can't initialize Parallels SDK"));
|
|
|
|
goto err_free;
|
2012-07-31 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
2014-09-11 16:24:03 +00:00
|
|
|
if (prlsdkConnect(privconn) < 0)
|
|
|
|
goto err_free;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(privconn->caps = vzBuildCapabilities()))
|
2012-07-31 18:56:05 +00:00
|
|
|
goto error;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(privconn->xmlopt = virDomainXMLOptionNew(&vzDomainDefParserConfig,
|
2015-06-25 07:56:56 +00:00
|
|
|
NULL, NULL)))
|
2013-03-05 15:17:24 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-01-11 16:04:47 +00:00
|
|
|
if (!(privconn->domains = virDomainObjListNew()))
|
2012-07-31 18:56:05 +00:00
|
|
|
goto error;
|
|
|
|
|
2014-12-01 15:38:50 +00:00
|
|
|
if (!(privconn->domainEventState = virObjectEventStateNew()))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (prlsdkSubscribeToPCSEvents(privconn))
|
|
|
|
goto error;
|
|
|
|
|
2012-07-31 18:56:05 +00:00
|
|
|
conn->privateData = privconn;
|
|
|
|
|
2014-12-01 15:38:48 +00:00
|
|
|
if (prlsdkLoadDomains(privconn))
|
2012-07-31 18:56:07 +00:00
|
|
|
goto error;
|
|
|
|
|
2012-07-31 18:56:05 +00:00
|
|
|
return VIR_DRV_OPEN_SUCCESS;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
error:
|
2013-01-11 13:54:15 +00:00
|
|
|
virObjectUnref(privconn->domains);
|
2013-02-01 12:26:18 +00:00
|
|
|
virObjectUnref(privconn->caps);
|
2014-12-01 15:38:50 +00:00
|
|
|
virObjectEventStateFree(privconn->domainEventState);
|
2014-09-11 16:24:03 +00:00
|
|
|
prlsdkDisconnect(privconn);
|
|
|
|
prlsdkDeinit();
|
|
|
|
err_free:
|
2012-07-31 18:56:05 +00:00
|
|
|
VIR_FREE(privconn);
|
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDrvOpenStatus
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectOpen(virConnectPtr conn,
|
2015-06-25 07:56:56 +00:00
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
|
|
|
unsigned int flags)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
|
|
|
|
|
|
|
|
if (!conn->uri)
|
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
|
2015-05-26 17:12:00 +00:00
|
|
|
if (!conn->uri->scheme)
|
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
|
|
|
|
if (STRNEQ(conn->uri->scheme, "vz") &&
|
|
|
|
STRNEQ(conn->uri->scheme, "parallels"))
|
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
|
|
|
|
if (STREQ(conn->uri->scheme, "vz") && STRNEQ(conn->driver->name, "vz"))
|
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
|
|
|
|
if (STREQ(conn->uri->scheme, "parallels") && STRNEQ(conn->driver->name, "Parallels"))
|
2012-07-31 18:56:05 +00:00
|
|
|
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. */
|
2015-10-20 16:15:12 +00:00
|
|
|
if (STRNEQ_NULLABLE(conn->uri->path, "/system")) {
|
2012-08-13 15:50:13 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2015-05-26 17:12:00 +00:00
|
|
|
_("Unexpected Virtuozzo URI path '%s', try vz:///system"),
|
2012-08-13 15:50:13 +00:00
|
|
|
conn->uri->path);
|
2012-07-31 18:56:05 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
|
|
|
|
2015-09-22 10:33:00 +00:00
|
|
|
if ((ret = vzOpenDefault(conn)) != VIR_DRV_OPEN_SUCCESS) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectClose(conn);
|
2012-07-31 18:56:05 +00:00
|
|
|
return ret;
|
2015-02-26 16:13:53 +00:00
|
|
|
}
|
2012-07-31 18:56:05 +00:00
|
|
|
|
|
|
|
return VIR_DRV_OPEN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectClose(virConnectPtr conn)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2015-02-26 16:13:53 +00:00
|
|
|
if (!privconn)
|
|
|
|
return 0;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2014-12-01 15:38:50 +00:00
|
|
|
prlsdkUnsubscribeFromPCSEvents(privconn);
|
2013-02-01 12:26:18 +00:00
|
|
|
virObjectUnref(privconn->caps);
|
2013-03-31 18:03:42 +00:00
|
|
|
virObjectUnref(privconn->xmlopt);
|
2013-01-11 13:54:15 +00:00
|
|
|
virObjectUnref(privconn->domains);
|
2014-12-01 15:38:50 +00:00
|
|
|
virObjectEventStateFree(privconn->domainEventState);
|
2014-09-11 16:24:03 +00:00
|
|
|
prlsdkDisconnect(privconn);
|
2012-07-31 18:56:05 +00:00
|
|
|
conn->privateData = NULL;
|
2014-09-11 16:24:03 +00:00
|
|
|
prlsdkDeinit();
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2012-07-31 18:56:05 +00:00
|
|
|
virMutexDestroy(&privconn->lock);
|
|
|
|
|
|
|
|
VIR_FREE(privconn);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *hvVer)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
2012-07-31 18:56:07 +00:00
|
|
|
char *output, *sVer, *tmp;
|
|
|
|
const char *searchStr = "prlsrvctl version ";
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
output = vzGetOutput(PRLSRVCTL, "--help", NULL);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
if (!output) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(sVer = strstr(output, searchStr))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
sVer = sVer + strlen(searchStr);
|
|
|
|
|
|
|
|
/* parallels server has versions number like 6.0.17977.782218,
|
|
|
|
* so libvirt can handle only first two numbers. */
|
|
|
|
if (!(tmp = strchr(sVer, '.'))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(tmp = strchr(tmp + 1, '.'))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp[0] = '\0';
|
|
|
|
if (virParseVersionString(sVer, hvVer, true) < 0) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-07-31 18:56:07 +00:00
|
|
|
VIR_FREE(output);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-04-26 16:39:11 +00:00
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static char *vzConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
2013-04-26 16:39:11 +00:00
|
|
|
{
|
|
|
|
return virGetHostname();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-31 18:56:07 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectListDomains(virConnectPtr conn, int *ids, int maxids)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-07-31 18:56:07 +00:00
|
|
|
int n;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2013-06-24 16:49:47 +00:00
|
|
|
n = virDomainObjListGetActiveIDs(privconn->domains, ids, maxids,
|
|
|
|
NULL, NULL);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectNumOfDomains(virConnectPtr conn)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-07-31 18:56:07 +00:00
|
|
|
int count;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2013-06-24 16:49:47 +00:00
|
|
|
count = virDomainObjListNumOfDomains(privconn->domains, true,
|
|
|
|
NULL, NULL);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectListDefinedDomains(virConnectPtr conn, char **const names, int maxnames)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-07-31 18:56:07 +00:00
|
|
|
int n;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2012-07-31 18:56:07 +00:00
|
|
|
memset(names, 0, sizeof(*names) * maxnames);
|
2013-01-11 16:04:47 +00:00
|
|
|
n = virDomainObjListGetInactiveNames(privconn->domains, names,
|
2013-06-24 16:49:47 +00:00
|
|
|
maxnames, NULL, NULL);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectNumOfDefinedDomains(virConnectPtr conn)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-07-31 18:56:07 +00:00
|
|
|
int count;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2013-06-24 16:49:47 +00:00
|
|
|
count = virDomainObjListNumOfDomains(privconn->domains, false,
|
|
|
|
NULL, NULL);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectListAllDomains(virConnectPtr conn,
|
2015-06-25 07:56:56 +00:00
|
|
|
virDomainPtr **domains,
|
|
|
|
unsigned int flags)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-07-31 18:56:07 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
2012-08-03 15:48:05 +00:00
|
|
|
virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2013-06-24 16:49:47 +00:00
|
|
|
ret = virDomainObjListExport(privconn->domains, conn, domains,
|
|
|
|
NULL, flags);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainPtr
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainLookupByID(virConnectPtr conn, int id)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-07-31 18:56:07 +00:00
|
|
|
virDomainPtr ret = NULL;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2013-01-11 16:04:47 +00:00
|
|
|
dom = virDomainObjListFindByID(privconn->domains, id);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
if (dom == NULL) {
|
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, NULL);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
|
|
|
|
if (ret)
|
|
|
|
ret->id = dom->def->id;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-07-31 18:56:07 +00:00
|
|
|
if (dom)
|
2013-01-09 21:00:32 +00:00
|
|
|
virObjectUnlock(dom);
|
2012-07-31 18:56:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainPtr
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-07-31 18:56:07 +00:00
|
|
|
virDomainPtr ret = NULL;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2013-01-11 16:04:47 +00:00
|
|
|
dom = virDomainObjListFindByUUID(privconn->domains, uuid);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
if (dom == NULL) {
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virUUIDFormat(uuid, uuidstr);
|
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching uuid '%s'"), uuidstr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
|
|
|
|
if (ret)
|
|
|
|
ret->id = dom->def->id;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-07-31 18:56:07 +00:00
|
|
|
if (dom)
|
2013-01-09 21:00:32 +00:00
|
|
|
virObjectUnlock(dom);
|
2012-07-31 18:56:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainPtr
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainLookupByName(virConnectPtr conn, const char *name)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-07-31 18:56:07 +00:00
|
|
|
virDomainPtr ret = NULL;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2013-01-11 16:04:47 +00:00
|
|
|
dom = virDomainObjListFindByName(privconn->domains, name);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
if (dom == NULL) {
|
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching name '%s'"), name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
|
|
|
|
if (ret)
|
|
|
|
ret->id = dom->def->id;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2015-04-23 16:00:01 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2012-07-31 18:56:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr privdom;
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-10-28 14:29:00 +00:00
|
|
|
if (!(privdom = vzDomObjFromDomainRef(domain)))
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
info->state = virDomainObjGetState(privdom, NULL);
|
|
|
|
info->memory = privdom->def->mem.cur_balloon;
|
2015-02-17 17:01:09 +00:00
|
|
|
info->maxMem = virDomainDefGetMemoryActual(privdom->def);
|
2015-10-22 12:59:03 +00:00
|
|
|
info->nrVirtCpu = virDomainDefGetVcpus(privdom->def);
|
2012-07-31 18:56:07 +00:00
|
|
|
info->cpuTime = 0;
|
2015-10-28 14:29:00 +00:00
|
|
|
|
|
|
|
if (virDomainObjIsActive(privdom)) {
|
|
|
|
unsigned long long vtime;
|
|
|
|
size_t i;
|
|
|
|
|
2015-10-22 12:59:03 +00:00
|
|
|
for (i = 0; i < virDomainDefGetVcpus(privdom->def); ++i) {
|
2015-10-28 14:29:00 +00:00
|
|
|
if (prlsdkGetVcpuStats(privdom, i, &vtime) < 0) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("cannot read cputime for domain"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
info->cpuTime += vtime;
|
|
|
|
}
|
|
|
|
}
|
2012-07-31 18:56:07 +00:00
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2015-10-28 14:29:00 +00:00
|
|
|
virDomainObjEndAPI(&privdom);
|
2012-07-31 18:56:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainGetOSType(virDomainPtr domain)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr privdom;
|
|
|
|
|
|
|
|
char *ret = NULL;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(privdom = vzDomObjFromDomain(domain)))
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2015-04-17 00:11:06 +00:00
|
|
|
ignore_value(VIR_STRDUP(ret, virDomainOSTypeToString(privdom->def->os.type)));
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-07-31 18:56:07 +00:00
|
|
|
if (privdom)
|
2013-01-09 21:00:32 +00:00
|
|
|
virObjectUnlock(privdom);
|
2012-07-31 18:56:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainIsPersistent(virDomainPtr domain)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr privdom;
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(privdom = vzDomObjFromDomain(domain)))
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 1;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-07-31 18:56:07 +00:00
|
|
|
if (privdom)
|
2013-01-09 21:00:32 +00:00
|
|
|
virObjectUnlock(privdom);
|
2012-07-31 18:56:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainGetState(virDomainPtr domain,
|
2015-06-25 07:56:56 +00:00
|
|
|
int *state, int *reason, unsigned int flags)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr privdom;
|
|
|
|
int ret = -1;
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(privdom = vzDomObjFromDomain(domain)))
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
*state = virDomainObjGetState(privdom, reason);
|
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-07-31 18:56:07 +00:00
|
|
|
if (privdom)
|
2013-01-09 21:00:32 +00:00
|
|
|
virObjectUnlock(privdom);
|
2012-07-31 18:56:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
|
|
|
virDomainDefPtr def;
|
|
|
|
virDomainObjPtr privdom;
|
|
|
|
char *ret = NULL;
|
|
|
|
|
|
|
|
/* Flags checked by virDomainDefFormat */
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(privdom = vzDomObjFromDomain(domain)))
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
def = (flags & VIR_DOMAIN_XML_INACTIVE) &&
|
|
|
|
privdom->newDef ? privdom->newDef : privdom->def;
|
|
|
|
|
|
|
|
ret = virDomainDefFormat(def, flags);
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-07-31 18:56:07 +00:00
|
|
|
if (privdom)
|
2013-01-09 21:00:32 +00:00
|
|
|
virObjectUnlock(privdom);
|
2012-07-31 18:56:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainGetAutostart(virDomainPtr domain, int *autostart)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr privdom;
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(privdom = vzDomObjFromDomain(domain)))
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
*autostart = privdom->autostart;
|
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-07-31 18:56:07 +00:00
|
|
|
if (privdom)
|
2013-01-09 21:00:32 +00:00
|
|
|
virObjectUnlock(privdom);
|
2012-07-31 18:56:07 +00:00
|
|
|
return ret;
|
2012-07-31 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
2012-07-31 18:56:11 +00:00
|
|
|
static virDomainPtr
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
|
2012-07-31 18:56:11 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2014-12-01 15:38:54 +00:00
|
|
|
virDomainPtr retdom = NULL;
|
2012-07-31 18:56:11 +00:00
|
|
|
virDomainDefPtr def;
|
2014-04-23 14:35:02 +00:00
|
|
|
virDomainObjPtr olddom = NULL;
|
2014-11-18 17:34:42 +00:00
|
|
|
unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
|
2012-07-31 18:56:11 +00:00
|
|
|
|
2014-11-18 17:34:42 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL);
|
|
|
|
|
|
|
|
if (flags & VIR_DOMAIN_DEFINE_VALIDATE)
|
|
|
|
parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE;
|
2014-11-18 14:19:38 +00:00
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverLock(privconn);
|
2013-03-28 13:55:55 +00:00
|
|
|
if ((def = virDomainDefParseString(xml, privconn->caps, privconn->xmlopt,
|
2014-11-18 17:34:42 +00:00
|
|
|
parse_flags)) == NULL)
|
2012-07-31 18:56:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
Merge virDomainObjListIsDuplicate into virDomainObjListAdd
The duplicate VM checking should be done atomically with
virDomainObjListAdd, so shoud not be a separate function.
Instead just use flags to indicate what kind of checks are
required.
This pair, used in virDomainCreateXML:
if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, false)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
NULL)))
goto cleanup;
This pair, used in virDomainRestoreFlags:
if (virDomainObjListIsDuplicate(privconn->domains, def, 1) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, true)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
NULL)))
goto cleanup;
This pair, used in virDomainDefineXML:
if (virDomainObjListIsDuplicate(privconn->domains, def, 0) < 0)
goto cleanup;
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def, false)))
goto cleanup;
Changes to
if (!(dom = virDomainObjListAdd(privconn->domains,
privconn->caps,
def,
0, NULL)))
goto cleanup;
2013-01-14 14:46:58 +00:00
|
|
|
olddom = virDomainObjListFindByUUID(privconn->domains, def->uuid);
|
|
|
|
if (olddom == NULL) {
|
|
|
|
virResetLastError();
|
2015-04-17 00:11:06 +00:00
|
|
|
if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) {
|
2014-12-01 15:38:53 +00:00
|
|
|
if (prlsdkCreateVm(conn, def))
|
2012-09-12 12:40:54 +00:00
|
|
|
goto cleanup;
|
2015-04-17 00:11:06 +00:00
|
|
|
} else if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) {
|
2014-12-01 15:38:53 +00:00
|
|
|
if (prlsdkCreateCt(conn, def))
|
2012-09-12 12:40:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
2015-04-17 00:11:06 +00:00
|
|
|
_("Unsupported OS type: %s"),
|
|
|
|
virDomainOSTypeToString(def->os.type));
|
2012-07-31 18:56:11 +00:00
|
|
|
goto cleanup;
|
2012-09-12 12:40:54 +00:00
|
|
|
}
|
2014-12-01 15:38:54 +00:00
|
|
|
|
|
|
|
olddom = prlsdkAddDomain(privconn, def->uuid);
|
|
|
|
if (!olddom)
|
2012-07-31 18:56:13 +00:00
|
|
|
goto cleanup;
|
2014-12-01 15:38:54 +00:00
|
|
|
} else {
|
2015-04-07 20:35:13 +00:00
|
|
|
int state, reason;
|
|
|
|
|
|
|
|
state = virDomainObjGetState(olddom, &reason);
|
|
|
|
|
|
|
|
if (state == VIR_DOMAIN_SHUTOFF &&
|
|
|
|
reason == VIR_DOMAIN_SHUTOFF_SAVED) {
|
|
|
|
|
|
|
|
/* PCS doesn't store domain config in managed save state file.
|
|
|
|
* It's forbidden to change config for VMs in this state.
|
|
|
|
* It's possible to change config for containers, but after
|
|
|
|
* restoring domain will have that new config, not a config,
|
|
|
|
* which domain had at the moment of virDomainManagedSave.
|
|
|
|
*
|
|
|
|
* So forbid this operation, if config is changed. If it's
|
|
|
|
* not changed - just do nothing. */
|
|
|
|
|
|
|
|
if (!virDomainDefCheckABIStability(olddom->def, def)) {
|
|
|
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
|
|
|
_("Can't change domain configuration "
|
|
|
|
"in managed save state"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (prlsdkApplyConfig(conn, olddom, def))
|
|
|
|
goto cleanup;
|
2012-07-31 18:56:11 +00:00
|
|
|
|
2015-04-07 20:35:13 +00:00
|
|
|
if (prlsdkUpdateDomain(privconn, olddom))
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-12-04 13:43:12 +00:00
|
|
|
}
|
|
|
|
|
2014-12-01 15:38:54 +00:00
|
|
|
retdom = virGetDomain(conn, def->name, def->uuid);
|
|
|
|
if (retdom)
|
|
|
|
retdom->id = def->id;
|
2012-07-31 18:56:11 +00:00
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2014-12-01 15:38:54 +00:00
|
|
|
if (olddom)
|
|
|
|
virObjectUnlock(olddom);
|
2012-07-31 18:56:11 +00:00
|
|
|
virDomainDefFree(def);
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDriverUnlock(privconn);
|
2014-12-01 15:38:54 +00:00
|
|
|
return retdom;
|
2012-07-31 18:56:11 +00:00
|
|
|
}
|
|
|
|
|
2014-11-18 14:19:38 +00:00
|
|
|
static virDomainPtr
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainDefineXML(virConnectPtr conn, const char *xml)
|
2014-11-18 14:19:38 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
return vzDomainDefineXMLFlags(conn, xml, 0);
|
2014-11-18 14:19:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-26 17:21:58 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzNodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED,
|
2015-06-25 07:56:56 +00:00
|
|
|
virNodeInfoPtr nodeinfo)
|
2013-04-26 17:21:58 +00:00
|
|
|
{
|
2015-07-07 11:27:53 +00:00
|
|
|
return nodeGetInfo(NULL, nodeinfo);
|
2013-04-26 17:21:58 +00:00
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
|
2014-04-23 14:35:03 +00:00
|
|
|
{
|
|
|
|
/* Encryption is not relevant / applicable to way we talk to PCS */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
|
2014-04-23 14:35:03 +00:00
|
|
|
{
|
|
|
|
/* We run CLI tools directly so this is secure */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
|
2014-04-23 14:35:03 +00:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-26 17:21:58 +00:00
|
|
|
|
2014-06-05 05:50:05 +00:00
|
|
|
static char *
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
|
2015-06-25 07:56:56 +00:00
|
|
|
const char **xmlCPUs,
|
|
|
|
unsigned int ncpus,
|
|
|
|
unsigned int flags)
|
2014-06-05 05:50:05 +00:00
|
|
|
{
|
|
|
|
virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, NULL);
|
|
|
|
|
|
|
|
return cpuBaselineXML(xmlCPUs, ncpus, NULL, 0, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-05 05:50:04 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainGetVcpus(virDomainPtr domain,
|
2015-06-25 07:56:56 +00:00
|
|
|
virVcpuInfoPtr info,
|
|
|
|
int maxinfo,
|
|
|
|
unsigned char *cpumaps,
|
|
|
|
int maplen)
|
2014-06-05 05:50:04 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr privdom = NULL;
|
|
|
|
size_t i;
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-06-26 11:24:00 +00:00
|
|
|
if (!(privdom = vzDomObjFromDomainRef(domain)))
|
2014-06-05 05:50:04 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!virDomainObjIsActive(privdom)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
"%s",
|
|
|
|
_("cannot list vcpu pinning for an inactive domain"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (maxinfo >= 1) {
|
|
|
|
if (info != NULL) {
|
|
|
|
memset(info, 0, sizeof(*info) * maxinfo);
|
|
|
|
for (i = 0; i < maxinfo; i++) {
|
|
|
|
info[i].number = i;
|
|
|
|
info[i].state = VIR_VCPU_RUNNING;
|
2015-06-26 11:24:00 +00:00
|
|
|
if (prlsdkGetVcpuStats(privdom, i, &info[i].cpuTime) < 0)
|
|
|
|
goto cleanup;
|
2014-06-05 05:50:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (cpumaps != NULL) {
|
|
|
|
memset(cpumaps, 0, maplen * maxinfo);
|
2015-07-02 14:26:59 +00:00
|
|
|
for (i = 0; i < maxinfo; i++)
|
|
|
|
virBitmapToDataBuf(privdom->def->cpumask,
|
|
|
|
VIR_GET_CPUMAP(cpumaps, maplen, i),
|
|
|
|
maplen);
|
2014-06-05 05:50:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ret = maxinfo;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (privdom)
|
2015-06-26 11:24:00 +00:00
|
|
|
virDomainObjEndAPI(&privdom);
|
2014-06-05 05:50:04 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-22 11:04:43 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzNodeGetCPUMap(virConnectPtr conn ATTRIBUTE_UNUSED,
|
2015-06-25 07:56:56 +00:00
|
|
|
unsigned char **cpumap,
|
|
|
|
unsigned int *online,
|
|
|
|
unsigned int flags)
|
2014-08-22 11:04:43 +00:00
|
|
|
{
|
2015-07-06 21:49:04 +00:00
|
|
|
return nodeGetCPUMap(NULL, cpumap, online, flags);
|
2014-08-22 11:04:43 +00:00
|
|
|
}
|
|
|
|
|
2014-12-01 15:38:50 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectDomainEventRegisterAny(virConnectPtr conn,
|
2015-06-25 07:56:56 +00:00
|
|
|
virDomainPtr domain,
|
|
|
|
int eventID,
|
|
|
|
virConnectDomainEventGenericCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
2014-12-01 15:38:50 +00:00
|
|
|
{
|
|
|
|
int ret = -1;
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2014-12-01 15:38:50 +00:00
|
|
|
if (virDomainEventStateRegisterID(conn,
|
|
|
|
privconn->domainEventState,
|
|
|
|
domain, eventID,
|
|
|
|
callback, opaque, freecb, &ret) < 0)
|
|
|
|
ret = -1;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectDomainEventDeregisterAny(virConnectPtr conn,
|
2015-06-25 07:56:56 +00:00
|
|
|
int callbackID)
|
2014-12-01 15:38:50 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2014-12-01 15:38:50 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (virObjectEventStateDeregisterID(conn,
|
|
|
|
privconn->domainEventState,
|
|
|
|
callbackID) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
2014-08-22 11:04:43 +00:00
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzDomainSuspend(virDomainPtr domain)
|
2014-12-01 15:38:51 +00:00
|
|
|
{
|
|
|
|
return prlsdkDomainChangeState(domain, prlsdkPause);
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzDomainResume(virDomainPtr domain)
|
2014-12-01 15:38:51 +00:00
|
|
|
{
|
|
|
|
return prlsdkDomainChangeState(domain, prlsdkResume);
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzDomainCreate(virDomainPtr domain)
|
2014-12-01 15:38:51 +00:00
|
|
|
{
|
|
|
|
return prlsdkDomainChangeState(domain, prlsdkStart);
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzDomainDestroy(virDomainPtr domain)
|
2014-12-01 15:38:51 +00:00
|
|
|
{
|
|
|
|
return prlsdkDomainChangeState(domain, prlsdkKill);
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzDomainShutdown(virDomainPtr domain)
|
2014-12-01 15:38:51 +00:00
|
|
|
{
|
|
|
|
return prlsdkDomainChangeState(domain, prlsdkStop);
|
|
|
|
}
|
|
|
|
|
2015-11-19 12:16:48 +00:00
|
|
|
static int vzDomainReboot(virDomainPtr domain,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
return prlsdkDomainChangeState(domain, prlsdkRestart);
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzDomainIsActive(virDomainPtr domain)
|
2014-12-01 15:38:55 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2014-12-01 15:38:55 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
ret = virDomainObjIsActive(dom);
|
|
|
|
virObjectUnlock(dom);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-12-01 15:38:56 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
|
2014-12-01 15:38:56 +00:00
|
|
|
{
|
|
|
|
/* we don't support any create flags */
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
return vzDomainCreate(domain);
|
2014-12-01 15:38:56 +00:00
|
|
|
}
|
|
|
|
|
2014-12-01 15:38:58 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainUndefineFlags(virDomainPtr domain,
|
2015-06-25 07:56:56 +00:00
|
|
|
unsigned int flags)
|
2014-12-01 15:38:58 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
2014-12-01 15:38:58 +00:00
|
|
|
virDomainObjPtr dom = NULL;
|
2015-03-13 15:40:41 +00:00
|
|
|
int ret;
|
2014-12-01 15:38:58 +00:00
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2014-12-01 15:38:58 +00:00
|
|
|
return -1;
|
|
|
|
|
2015-03-13 15:40:41 +00:00
|
|
|
ret = prlsdkUnregisterDomain(privconn, dom);
|
|
|
|
if (ret)
|
2015-06-25 07:56:56 +00:00
|
|
|
virObjectUnlock(dom);
|
2015-03-13 15:40:41 +00:00
|
|
|
|
|
|
|
return ret;
|
2014-12-01 15:38:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainUndefine(virDomainPtr domain)
|
2014-12-01 15:38:58 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
return vzDomainUndefineFlags(domain, 0);
|
2014-12-01 15:38:58 +00:00
|
|
|
}
|
|
|
|
|
2015-01-15 14:02:44 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainHasManagedSaveImage(virDomainPtr domain, unsigned int flags)
|
2015-01-15 14:02:44 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
2015-04-07 20:35:02 +00:00
|
|
|
int state, reason;
|
|
|
|
int ret = 0;
|
2015-01-15 14:02:44 +00:00
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2015-01-15 14:02:44 +00:00
|
|
|
return -1;
|
|
|
|
|
2015-04-07 20:35:02 +00:00
|
|
|
state = virDomainObjGetState(dom, &reason);
|
|
|
|
if (state == VIR_DOMAIN_SHUTOFF && reason == VIR_DOMAIN_SHUTOFF_SAVED)
|
|
|
|
ret = 1;
|
2015-03-10 20:12:20 +00:00
|
|
|
virObjectUnlock(dom);
|
|
|
|
|
2015-04-07 20:35:02 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainManagedSave(virDomainPtr domain, unsigned int flags)
|
2015-04-07 20:35:02 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
2015-04-07 20:35:02 +00:00
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int state, reason;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_SAVE_RUNNING |
|
|
|
|
VIR_DOMAIN_SAVE_PAUSED, -1);
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2015-04-07 20:35:02 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
state = virDomainObjGetState(dom, &reason);
|
|
|
|
|
|
|
|
if (state == VIR_DOMAIN_RUNNING && (flags & VIR_DOMAIN_SAVE_PAUSED)) {
|
|
|
|
ret = prlsdkDomainChangeStateLocked(privconn, dom, prlsdkPause);
|
|
|
|
if (ret)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = prlsdkDomainChangeStateLocked(privconn, dom, prlsdkSuspend);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virObjectUnlock(dom);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainManagedSaveRemove(virDomainPtr domain, unsigned int flags)
|
2015-04-07 20:35:02 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int state, reason;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2015-04-07 20:35:02 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
state = virDomainObjGetState(dom, &reason);
|
|
|
|
|
|
|
|
if (!(state == VIR_DOMAIN_SHUTOFF && reason == VIR_DOMAIN_SHUTOFF_SAVED))
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-05-13 14:23:00 +00:00
|
|
|
ret = prlsdkDomainManagedSaveRemove(dom);
|
2015-04-07 20:35:02 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virObjectUnlock(dom);
|
|
|
|
return ret;
|
2015-01-15 14:02:44 +00:00
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzDomainAttachDeviceFlags(virDomainPtr dom, const char *xml,
|
2015-06-25 07:56:56 +00:00
|
|
|
unsigned int flags)
|
2015-04-13 14:55:27 +00:00
|
|
|
{
|
|
|
|
int ret = -1;
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = dom->conn->privateData;
|
2015-04-13 14:55:27 +00:00
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
|
|
|
virDomainObjPtr privdom = NULL;
|
|
|
|
bool domactive = false;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(privdom = vzDomObjFromDomain(dom)))
|
2015-04-22 15:25:50 +00:00
|
|
|
return -1;
|
2015-04-13 14:55:27 +00:00
|
|
|
|
|
|
|
if (!(flags & VIR_DOMAIN_AFFECT_CONFIG)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("device attach needs VIR_DOMAIN_AFFECT_CONFIG "
|
|
|
|
"flag to be set"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
domactive = virDomainObjIsActive(privdom);
|
|
|
|
if (!domactive && (flags & VIR_DOMAIN_AFFECT_LIVE)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("cannot do live update a device on "
|
|
|
|
"inactive domain"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (domactive && !(flags & VIR_DOMAIN_AFFECT_LIVE)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("Updates on a running domain need "
|
|
|
|
"VIR_DOMAIN_AFFECT_LIVE flag"));
|
|
|
|
}
|
|
|
|
|
|
|
|
dev = virDomainDeviceDefParse(xml, privdom->def, privconn->caps,
|
|
|
|
privconn->xmlopt, VIR_DOMAIN_XML_INACTIVE);
|
|
|
|
if (dev == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
switch (dev->type) {
|
|
|
|
case VIR_DOMAIN_DEVICE_DISK:
|
2015-05-13 14:23:00 +00:00
|
|
|
ret = prlsdkAttachVolume(privdom, dev->data.disk);
|
2015-04-13 14:55:27 +00:00
|
|
|
if (ret) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("disk attach failed"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
break;
|
2015-06-22 16:57:00 +00:00
|
|
|
case VIR_DOMAIN_DEVICE_NET:
|
|
|
|
ret = prlsdkAttachNet(privdom, privconn, dev->data.net);
|
|
|
|
if (ret) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("network attach failed"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
break;
|
2015-04-13 14:55:27 +00:00
|
|
|
default:
|
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
2015-04-22 15:25:50 +00:00
|
|
|
_("device type '%s' cannot be attached"),
|
2015-04-13 14:55:27 +00:00
|
|
|
virDomainDeviceTypeToString(dev->type));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
2015-04-22 15:25:50 +00:00
|
|
|
virObjectUnlock(privdom);
|
2015-04-13 14:55:27 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzDomainAttachDevice(virDomainPtr dom, const char *xml)
|
2015-04-09 10:42:00 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
return vzDomainAttachDeviceFlags(dom, xml,
|
2015-06-25 07:56:56 +00:00
|
|
|
VIR_DOMAIN_AFFECT_CONFIG | VIR_DOMAIN_AFFECT_LIVE);
|
2015-04-09 10:42:00 +00:00
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
|
2015-06-25 07:56:56 +00:00
|
|
|
unsigned int flags)
|
2015-04-23 18:37:00 +00:00
|
|
|
{
|
|
|
|
int ret = -1;
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = dom->conn->privateData;
|
2015-04-23 18:37:00 +00:00
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
|
|
|
virDomainObjPtr privdom = NULL;
|
|
|
|
bool domactive = false;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
privdom = vzDomObjFromDomain(dom);
|
2015-04-23 18:37:00 +00:00
|
|
|
if (privdom == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!(flags & VIR_DOMAIN_AFFECT_CONFIG)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("device detach needs VIR_DOMAIN_AFFECT_CONFIG "
|
|
|
|
"flag to be set"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
domactive = virDomainObjIsActive(privdom);
|
|
|
|
if (!domactive && (flags & VIR_DOMAIN_AFFECT_LIVE)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("cannot do live update a device on "
|
|
|
|
"inactive domain"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (domactive && !(flags & VIR_DOMAIN_AFFECT_LIVE)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("Updates on a running domain need "
|
|
|
|
"VIR_DOMAIN_AFFECT_LIVE flag"));
|
|
|
|
}
|
|
|
|
|
|
|
|
dev = virDomainDeviceDefParse(xml, privdom->def, privconn->caps,
|
|
|
|
privconn->xmlopt, VIR_DOMAIN_XML_INACTIVE);
|
|
|
|
if (dev == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
switch (dev->type) {
|
|
|
|
case VIR_DOMAIN_DEVICE_DISK:
|
2015-05-13 14:23:00 +00:00
|
|
|
ret = prlsdkDetachVolume(privdom, dev->data.disk);
|
2015-04-23 18:37:00 +00:00
|
|
|
if (ret) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("disk detach failed"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
break;
|
2015-06-22 16:57:00 +00:00
|
|
|
case VIR_DOMAIN_DEVICE_NET:
|
|
|
|
ret = prlsdkDetachNet(privdom, privconn, dev->data.net);
|
|
|
|
if (ret) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("network detach failed"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
break;
|
2015-04-23 18:37:00 +00:00
|
|
|
default:
|
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
|
|
|
_("device type '%s' cannot be detached"),
|
|
|
|
virDomainDeviceTypeToString(dev->type));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
virObjectUnlock(privdom);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzDomainDetachDevice(virDomainPtr dom, const char *xml)
|
2015-04-23 18:37:00 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
return vzDomainDetachDeviceFlags(dom, xml,
|
2015-06-25 07:56:56 +00:00
|
|
|
VIR_DOMAIN_AFFECT_CONFIG | VIR_DOMAIN_AFFECT_LIVE);
|
2015-04-23 18:37:00 +00:00
|
|
|
}
|
|
|
|
|
2015-04-23 13:21:00 +00:00
|
|
|
static unsigned long long
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainGetMaxMemory(virDomainPtr domain)
|
2015-04-23 13:21:00 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2015-04-23 13:21:00 +00:00
|
|
|
return -1;
|
|
|
|
|
2015-09-16 12:00:02 +00:00
|
|
|
ret = virDomainDefGetMemoryActual(dom->def);
|
2015-04-23 13:21:00 +00:00
|
|
|
virObjectUnlock(dom);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-09 07:35:53 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainBlockStats(virDomainPtr domain, const char *path,
|
2015-06-25 07:56:56 +00:00
|
|
|
virDomainBlockStatsPtr stats)
|
2015-06-09 07:35:53 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
size_t i;
|
|
|
|
int idx;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomainRef(domain)))
|
2015-06-09 07:35:53 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (*path) {
|
|
|
|
if ((idx = virDomainDiskIndexByName(dom->def, path, false)) < 0) {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG, _("invalid path: %s"), path);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (prlsdkGetBlockStats(dom, dom->def->disks[idx], stats) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
} else {
|
|
|
|
virDomainBlockStatsStruct s;
|
|
|
|
|
2015-06-25 07:56:56 +00:00
|
|
|
#define PARALLELS_ZERO_STATS(VAR, TYPE, NAME) \
|
2015-06-09 07:35:53 +00:00
|
|
|
stats->VAR = 0;
|
|
|
|
|
|
|
|
PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_ZERO_STATS)
|
|
|
|
|
|
|
|
#undef PARALLELS_ZERO_STATS
|
|
|
|
|
|
|
|
for (i = 0; i < dom->def->ndisks; i++) {
|
|
|
|
if (prlsdkGetBlockStats(dom, dom->def->disks[i], &s) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-06-09 14:04:24 +00:00
|
|
|
#define PARALLELS_SUM_STATS(VAR, TYPE, NAME) \
|
2015-06-25 07:56:56 +00:00
|
|
|
if (s.VAR != -1) \
|
|
|
|
stats->VAR += s.VAR;
|
2015-06-09 07:35:53 +00:00
|
|
|
|
2015-06-25 07:56:56 +00:00
|
|
|
PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_SUM_STATS)
|
2015-06-09 07:35:53 +00:00
|
|
|
|
2015-06-09 14:04:24 +00:00
|
|
|
#undef PARALLELS_SUM_STATS
|
2015-06-09 07:35:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
stats->errs = -1;
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (dom)
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainBlockStatsFlags(virDomainPtr domain,
|
2015-06-25 07:56:56 +00:00
|
|
|
const char *path,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
2015-06-09 07:35:53 +00:00
|
|
|
{
|
|
|
|
virDomainBlockStatsStruct stats;
|
|
|
|
int ret = -1;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
|
|
|
|
/* We don't return strings, and thus trivially support this flag. */
|
|
|
|
flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (vzDomainBlockStats(domain, path, &stats) < 0)
|
2015-06-09 07:35:53 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (*nparams == 0) {
|
|
|
|
#define PARALLELS_COUNT_STATS(VAR, TYPE, NAME) \
|
|
|
|
if ((stats.VAR) != -1) \
|
|
|
|
++*nparams;
|
|
|
|
|
|
|
|
PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_COUNT_STATS)
|
|
|
|
|
|
|
|
#undef PARALLELS_COUNT_STATS
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
#define PARALLELS_BLOCK_STATS_ASSIGN_PARAM(VAR, TYPE, NAME) \
|
|
|
|
if (i < *nparams && (stats.VAR) != -1) { \
|
|
|
|
if (virTypedParameterAssign(params + i, TYPE, \
|
|
|
|
VIR_TYPED_PARAM_LLONG, (stats.VAR)) < 0) \
|
|
|
|
goto cleanup; \
|
|
|
|
i++; \
|
|
|
|
}
|
|
|
|
|
|
|
|
PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_BLOCK_STATS_ASSIGN_PARAM)
|
|
|
|
|
|
|
|
#undef PARALLELS_BLOCK_STATS_ASSIGN_PARAM
|
|
|
|
|
|
|
|
*nparams = i;
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-26 11:24:00 +00:00
|
|
|
static int
|
|
|
|
vzDomainInterfaceStats(virDomainPtr domain,
|
|
|
|
const char *path,
|
|
|
|
virDomainInterfaceStatsPtr stats)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!(dom = vzDomObjFromDomainRef(domain)))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
ret = prlsdkGetNetStats(dom, path, stats);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2015-06-09 07:35:53 +00:00
|
|
|
|
2015-06-26 11:24:00 +00:00
|
|
|
static int
|
|
|
|
vzDomainMemoryStats(virDomainPtr domain,
|
|
|
|
virDomainMemoryStatPtr stats,
|
|
|
|
unsigned int nr_stats,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
if (!(dom = vzDomObjFromDomainRef(domain)))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
ret = prlsdkGetMemoryStats(dom, stats, nr_stats);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-19 19:02:00 +00:00
|
|
|
static int
|
|
|
|
vzDomainGetVcpusFlags(virDomainPtr dom,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr privdom = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_AFFECT_CONFIG |
|
|
|
|
VIR_DOMAIN_VCPU_MAXIMUM, -1);
|
|
|
|
|
|
|
|
if (!(privdom = vzDomObjFromDomain(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (flags & VIR_DOMAIN_VCPU_MAXIMUM)
|
2015-10-19 17:21:24 +00:00
|
|
|
ret = virDomainDefGetVcpusMax(privdom->def);
|
2015-10-19 19:02:00 +00:00
|
|
|
else
|
2015-10-22 12:59:03 +00:00
|
|
|
ret = virDomainDefGetVcpus(privdom->def);
|
2015-10-19 19:02:00 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (privdom)
|
|
|
|
virObjectUnlock(privdom);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vzDomainGetMaxVcpus(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
return vzDomainGetVcpusFlags(dom, (VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_VCPU_MAXIMUM));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vzDomainIsUpdated(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
virDomainObjPtr privdom;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
/* As far as VZ domains are always updated (e.g. current==persistent),
|
|
|
|
* we just check for domain existence */
|
|
|
|
if (!(privdom = vzDomObjFromDomain(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (privdom)
|
|
|
|
virObjectUnlock(privdom);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-19 19:02:00 +00:00
|
|
|
static int vzConnectGetMaxVcpus(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
|
const char *type)
|
|
|
|
{
|
|
|
|
/* As far as we have no limitation for containers
|
|
|
|
* we report maximum */
|
|
|
|
if (type == NULL || STRCASEEQ(type, "vz") || STRCASEEQ(type, "parallels"))
|
|
|
|
return 1028;
|
|
|
|
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("unknown type '%s'"), type);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-10-19 19:02:00 +00:00
|
|
|
static int
|
|
|
|
vzNodeGetCPUStats(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
|
int cpuNum,
|
|
|
|
virNodeCPUStatsPtr params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
return nodeGetCPUStats(cpuNum, params, nparams, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzNodeGetMemoryStats(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
|
int cellNum,
|
|
|
|
virNodeMemoryStatsPtr params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
return nodeGetMemoryStats(NULL, cellNum, params, nparams, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzNodeGetCellsFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
|
unsigned long long *freeMems,
|
|
|
|
int startCell,
|
|
|
|
int maxCells)
|
|
|
|
{
|
|
|
|
return nodeGetCellsFreeMemory(freeMems, startCell, maxCells);
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned long long
|
|
|
|
vzNodeGetFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
unsigned long long freeMem;
|
|
|
|
if (nodeGetMemory(NULL, &freeMem) < 0)
|
|
|
|
return 0;
|
|
|
|
return freeMem;
|
|
|
|
}
|
|
|
|
|
2015-05-26 17:12:00 +00:00
|
|
|
static virHypervisorDriver vzDriver = {
|
|
|
|
.name = "vz",
|
2015-06-10 07:50:00 +00:00
|
|
|
.connectOpen = vzConnectOpen, /* 0.10.0 */
|
|
|
|
.connectClose = vzConnectClose, /* 0.10.0 */
|
|
|
|
.connectGetVersion = vzConnectGetVersion, /* 0.10.0 */
|
|
|
|
.connectGetHostname = vzConnectGetHostname, /* 0.10.0 */
|
2015-10-19 19:02:00 +00:00
|
|
|
.connectGetMaxVcpus = vzConnectGetMaxVcpus, /* 1.2.21 */
|
2015-06-10 07:50:00 +00:00
|
|
|
.nodeGetInfo = vzNodeGetInfo, /* 0.10.0 */
|
2015-10-19 19:02:00 +00:00
|
|
|
.nodeGetCPUStats = vzNodeGetCPUStats, /* 1.2.21 */
|
|
|
|
.nodeGetMemoryStats = vzNodeGetMemoryStats, /* 1.2.21 */
|
|
|
|
.nodeGetCellsFreeMemory = vzNodeGetCellsFreeMemory, /* 1.2.21 */
|
|
|
|
.nodeGetFreeMemory = vzNodeGetFreeMemory, /* 1.2.21 */
|
2015-06-10 07:50:00 +00:00
|
|
|
.connectGetCapabilities = vzConnectGetCapabilities, /* 0.10.0 */
|
|
|
|
.connectBaselineCPU = vzConnectBaselineCPU, /* 1.2.6 */
|
|
|
|
.connectListDomains = vzConnectListDomains, /* 0.10.0 */
|
|
|
|
.connectNumOfDomains = vzConnectNumOfDomains, /* 0.10.0 */
|
|
|
|
.connectListDefinedDomains = vzConnectListDefinedDomains, /* 0.10.0 */
|
|
|
|
.connectNumOfDefinedDomains = vzConnectNumOfDefinedDomains, /* 0.10.0 */
|
|
|
|
.connectListAllDomains = vzConnectListAllDomains, /* 0.10.0 */
|
|
|
|
.domainLookupByID = vzDomainLookupByID, /* 0.10.0 */
|
|
|
|
.domainLookupByUUID = vzDomainLookupByUUID, /* 0.10.0 */
|
|
|
|
.domainLookupByName = vzDomainLookupByName, /* 0.10.0 */
|
|
|
|
.domainGetOSType = vzDomainGetOSType, /* 0.10.0 */
|
|
|
|
.domainGetInfo = vzDomainGetInfo, /* 0.10.0 */
|
|
|
|
.domainGetState = vzDomainGetState, /* 0.10.0 */
|
|
|
|
.domainGetXMLDesc = vzDomainGetXMLDesc, /* 0.10.0 */
|
|
|
|
.domainIsPersistent = vzDomainIsPersistent, /* 0.10.0 */
|
|
|
|
.domainGetAutostart = vzDomainGetAutostart, /* 0.10.0 */
|
|
|
|
.domainGetVcpus = vzDomainGetVcpus, /* 1.2.6 */
|
|
|
|
.domainSuspend = vzDomainSuspend, /* 0.10.0 */
|
|
|
|
.domainResume = vzDomainResume, /* 0.10.0 */
|
|
|
|
.domainDestroy = vzDomainDestroy, /* 0.10.0 */
|
|
|
|
.domainShutdown = vzDomainShutdown, /* 0.10.0 */
|
|
|
|
.domainCreate = vzDomainCreate, /* 0.10.0 */
|
|
|
|
.domainCreateWithFlags = vzDomainCreateWithFlags, /* 1.2.10 */
|
2015-11-24 11:48:50 +00:00
|
|
|
.domainReboot = vzDomainReboot, /* 1.3.0 */
|
2015-06-10 07:50:00 +00:00
|
|
|
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
|
|
|
|
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */
|
|
|
|
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
|
|
|
|
.domainUndefineFlags = vzDomainUndefineFlags, /* 1.2.10 */
|
|
|
|
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
|
|
|
|
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
|
|
|
|
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
|
|
|
|
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
|
|
|
|
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
|
2015-10-19 19:02:00 +00:00
|
|
|
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
|
|
|
|
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
|
|
|
|
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
|
2015-06-10 07:50:00 +00:00
|
|
|
.connectDomainEventRegisterAny = vzConnectDomainEventRegisterAny, /* 1.2.10 */
|
|
|
|
.connectDomainEventDeregisterAny = vzConnectDomainEventDeregisterAny, /* 1.2.10 */
|
|
|
|
.nodeGetCPUMap = vzNodeGetCPUMap, /* 1.2.8 */
|
|
|
|
.connectIsEncrypted = vzConnectIsEncrypted, /* 1.2.5 */
|
|
|
|
.connectIsSecure = vzConnectIsSecure, /* 1.2.5 */
|
|
|
|
.connectIsAlive = vzConnectIsAlive, /* 1.2.5 */
|
|
|
|
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
|
|
|
|
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
|
|
|
|
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
|
|
|
|
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
|
2015-06-26 15:26:30 +00:00
|
|
|
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
|
|
|
|
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
|
|
|
|
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */
|
|
|
|
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
|
2012-07-31 18:56:05 +00:00
|
|
|
};
|
|
|
|
|
2015-05-26 17:12:00 +00:00
|
|
|
static virConnectDriver vzConnectDriver = {
|
|
|
|
.hypervisorDriver = &vzDriver,
|
2015-01-20 16:16:26 +00:00
|
|
|
};
|
|
|
|
|
2015-05-26 17:12:00 +00:00
|
|
|
/* Parallels domain type backward compatibility*/
|
|
|
|
static virHypervisorDriver parallelsDriver;
|
|
|
|
static virConnectDriver parallelsConnectDriver;
|
|
|
|
|
2012-07-31 18:56:05 +00:00
|
|
|
/**
|
2015-06-10 07:50:00 +00:00
|
|
|
* vzRegister:
|
2012-07-31 18:56:05 +00:00
|
|
|
*
|
2015-06-10 07:50:00 +00:00
|
|
|
* Registers the vz driver
|
2012-07-31 18:56:05 +00:00
|
|
|
*/
|
|
|
|
int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzRegister(void)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
2015-05-26 17:12:00 +00:00
|
|
|
/* Backward compatibility with Parallels domain type */
|
|
|
|
parallelsDriver = vzDriver;
|
|
|
|
parallelsDriver.name = "Parallels";
|
|
|
|
parallelsConnectDriver = vzConnectDriver;
|
|
|
|
parallelsConnectDriver.hypervisorDriver = ¶llelsDriver;
|
2015-01-20 16:16:26 +00:00
|
|
|
if (virRegisterConnectDriver(¶llelsConnectDriver, false) < 0)
|
2012-12-11 10:59:45 +00:00
|
|
|
return -1;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2015-05-26 17:12:00 +00:00
|
|
|
if (virRegisterConnectDriver(&vzConnectDriver, false) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2012-07-31 18:56:05 +00:00
|
|
|
return 0;
|
|
|
|
}
|