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 <stdarg.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.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"
|
2019-05-23 10:34:08 +00:00
|
|
|
#include "virpidfile.h"
|
2012-12-13 15:25:48 +00:00
|
|
|
#include "virstoragefile.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"
|
2016-06-10 17:21:18 +00:00
|
|
|
#include "virhostmem.h"
|
|
|
|
#include "virhostcpu.h"
|
2016-06-24 14:32:38 +00:00
|
|
|
#include "viraccessapicheck.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"
|
|
|
|
|
2019-08-20 15:05:12 +00:00
|
|
|
#define VZ_STATEDIR RUNSTATEDIR "/libvirt/vz"
|
2019-05-23 10:34:08 +00:00
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
static virClassPtr vzDriverClass;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2019-05-23 10:34:08 +00:00
|
|
|
static bool vz_driver_privileged;
|
|
|
|
/* pid file FD, ensures two copies of the driver can't use the same root */
|
|
|
|
static int vz_driver_lock_fd = -1;
|
2016-03-28 19:11:30 +00:00
|
|
|
static virMutex vz_driver_lock;
|
|
|
|
static vzDriverPtr vz_driver;
|
|
|
|
static vzConnPtr vz_conn_list;
|
|
|
|
|
|
|
|
static vzDriverPtr
|
|
|
|
vzDriverObjNew(void);
|
|
|
|
|
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;
|
|
|
|
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 };
|
2016-03-28 18:08:49 +00:00
|
|
|
const char *const emulators[] = { "vz", "parallels"};
|
2015-07-03 17:26:00 +00:00
|
|
|
virDomainVirtType virt_types[] = {
|
2016-03-28 18:08:49 +00:00
|
|
|
VIR_DOMAIN_VIRT_VZ,
|
|
|
|
VIR_DOMAIN_VIRT_PARALLELS
|
2015-07-03 17:26:00 +00:00
|
|
|
};
|
|
|
|
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
|
|
|
|
2017-03-07 09:40:15 +00:00
|
|
|
if (virCapabilitiesInitNUMA(caps) < 0)
|
2013-07-04 10:13:24 +00:00
|
|
|
goto error;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2017-03-29 13:52:31 +00:00
|
|
|
if (virCapabilitiesInitCaches(caps) < 0)
|
|
|
|
goto error;
|
2017-03-14 13:28:45 +00:00
|
|
|
|
2019-10-15 11:55:26 +00:00
|
|
|
verify(G_N_ELEMENTS(archs) == G_N_ELEMENTS(emulators));
|
2017-03-14 13:28:45 +00:00
|
|
|
|
2019-10-15 11:55:26 +00:00
|
|
|
for (i = 0; i < G_N_ELEMENTS(ostypes); i++)
|
|
|
|
for (j = 0; j < G_N_ELEMENTS(archs); j++)
|
|
|
|
for (k = 0; k < G_N_ELEMENTS(emulators); k++)
|
2015-07-03 17:26:00 +00:00
|
|
|
if (vzCapsAddGuestDomain(caps, ostypes[i], archs[j],
|
|
|
|
emulators[k], virt_types[k]) < 0)
|
|
|
|
goto error;
|
2015-05-26 17:12:00 +00:00
|
|
|
|
2017-03-07 09:40:15 +00:00
|
|
|
if (virCapabilitiesGetNodeInfo(&nodeinfo))
|
2014-06-05 05:50:06 +00:00
|
|
|
goto error;
|
|
|
|
|
2017-03-07 10:38:38 +00:00
|
|
|
if (!(caps->host.cpu = virCPUGetHost(caps->host.arch, VIR_CPU_TYPE_HOST,
|
2017-10-17 13:55:14 +00:00
|
|
|
&nodeinfo, NULL)))
|
2014-06-05 05:50:06 +00:00
|
|
|
goto error;
|
|
|
|
|
2016-05-18 08:11:06 +00:00
|
|
|
if (virCapabilitiesAddHostMigrateTransport(caps, "vzmigr") < 0)
|
|
|
|
goto error;
|
|
|
|
|
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);
|
2017-03-06 20:35:49 +00:00
|
|
|
return NULL;
|
2012-07-31 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
static void vzDriverDispose(void * obj)
|
|
|
|
{
|
|
|
|
vzDriverPtr driver = obj;
|
|
|
|
|
2017-02-03 07:01:55 +00:00
|
|
|
prlsdkDisconnect(driver);
|
2016-03-28 19:11:30 +00:00
|
|
|
virObjectUnref(driver->domains);
|
|
|
|
virObjectUnref(driver->caps);
|
|
|
|
virObjectUnref(driver->xmlopt);
|
2016-10-11 07:48:36 +00:00
|
|
|
virObjectUnref(driver->domainEventState);
|
2016-04-07 18:52:43 +00:00
|
|
|
virSysinfoDefFree(driver->hostsysinfo);
|
2016-03-28 19:11:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int vzDriverOnceInit(void)
|
|
|
|
{
|
2018-04-17 15:42:33 +00:00
|
|
|
if (!VIR_CLASS_NEW(vzDriver, virClassForObjectLockable()))
|
2016-03-28 19:11:30 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2019-01-20 17:23:29 +00:00
|
|
|
VIR_ONCE_GLOBAL_INIT(vzDriver);
|
2016-03-28 19:11:30 +00:00
|
|
|
|
|
|
|
vzDriverPtr
|
|
|
|
vzGetDriverConnection(void)
|
|
|
|
{
|
2019-05-23 10:34:08 +00:00
|
|
|
if (!vz_driver_privileged) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("vz state driver is not active"));
|
|
|
|
return NULL;
|
|
|
|
}
|
2016-03-28 19:11:30 +00:00
|
|
|
virMutexLock(&vz_driver_lock);
|
|
|
|
if (!vz_driver)
|
|
|
|
vz_driver = vzDriverObjNew();
|
|
|
|
virObjectRef(vz_driver);
|
|
|
|
virMutexUnlock(&vz_driver_lock);
|
|
|
|
|
|
|
|
return vz_driver;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
vzDestroyDriverConnection(void)
|
|
|
|
{
|
|
|
|
vzDriverPtr driver;
|
|
|
|
vzConnPtr privconn_list;
|
|
|
|
|
|
|
|
virMutexLock(&vz_driver_lock);
|
2019-10-16 11:45:15 +00:00
|
|
|
driver = g_steal_pointer(&vz_driver);
|
|
|
|
privconn_list = g_steal_pointer(&vz_conn_list);
|
2016-03-28 19:11:30 +00:00
|
|
|
virMutexUnlock(&vz_driver_lock);
|
|
|
|
|
|
|
|
while (privconn_list) {
|
|
|
|
vzConnPtr privconn = privconn_list;
|
|
|
|
privconn_list = privconn->next;
|
|
|
|
virConnectCloseCallbackDataCall(privconn->closeCallback,
|
|
|
|
VIR_CONNECT_CLOSE_REASON_EOF);
|
|
|
|
}
|
|
|
|
virObjectUnref(driver);
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectGetCapabilitiesEnsureACL(conn) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
xml = virCapabilitiesFormatXML(privconn->driver->caps);
|
2012-07-31 18:56:05 +00:00
|
|
|
return xml;
|
|
|
|
}
|
2016-08-18 11:43:09 +00:00
|
|
|
|
2016-04-20 08:58:20 +00:00
|
|
|
static int
|
|
|
|
vzDomainDefAddDefaultInputDevices(virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
if (def->ngraphics == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
int bus = IS_CT(def) ? VIR_DOMAIN_INPUT_BUS_PARALLELS :
|
|
|
|
VIR_DOMAIN_INPUT_BUS_PS2;
|
|
|
|
|
|
|
|
if (virDomainDefMaybeAddInput(def,
|
|
|
|
VIR_DOMAIN_INPUT_TYPE_MOUSE,
|
|
|
|
bus) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (virDomainDefMaybeAddInput(def,
|
|
|
|
VIR_DOMAIN_INPUT_TYPE_KBD,
|
|
|
|
bus) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2014-10-06 15:28:46 +00:00
|
|
|
static int
|
2016-04-20 08:58:20 +00:00
|
|
|
vzDomainDefPostParse(virDomainDefPtr def,
|
2019-10-14 12:45:33 +00:00
|
|
|
virCapsPtr caps G_GNUC_UNUSED,
|
|
|
|
unsigned int parseFlags G_GNUC_UNUSED,
|
|
|
|
void *opaque G_GNUC_UNUSED,
|
|
|
|
void *parseOpaque G_GNUC_UNUSED)
|
2014-10-06 15:28:46 +00:00
|
|
|
{
|
2016-04-20 08:58:20 +00:00
|
|
|
if (vzDomainDefAddDefaultInputDevices(def) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-08-18 11:43:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainDefValidate(const virDomainDef *def,
|
2019-10-14 12:45:33 +00:00
|
|
|
virCapsPtr caps G_GNUC_UNUSED,
|
2016-08-18 11:43:09 +00:00
|
|
|
void *opaque)
|
|
|
|
{
|
2016-03-15 07:47:50 +00:00
|
|
|
if (vzCheckUnsupportedControllers(def, opaque) < 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,
|
2019-10-14 12:45:33 +00:00
|
|
|
virCapsPtr caps G_GNUC_UNUSED,
|
|
|
|
unsigned int parseFlags G_GNUC_UNUSED,
|
|
|
|
void *opaque G_GNUC_UNUSED,
|
|
|
|
void *parseOpaque G_GNUC_UNUSED)
|
2014-10-06 15:28:46 +00:00
|
|
|
{
|
2015-03-18 08:33:55 +00:00
|
|
|
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) &&
|
2019-01-18 00:53:14 +00:00
|
|
|
dev->data.net->model == VIR_DOMAIN_NET_MODEL_UNKNOWN &&
|
|
|
|
def->os.type == VIR_DOMAIN_OSTYPE_HVM)
|
|
|
|
dev->data.net->model = VIR_DOMAIN_NET_MODEL_E1000;
|
2015-03-18 08:33:55 +00:00
|
|
|
|
2016-08-18 11:43:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainDeviceDefValidate(const virDomainDeviceDef *dev,
|
|
|
|
const virDomainDef *def,
|
2019-10-14 12:45:33 +00:00
|
|
|
void *opaque G_GNUC_UNUSED)
|
2016-08-18 11:43:09 +00:00
|
|
|
{
|
2016-04-20 14:05:32 +00:00
|
|
|
if (dev->type == VIR_DOMAIN_DEVICE_DISK)
|
|
|
|
return vzCheckUnsupportedDisk(def, dev->data.disk, opaque);
|
2016-04-20 14:05:42 +00:00
|
|
|
else if (dev->type == VIR_DOMAIN_DEVICE_GRAPHICS)
|
|
|
|
return vzCheckUnsupportedGraphics(dev->data.graphics);
|
2016-04-20 14:05:32 +00:00
|
|
|
|
|
|
|
return 0;
|
2014-10-06 15:28:46 +00:00
|
|
|
}
|
|
|
|
|
2016-06-14 08:45:56 +00:00
|
|
|
static virDomainXMLPrivateDataCallbacks vzDomainXMLPrivateDataCallbacksPtr = {
|
|
|
|
.alloc = vzDomObjAlloc,
|
|
|
|
.free = vzDomObjFree,
|
|
|
|
};
|
2014-10-06 15:28:46 +00:00
|
|
|
|
2016-03-29 07:36:54 +00:00
|
|
|
static virDomainDefParserConfig vzDomainDefParserConfig = {
|
2013-03-15 14:44:12 +00:00
|
|
|
.macPrefix = {0x42, 0x1C, 0x00},
|
2015-06-10 07:50:00 +00:00
|
|
|
.domainPostParseCallback = vzDomainDefPostParse,
|
2016-08-18 11:43:09 +00:00
|
|
|
.devicesPostParseCallback = vzDomainDeviceDefPostParse,
|
|
|
|
.domainValidateCallback = vzDomainDefValidate,
|
|
|
|
.deviceValidateCallback = vzDomainDeviceDefValidate,
|
2013-03-15 14:44:12 +00:00
|
|
|
};
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
static vzDriverPtr
|
|
|
|
vzDriverObjNew(void)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
2016-03-28 19:11:30 +00:00
|
|
|
vzDriverPtr driver;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
if (vzDriverInitialize() < 0)
|
|
|
|
return NULL;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
if (!(driver = virObjectLockableNew(vzDriverClass)))
|
|
|
|
return NULL;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
vzDomainDefParserConfig.priv = &driver->vzCaps;
|
|
|
|
|
|
|
|
if (!(driver->caps = vzBuildCapabilities()) ||
|
|
|
|
!(driver->xmlopt = virDomainXMLOptionNew(&vzDomainDefParserConfig,
|
2016-06-14 08:45:56 +00:00
|
|
|
&vzDomainXMLPrivateDataCallbacksPtr,
|
2017-06-01 22:44:46 +00:00
|
|
|
NULL, NULL, NULL)) ||
|
2016-03-28 19:11:30 +00:00
|
|
|
!(driver->domains = virDomainObjListNew()) ||
|
|
|
|
!(driver->domainEventState = virObjectEventStateNew()) ||
|
|
|
|
(vzInitVersion(driver) < 0) ||
|
2017-02-03 07:01:55 +00:00
|
|
|
(prlsdkConnect(driver) < 0)) {
|
2016-03-28 19:11:30 +00:00
|
|
|
virObjectUnref(driver);
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2016-04-07 18:52:43 +00:00
|
|
|
driver->hostsysinfo = virSysinfoRead();
|
2016-03-28 19:11:30 +00:00
|
|
|
ignore_value(prlsdkLoadDomains(driver));
|
2016-08-03 09:41:53 +00:00
|
|
|
|
|
|
|
/* As far as waitDomainJob finally calls virReportErrorHelper
|
|
|
|
* and we are not going to report it, reset it expicitly*/
|
|
|
|
virResetLastError();
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
return driver;
|
2012-07-31 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static virDrvOpenStatus
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectOpen(virConnectPtr conn,
|
2019-10-14 12:45:33 +00:00
|
|
|
virConnectAuthPtr auth G_GNUC_UNUSED,
|
|
|
|
virConfPtr conf G_GNUC_UNUSED,
|
2015-06-25 07:56:56 +00:00
|
|
|
unsigned int flags)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
2016-03-28 19:11:30 +00:00
|
|
|
vzDriverPtr driver = NULL;
|
|
|
|
vzConnPtr privconn = NULL;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
|
|
|
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
|
|
|
|
|
|
|
|
/* From this point on, the connection is for us. */
|
2018-03-28 13:25:23 +00:00
|
|
|
if (STRNEQ(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;
|
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectOpenEnsureACL(conn) < 0)
|
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
if (!(driver = vzGetDriverConnection()))
|
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(privconn) < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
conn->privateData = privconn;
|
|
|
|
privconn->driver = driver;
|
|
|
|
|
|
|
|
if (!(privconn->closeCallback = virNewConnectCloseCallbackData()))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
virMutexLock(&vz_driver_lock);
|
|
|
|
privconn->next = vz_conn_list;
|
|
|
|
vz_conn_list = privconn;
|
|
|
|
virMutexUnlock(&vz_driver_lock);
|
2012-07-31 18:56:05 +00:00
|
|
|
|
|
|
|
return VIR_DRV_OPEN_SUCCESS;
|
2016-03-28 19:11:30 +00:00
|
|
|
|
|
|
|
error:
|
|
|
|
|
|
|
|
conn->privateData = NULL;
|
|
|
|
virObjectUnref(driver);
|
|
|
|
VIR_FREE(privconn);
|
|
|
|
return VIR_DRV_OPEN_ERROR;
|
2012-07-31 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnectClose(virConnectPtr conn)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
2016-03-28 19:11:30 +00:00
|
|
|
vzConnPtr curr, *prev = &vz_conn_list;
|
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;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
virMutexLock(&vz_driver_lock);
|
|
|
|
for (curr = vz_conn_list; curr; prev = &curr->next, curr = curr->next) {
|
|
|
|
if (curr == privconn) {
|
|
|
|
*prev = curr->next;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
virMutexUnlock(&vz_driver_lock);
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
virObjectUnref(privconn->closeCallback);
|
|
|
|
virObjectUnref(privconn->driver);
|
2012-07-31 18:56:05 +00:00
|
|
|
VIR_FREE(privconn);
|
2016-03-28 19:11:30 +00:00
|
|
|
conn->privateData = NULL;
|
2012-07-31 18:56:05 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2016-03-15 07:47:46 +00:00
|
|
|
vzConnectGetVersion(virConnectPtr conn, unsigned long *hvVer)
|
2012-07-31 18:56:05 +00:00
|
|
|
{
|
2016-03-15 07:47:46 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2016-06-24 14:32:38 +00:00
|
|
|
|
|
|
|
if (virConnectGetVersionEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
*hvVer = privconn->driver->vzVersion;
|
2016-03-15 07:47:46 +00:00
|
|
|
return 0;
|
2012-07-31 18:56:07 +00:00
|
|
|
}
|
|
|
|
|
2013-04-26 16:39:11 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
static char *vzConnectGetHostname(virConnectPtr conn)
|
2013-04-26 16:39:11 +00:00
|
|
|
{
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectGetHostnameEnsureACL(conn) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
2013-04-26 16:39:11 +00:00
|
|
|
return virGetHostname();
|
|
|
|
}
|
|
|
|
|
2016-04-07 18:52:43 +00:00
|
|
|
static char *
|
|
|
|
vzConnectGetSysinfo(virConnectPtr conn, unsigned int flags)
|
|
|
|
{
|
|
|
|
vzConnPtr privconn = conn->privateData;
|
|
|
|
vzDriverPtr driver = privconn->driver;
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
|
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectGetSysinfoEnsureACL(conn) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
2016-04-07 18:52:43 +00:00
|
|
|
if (!driver->hostsysinfo) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("Host SMBIOS information is not available"));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virSysinfoFormat(&buf, driver->hostsysinfo) < 0)
|
|
|
|
return NULL;
|
|
|
|
if (virBufferCheckError(&buf) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return virBufferContentAndReset(&buf);
|
|
|
|
}
|
2013-04-26 16:39:11 +00:00
|
|
|
|
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;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectListDomainsEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
n = virDomainObjListGetActiveIDs(privconn->driver->domains, ids, maxids,
|
2016-06-24 14:32:38 +00:00
|
|
|
virConnectListDomainsCheckACL, conn);
|
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;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectNumOfDomainsEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
count = virDomainObjListNumOfDomains(privconn->driver->domains, true,
|
2016-06-24 14:32:38 +00:00
|
|
|
virConnectNumOfDomainsCheckACL, conn);
|
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;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectListDefinedDomainsEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2012-07-31 18:56:07 +00:00
|
|
|
memset(names, 0, sizeof(*names) * maxnames);
|
2016-03-28 19:11:30 +00:00
|
|
|
n = virDomainObjListGetInactiveNames(privconn->driver->domains, names,
|
2016-06-24 14:32:38 +00:00
|
|
|
maxnames,
|
|
|
|
virConnectListDefinedDomainsCheckACL,
|
|
|
|
conn);
|
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;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectNumOfDefinedDomainsEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
count = virDomainObjListNumOfDomains(privconn->driver->domains, false,
|
2016-06-24 14:32:38 +00:00
|
|
|
virConnectNumOfDefinedDomainsCheckACL,
|
|
|
|
conn);
|
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);
|
2016-06-24 14:32:38 +00:00
|
|
|
|
|
|
|
if (virConnectListAllDomainsEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
ret = virDomainObjListExport(privconn->driver->domains, conn, domains,
|
2016-06-24 14:32:38 +00:00
|
|
|
virConnectListAllDomainsCheckACL, flags);
|
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;
|
2016-06-24 14:32:38 +00:00
|
|
|
virDomainPtr ret = NULL;
|
2012-07-31 18:56:07 +00:00
|
|
|
virDomainObjPtr dom;
|
|
|
|
|
2018-03-09 15:59:28 +00:00
|
|
|
dom = virDomainObjListFindByID(privconn->driver->domains, id);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
if (dom == NULL) {
|
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, NULL);
|
2016-06-14 08:45:52 +00:00
|
|
|
return NULL;
|
2012-07-31 18:56:07 +00:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainLookupByIDEnsureACL(conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2017-03-28 15:08:03 +00:00
|
|
|
ret = virGetDomain(conn, dom->def->name, dom->def->uuid, dom->def->id);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
cleanup:
|
2018-03-09 15:30:47 +00:00
|
|
|
virDomainObjEndAPI(&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;
|
2016-06-24 14:32:38 +00:00
|
|
|
virDomainPtr ret = NULL;
|
2012-07-31 18:56:07 +00:00
|
|
|
virDomainObjPtr dom;
|
|
|
|
|
2018-03-09 15:47:46 +00:00
|
|
|
dom = virDomainObjListFindByUUID(privconn->driver->domains, uuid);
|
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);
|
2016-06-14 08:45:52 +00:00
|
|
|
return NULL;
|
2012-07-31 18:56:07 +00:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainLookupByUUIDEnsureACL(conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2017-03-28 15:08:03 +00:00
|
|
|
ret = virGetDomain(conn, dom->def->name, dom->def->uuid, dom->def->id);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
cleanup:
|
2018-03-09 15:30:47 +00:00
|
|
|
virDomainObjEndAPI(&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;
|
2016-06-24 14:32:38 +00:00
|
|
|
virDomainPtr ret = NULL;
|
2012-07-31 18:56:07 +00:00
|
|
|
virDomainObjPtr dom;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
dom = virDomainObjListFindByName(privconn->driver->domains, name);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
|
|
|
if (dom == NULL) {
|
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching name '%s'"), name);
|
2016-06-14 08:45:52 +00:00
|
|
|
return NULL;
|
2012-07-31 18:56:07 +00:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainLookupByNameEnsureACL(conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2017-03-28 15:08:03 +00:00
|
|
|
ret = virGetDomain(conn, dom->def->name, dom->def->uuid, dom->def->id);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +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
|
|
|
{
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjPtr dom;
|
2016-06-07 16:34:50 +00:00
|
|
|
vzDomObjPtr privdom;
|
2012-07-31 18:56:07 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2012-07-31 18:56:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainGetInfoEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
info->state = virDomainObjGetState(dom, NULL);
|
|
|
|
info->memory = dom->def->mem.cur_balloon;
|
2016-06-15 13:34:04 +00:00
|
|
|
info->maxMem = virDomainDefGetMemoryTotal(dom->def);
|
2016-06-03 07:11:43 +00:00
|
|
|
info->nrVirtCpu = virDomainDefGetVcpus(dom->def);
|
2012-07-31 18:56:07 +00:00
|
|
|
info->cpuTime = 0;
|
2015-10-28 14:29:00 +00:00
|
|
|
|
2016-06-07 16:34:50 +00:00
|
|
|
privdom = dom->privateData;
|
|
|
|
|
|
|
|
if (PRL_INVALID_HANDLE != privdom->stats && virDomainObjIsActive(dom)) {
|
2015-10-28 14:29:00 +00:00
|
|
|
unsigned long long vtime;
|
|
|
|
size_t i;
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
for (i = 0; i < virDomainDefGetVcpus(dom->def); ++i) {
|
2016-06-03 07:11:44 +00:00
|
|
|
if (prlsdkGetVcpuStats(privdom->stats, i, &vtime) < 0) {
|
2015-10-28 14:29:00 +00:00
|
|
|
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:
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
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
|
|
|
{
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjPtr dom;
|
2012-07-31 18:56:07 +00:00
|
|
|
char *ret = NULL;
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-14 08:45:52 +00:00
|
|
|
return NULL;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainGetOSTypeEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
ignore_value(VIR_STRDUP(ret, virDomainOSTypeToString(dom->def->os.type)));
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
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
|
|
|
{
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjPtr dom;
|
2016-06-24 14:32:38 +00:00
|
|
|
int ret = -1;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-14 08:45:52 +00:00
|
|
|
return -1;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainIsPersistentEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 1;
|
|
|
|
|
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-06-24 14:32:38 +00:00
|
|
|
return ret;
|
2012-07-31 18:56:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjPtr dom;
|
2016-06-24 14:32:38 +00:00
|
|
|
int ret = -1;
|
2016-06-14 08:45:52 +00:00
|
|
|
|
2012-07-31 18:56:07 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-14 08:45:52 +00:00
|
|
|
return -1;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainGetStateEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
*state = virDomainObjGetState(dom, reason);
|
2016-06-24 14:32:38 +00:00
|
|
|
ret = 0;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-06-24 14:32:38 +00:00
|
|
|
return ret;
|
2012-07-31 18:56:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
2015-06-10 07:50:00 +00:00
|
|
|
vzDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
|
2012-07-31 18:56:07 +00:00
|
|
|
{
|
2016-02-03 21:40:35 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
2012-07-31 18:56:07 +00:00
|
|
|
virDomainDefPtr def;
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjPtr dom;
|
2012-07-31 18:56:07 +00:00
|
|
|
char *ret = NULL;
|
|
|
|
|
2019-02-14 20:25:01 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS, NULL);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-14 08:45:52 +00:00
|
|
|
return NULL;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainGetXMLDescEnsureACL(domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2012-07-31 18:56:07 +00:00
|
|
|
def = (flags & VIR_DOMAIN_XML_INACTIVE) &&
|
2016-06-03 07:11:43 +00:00
|
|
|
dom->newDef ? dom->newDef : dom->def;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
ret = virDomainDefFormat(def, privconn->driver->caps, flags);
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
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
|
|
|
{
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjPtr dom;
|
2016-06-24 14:32:38 +00:00
|
|
|
int ret = -1;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-14 08:45:52 +00:00
|
|
|
return -1;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainGetAutostartEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
*autostart = dom->autostart;
|
2016-06-24 14:32:38 +00:00
|
|
|
ret = 0;
|
2012-07-31 18:56:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-06-24 14:32:38 +00:00
|
|
|
return ret;
|
2012-07-31 18:56:05 +00:00
|
|
|
}
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
static int
|
|
|
|
vzEnsureDomainExists(virDomainObjPtr dom)
|
|
|
|
{
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
|
|
|
|
if (!dom->removing)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
virUUIDFormat(dom->def->uuid, uuidstr);
|
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching uuid '%s' (%s)"),
|
|
|
|
uuidstr, dom->def->name);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
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;
|
2016-06-14 08:45:59 +00:00
|
|
|
virDomainObjPtr dom = NULL;
|
2014-11-18 17:34:42 +00:00
|
|
|
unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
|
2016-03-28 19:11:30 +00:00
|
|
|
vzDriverPtr driver = privconn->driver;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
bool job = false;
|
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)
|
2016-05-24 15:20:20 +00:00
|
|
|
parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA;
|
2014-11-18 14:19:38 +00:00
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
if ((def = virDomainDefParseString(xml, driver->caps, driver->xmlopt,
|
2016-09-22 15:14:17 +00:00
|
|
|
NULL, parse_flags)) == NULL)
|
2012-07-31 18:56:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-11-11 09:17:37 +00:00
|
|
|
if (virXMLCheckIllegalChars("name", def->name, "\n") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainDefineXMLFlagsEnsureACL(conn, def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2018-03-09 15:47:46 +00:00
|
|
|
dom = virDomainObjListFindByUUID(driver->domains, def->uuid);
|
2016-06-14 08:45:59 +00:00
|
|
|
if (dom == NULL) {
|
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
|
|
|
virResetLastError();
|
2015-04-17 00:11:06 +00:00
|
|
|
if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) {
|
2016-03-28 19:11:30 +00:00
|
|
|
if (prlsdkCreateVm(driver, 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) {
|
2016-07-14 13:52:41 +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
|
|
|
|
2016-06-14 08:45:59 +00:00
|
|
|
if (!(dom = prlsdkAddDomainByUUID(driver, def->uuid)))
|
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;
|
|
|
|
|
2016-06-14 08:45:59 +00:00
|
|
|
state = virDomainObjGetState(dom, &reason);
|
2015-04-07 20:35:13 +00:00
|
|
|
|
|
|
|
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. */
|
|
|
|
|
2017-06-29 10:17:35 +00:00
|
|
|
if (!virDomainDefCheckABIStability(dom->def, def, driver->xmlopt)) {
|
2015-04-07 20:35:13 +00:00
|
|
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
|
|
|
_("Can't change domain configuration "
|
|
|
|
"in managed save state"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else {
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-14 08:45:59 +00:00
|
|
|
if (prlsdkApplyConfig(driver, dom, def))
|
2015-04-07 20:35:13 +00:00
|
|
|
goto cleanup;
|
2012-07-31 18:56:11 +00:00
|
|
|
|
2016-06-14 08:45:59 +00:00
|
|
|
if (prlsdkUpdateDomain(driver, dom))
|
2015-04-07 20:35:13 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-12-04 13:43:12 +00:00
|
|
|
}
|
|
|
|
|
2017-03-28 15:08:03 +00:00
|
|
|
retdom = virGetDomain(conn, def->name, def->uuid, def->id);
|
2012-07-31 18:56:11 +00:00
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
2012-07-31 18:56:11 +00:00
|
|
|
virDomainDefFree(def);
|
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
|
2016-06-24 14:32:38 +00:00
|
|
|
vzNodeGetInfo(virConnectPtr conn,
|
2015-06-25 07:56:56 +00:00
|
|
|
virNodeInfoPtr nodeinfo)
|
2013-04-26 17:21:58 +00:00
|
|
|
{
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virNodeGetInfoEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2017-03-07 09:40:15 +00:00
|
|
|
return virCapabilitiesGetNodeInfo(nodeinfo);
|
2013-04-26 17:21:58 +00:00
|
|
|
}
|
|
|
|
|
2019-10-14 12:45:33 +00:00
|
|
|
static int vzConnectIsEncrypted(virConnectPtr conn G_GNUC_UNUSED)
|
2014-04-23 14:35:03 +00:00
|
|
|
{
|
|
|
|
/* Encryption is not relevant / applicable to way we talk to PCS */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-10-14 12:45:33 +00:00
|
|
|
static int vzConnectIsSecure(virConnectPtr conn G_GNUC_UNUSED)
|
2014-04-23 14:35:03 +00:00
|
|
|
{
|
|
|
|
/* We run CLI tools directly so this is secure */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2019-10-14 12:45:33 +00:00
|
|
|
static int vzConnectIsAlive(virConnectPtr conn G_GNUC_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 *
|
2016-06-24 14:32:38 +00:00
|
|
|
vzConnectBaselineCPU(virConnectPtr conn,
|
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
|
|
|
{
|
2017-09-13 14:27:15 +00:00
|
|
|
virCPUDefPtr *cpus = NULL;
|
|
|
|
virCPUDefPtr cpu = NULL;
|
|
|
|
char *cpustr = NULL;
|
|
|
|
|
2014-06-05 05:50:05 +00:00
|
|
|
virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, NULL);
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectBaselineCPUEnsureACL(conn) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
2017-09-13 14:27:15 +00:00
|
|
|
if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
|
|
|
|
goto cleanup;
|
|
|
|
|
2018-05-15 09:57:35 +00:00
|
|
|
if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL, false)))
|
2017-09-13 14:27:15 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
|
|
|
|
virCPUExpandFeatures(cpus[0]->arch, cpu) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2017-06-30 13:47:23 +00:00
|
|
|
cpustr = virCPUDefFormat(cpu, NULL);
|
2017-09-13 14:27:15 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virCPUDefListFree(cpus);
|
|
|
|
virCPUDefFree(cpu);
|
|
|
|
|
|
|
|
return cpustr;
|
2014-06-05 05:50:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjPtr dom = NULL;
|
2014-06-05 05:50:04 +00:00
|
|
|
size_t i;
|
|
|
|
int ret = -1;
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-14 08:45:52 +00:00
|
|
|
return -1;
|
2014-06-05 05:50:04 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainGetVcpusEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
if (!virDomainObjIsActive(dom)) {
|
2014-06-05 05:50:04 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
"%s",
|
|
|
|
_("cannot list vcpu pinning for an inactive domain"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (maxinfo >= 1) {
|
|
|
|
if (info != NULL) {
|
2016-06-03 07:11:44 +00:00
|
|
|
vzDomObjPtr privdom;
|
|
|
|
|
2014-06-05 05:50:04 +00:00
|
|
|
memset(info, 0, sizeof(*info) * maxinfo);
|
2016-06-03 07:11:44 +00:00
|
|
|
privdom = dom->privateData;
|
|
|
|
|
2014-06-05 05:50:04 +00:00
|
|
|
for (i = 0; i < maxinfo; i++) {
|
|
|
|
info[i].number = i;
|
|
|
|
info[i].state = VIR_VCPU_RUNNING;
|
2016-06-03 07:11:44 +00:00
|
|
|
if (prlsdkGetVcpuStats(privdom->stats, i, &info[i].cpuTime) < 0)
|
2015-06-26 11:24:00 +00:00
|
|
|
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++)
|
2016-06-03 07:11:43 +00:00
|
|
|
virBitmapToDataBuf(dom->def->cpumask,
|
2015-07-02 14:26:59 +00:00
|
|
|
VIR_GET_CPUMAP(cpumaps, maplen, i),
|
|
|
|
maplen);
|
2014-06-05 05:50:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ret = maxinfo;
|
|
|
|
|
|
|
|
cleanup:
|
2016-06-14 08:45:52 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2014-06-05 05:50:04 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-22 11:04:43 +00:00
|
|
|
static int
|
2016-06-24 14:32:38 +00:00
|
|
|
vzNodeGetCPUMap(virConnectPtr conn,
|
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
|
|
|
{
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virNodeGetCPUMapEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-04-13 17:16:16 +00:00
|
|
|
return virHostCPUGetMap(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;
|
2016-06-24 14:32:38 +00:00
|
|
|
|
|
|
|
if (virConnectDomainEventRegisterAnyEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2014-12-01 15:38:50 +00:00
|
|
|
if (virDomainEventStateRegisterID(conn,
|
2016-03-28 19:11:30 +00:00
|
|
|
privconn->driver->domainEventState,
|
2014-12-01 15:38:50 +00:00
|
|
|
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
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2014-12-01 15:38:50 +00:00
|
|
|
if (virObjectEventStateDeregisterID(conn,
|
2016-03-28 19:11:30 +00:00
|
|
|
privconn->driver->domainEventState,
|
2017-06-14 11:32:15 +00:00
|
|
|
callbackID, true) < 0)
|
2016-06-14 08:45:52 +00:00
|
|
|
return -1;
|
2014-12-01 15:38:50 +00:00
|
|
|
|
2016-06-14 08:45:52 +00:00
|
|
|
return 0;
|
2014-12-01 15:38:50 +00:00
|
|
|
}
|
2014-08-22 11:04:43 +00:00
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
static int
|
|
|
|
vzDomainSuspend(virDomainPtr domain)
|
2014-12-01 15:38:51 +00:00
|
|
|
{
|
2016-06-24 14:32:30 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-24 14:32:30 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSuspendEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkPause(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkUpdateDomain(privconn->driver, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
2014-12-01 15:38:51 +00:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
static int
|
|
|
|
vzDomainResume(virDomainPtr domain)
|
2014-12-01 15:38:51 +00:00
|
|
|
{
|
2016-06-24 14:32:30 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-24 14:32:30 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainResumeEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkResume(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkUpdateDomain(privconn->driver, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
2014-12-01 15:38:51 +00:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
static int
|
2016-06-24 14:32:31 +00:00
|
|
|
vzDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
|
2014-12-01 15:38:51 +00:00
|
|
|
{
|
2016-06-24 14:32:30 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
|
|
|
|
2016-06-24 14:32:31 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-24 14:32:30 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainCreateWithFlagsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkStart(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkUpdateDomain(privconn->driver, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
2014-12-01 15:38:51 +00:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
static int
|
2016-06-24 14:32:34 +00:00
|
|
|
vzDomainDestroyFlags(virDomainPtr domain, unsigned int flags)
|
2014-12-01 15:38:51 +00:00
|
|
|
{
|
2016-06-24 14:32:30 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
|
|
|
|
2016-06-24 14:32:34 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-24 14:32:30 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainDestroyFlagsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkKill(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkUpdateDomain(privconn->driver, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
2014-12-01 15:38:51 +00:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
static int
|
2016-06-24 14:32:34 +00:00
|
|
|
vzDomainDestroy(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
return vzDomainDestroyFlags(dom, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
|
2014-12-01 15:38:51 +00:00
|
|
|
{
|
2016-06-24 14:32:30 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
|
|
|
|
2016-06-24 14:32:34 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-24 14:32:30 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainShutdownFlagsEnsureACL(domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkStop(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkUpdateDomain(privconn->driver, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
2014-12-01 15:38:51 +00:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:34 +00:00
|
|
|
static int vzDomainShutdown(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
return vzDomainShutdownFlags(dom, 0);
|
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
static int
|
|
|
|
vzDomainReboot(virDomainPtr domain, unsigned int flags)
|
2015-11-19 12:16:48 +00:00
|
|
|
{
|
2016-06-24 14:32:30 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
|
|
|
|
2015-11-19 12:16:48 +00:00
|
|
|
virCheckFlags(0, -1);
|
2016-06-24 14:32:30 +00:00
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-24 14:32:30 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainRebootEnsureACL(domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkRestart(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkUpdateDomain(privconn->driver, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
2015-11-19 12:16:48 +00:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainIsActiveEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2014-12-01 15:38:55 +00:00
|
|
|
ret = virDomainObjIsActive(dom);
|
2016-06-24 14:32:38 +00:00
|
|
|
|
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2014-12-01 15:38:55 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-12-01 15:38:56 +00:00
|
|
|
static int
|
2016-06-24 14:32:31 +00:00
|
|
|
vzDomainCreate(virDomainPtr domain)
|
2014-12-01 15:38:56 +00:00
|
|
|
{
|
2016-06-24 14:32:31 +00:00
|
|
|
return vzDomainCreateWithFlags(domain, 0);
|
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;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
2014-12-01 15:38:58 +00:00
|
|
|
|
2015-12-22 15:29:40 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE |
|
|
|
|
VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA, -1);
|
2014-12-01 15:38:58 +00:00
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2014-12-01 15:38:58 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainUndefineFlagsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
ret = prlsdkUnregisterDomain(privconn->driver, dom, flags);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&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;
|
2016-06-24 14:32:38 +00:00
|
|
|
int ret = -1;
|
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;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainHasManagedSaveImageEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-04-07 20:35:02 +00:00
|
|
|
state = virDomainObjGetState(dom, &reason);
|
|
|
|
if (state == VIR_DOMAIN_SHUTOFF && reason == VIR_DOMAIN_SHUTOFF_SAVED)
|
|
|
|
ret = 1;
|
2016-06-24 14:32:38 +00:00
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2015-03-10 20:12:20 +00:00
|
|
|
|
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;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
bool job = false;
|
2015-04-07 20:35:02 +00:00
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_SAVE_RUNNING |
|
|
|
|
VIR_DOMAIN_SAVE_PAUSED, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2015-04-07 20:35:02 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainManagedSaveEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-04-07 20:35:02 +00:00
|
|
|
state = virDomainObjGetState(dom, &reason);
|
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
if (state == VIR_DOMAIN_RUNNING && (flags & VIR_DOMAIN_SAVE_PAUSED) &&
|
|
|
|
prlsdkPause(dom) < 0)
|
|
|
|
goto cleanup;
|
2015-04-07 20:35:02 +00:00
|
|
|
|
2016-06-24 14:32:30 +00:00
|
|
|
if (prlsdkSuspend(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkUpdateDomain(privconn->driver, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
2015-04-07 20:35:02 +00:00
|
|
|
|
|
|
|
cleanup:
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
2015-04-07 20:35:02 +00:00
|
|
|
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);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2015-04-07 20:35:02 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainManagedSaveRemoveEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-04-07 20:35:02 +00:00
|
|
|
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:
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2015-04-07 20:35:02 +00:00
|
|
|
return ret;
|
2015-01-15 14:02:44 +00:00
|
|
|
}
|
|
|
|
|
2016-04-08 09:36:44 +00:00
|
|
|
static int vzCheckConfigUpdateFlags(virDomainObjPtr dom, unsigned int *flags)
|
|
|
|
{
|
|
|
|
if (virDomainObjUpdateModificationImpact(dom, flags) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!(*flags & VIR_DOMAIN_AFFECT_CONFIG)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("domain config update needs VIR_DOMAIN_AFFECT_CONFIG "
|
|
|
|
"flag to be set"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virDomainObjIsActive(dom) && !(*flags & VIR_DOMAIN_AFFECT_LIVE)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("Updates on a running domain need "
|
|
|
|
"VIR_DOMAIN_AFFECT_LIVE flag"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
static int vzDomainAttachDeviceFlags(virDomainPtr domain, 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;
|
2016-06-03 07:11:43 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
2015-04-13 14:55:27 +00:00
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjPtr dom = NULL;
|
2016-04-20 14:05:30 +00:00
|
|
|
vzDriverPtr driver = privconn->driver;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
bool job = false;
|
2015-04-13 14:55:27 +00:00
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2015-04-22 15:25:50 +00:00
|
|
|
return -1;
|
2015-04-13 14:55:27 +00:00
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
if (vzCheckConfigUpdateFlags(dom, &flags) < 0)
|
2015-04-13 14:55:27 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainAttachDeviceFlagsEnsureACL(domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-04-20 14:05:30 +00:00
|
|
|
dev = virDomainDeviceDefParse(xml, dom->def, driver->caps,
|
2019-09-18 06:57:08 +00:00
|
|
|
driver->xmlopt, NULL, VIR_DOMAIN_XML_INACTIVE);
|
2015-04-13 14:55:27 +00:00
|
|
|
if (dev == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-04-20 14:05:30 +00:00
|
|
|
if (prlsdkAttachDevice(driver, dom, dev) < 0)
|
|
|
|
goto cleanup;
|
2015-04-13 14:55:27 +00:00
|
|
|
|
2016-08-18 12:37:00 +00:00
|
|
|
if (prlsdkUpdateDomain(driver, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-04-13 14:55:27 +00:00
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
2016-04-20 14:05:34 +00:00
|
|
|
virDomainDeviceDefFree(dev);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
2015-04-13 14:55:27 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
static int vzDomainAttachDevice(virDomainPtr domain, const char *xml)
|
2015-04-09 10:42:00 +00:00
|
|
|
{
|
2016-06-03 07:11:43 +00:00
|
|
|
return vzDomainAttachDeviceFlags(domain, 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
|
|
|
}
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
static int vzDomainDetachDeviceFlags(virDomainPtr domain, 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;
|
2016-06-03 07:11:43 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
2015-04-23 18:37:00 +00:00
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjPtr dom = NULL;
|
2016-04-20 14:05:30 +00:00
|
|
|
vzDriverPtr driver = privconn->driver;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
bool job = false;
|
2015-04-23 18:37:00 +00:00
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
dom = vzDomObjFromDomain(domain);
|
2016-06-03 07:11:43 +00:00
|
|
|
if (dom == NULL)
|
2015-04-23 18:37:00 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
if (vzCheckConfigUpdateFlags(dom, &flags) < 0)
|
2015-04-23 18:37:00 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainDetachDeviceFlagsEnsureACL(domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-04-20 14:05:30 +00:00
|
|
|
dev = virDomainDeviceDefParse(xml, dom->def, driver->caps,
|
2019-09-18 06:57:08 +00:00
|
|
|
driver->xmlopt, NULL,
|
2016-05-27 08:56:56 +00:00
|
|
|
VIR_DOMAIN_XML_INACTIVE |
|
|
|
|
VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE);
|
2015-04-23 18:37:00 +00:00
|
|
|
if (dev == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-04-20 14:05:30 +00:00
|
|
|
if (prlsdkDetachDevice(driver, dom, dev) < 0)
|
|
|
|
goto cleanup;
|
2015-04-23 18:37:00 +00:00
|
|
|
|
2016-08-18 12:37:00 +00:00
|
|
|
if (prlsdkUpdateDomain(driver, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-04-23 18:37:00 +00:00
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
2016-04-20 14:05:34 +00:00
|
|
|
virDomainDeviceDefFree(dev);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
2016-03-28 19:11:30 +00:00
|
|
|
|
2015-04-23 18:37:00 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
static int vzDomainDetachDevice(virDomainPtr domain, const char *xml)
|
2015-04-23 18:37:00 +00:00
|
|
|
{
|
2016-06-03 07:11:43 +00:00
|
|
|
return vzDomainDetachDeviceFlags(domain, 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
|
|
|
}
|
|
|
|
|
2016-05-27 15:16:34 +00:00
|
|
|
static int
|
|
|
|
vzDomainSetUserPassword(virDomainPtr domain,
|
|
|
|
const char *user,
|
|
|
|
const char *password,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int ret = -1;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
bool job = false;
|
2016-05-27 15:16:34 +00:00
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-05-27 15:16:34 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSetUserPasswordEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-27 15:16:34 +00:00
|
|
|
ret = prlsdkDomainSetUserPassword(dom, user, password);
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-27 15:16:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-07-20 15:00:32 +00:00
|
|
|
static int vzDomainUpdateDeviceFlags(virDomainPtr domain,
|
2016-04-20 14:05:31 +00:00
|
|
|
const char *xml,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
2016-07-20 15:00:32 +00:00
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
|
|
|
virDomainObjPtr dom = NULL;
|
2016-04-20 14:05:31 +00:00
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
|
|
|
vzDriverPtr driver = privconn->driver;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
bool job = false;
|
2016-04-20 14:05:31 +00:00
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-04-20 14:05:31 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainUpdateDeviceFlagsEnsureACL(domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-07-20 15:00:32 +00:00
|
|
|
if (vzCheckConfigUpdateFlags(dom, &flags) < 0)
|
2016-04-20 14:05:31 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-07-20 15:00:32 +00:00
|
|
|
if (!(dev = virDomainDeviceDefParse(xml, dom->def, driver->caps,
|
2019-09-18 06:57:08 +00:00
|
|
|
driver->xmlopt, NULL,
|
2016-04-20 14:05:31 +00:00
|
|
|
VIR_DOMAIN_XML_INACTIVE)))
|
|
|
|
goto cleanup;
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-07-20 15:00:32 +00:00
|
|
|
if (prlsdkUpdateDevice(driver, dom, dev) < 0)
|
2016-04-20 14:05:31 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-08-25 08:33:35 +00:00
|
|
|
if (prlsdkUpdateDomain(driver, dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-04-20 14:05:31 +00:00
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
|
|
|
|
virDomainDeviceDefFree(dev);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
2016-04-20 14:05:31 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainGetMaxMemoryEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-15 13:34:04 +00:00
|
|
|
ret = virDomainDefGetMemoryTotal(dom->def);
|
2016-06-24 14:32:38 +00:00
|
|
|
|
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2015-04-23 13:21:00 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-09 07:35:53 +00:00
|
|
|
static int
|
2016-06-24 14:32:32 +00:00
|
|
|
vzDomainBlockStatsImpl(virDomainObjPtr dom,
|
|
|
|
const char *path,
|
|
|
|
virDomainBlockStatsPtr stats)
|
2015-06-09 07:35:53 +00:00
|
|
|
{
|
2016-06-24 14:32:32 +00:00
|
|
|
vzDomObjPtr privdom = dom->privateData;
|
2015-06-09 07:35:53 +00:00
|
|
|
size_t i;
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
if (*path) {
|
|
|
|
if ((idx = virDomainDiskIndexByName(dom->def, path, false)) < 0) {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG, _("invalid path: %s"), path);
|
2016-06-24 14:32:32 +00:00
|
|
|
return -1;
|
2015-06-09 07:35:53 +00:00
|
|
|
}
|
2016-12-05 13:52:56 +00:00
|
|
|
if (prlsdkGetBlockStats(privdom->stats,
|
|
|
|
dom->def->disks[idx],
|
|
|
|
stats,
|
|
|
|
IS_CT(dom->def)) < 0)
|
2016-06-24 14:32:32 +00:00
|
|
|
return -1;
|
2015-06-09 07:35:53 +00:00
|
|
|
} else {
|
|
|
|
virDomainBlockStatsStruct s;
|
|
|
|
|
2017-11-03 12:09:47 +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++) {
|
2016-12-05 13:52:56 +00:00
|
|
|
if (prlsdkGetBlockStats(privdom->stats,
|
|
|
|
dom->def->disks[i],
|
|
|
|
&s,
|
|
|
|
IS_CT(dom->def)) < 0)
|
2016-06-24 14:32:32 +00:00
|
|
|
return -1;
|
2015-06-09 07:35:53 +00:00
|
|
|
|
2017-11-03 12:09:47 +00:00
|
|
|
#define PARALLELS_SUM_STATS(VAR, TYPE, NAME) \
|
|
|
|
if (s.VAR != -1) \
|
2015-06-25 07:56:56 +00:00
|
|
|
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;
|
2016-06-24 14:32:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainBlockStats(virDomainPtr domain,
|
|
|
|
const char *path,
|
|
|
|
virDomainBlockStatsPtr stats)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-24 14:32:32 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainBlockStatsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:32 +00:00
|
|
|
if (vzDomainBlockStatsImpl(dom, path, stats) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-06-09 07:35:53 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2016-06-14 08:45:52 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2015-06-09 07:35:53 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:33 +00:00
|
|
|
static int
|
|
|
|
vzDomainBlockStatsToParams(virDomainBlockStatsPtr stats,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int *nparams)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (*nparams == 0) {
|
2017-11-03 12:09:47 +00:00
|
|
|
#define PARALLELS_COUNT_STATS(VAR, TYPE, NAME) \
|
|
|
|
if ((stats->VAR) != -1) \
|
2016-06-24 14:32:33 +00:00
|
|
|
++*nparams;
|
|
|
|
|
|
|
|
PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_COUNT_STATS)
|
|
|
|
|
|
|
|
#undef PARALLELS_COUNT_STATS
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
2017-11-03 12:09:47 +00:00
|
|
|
#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) \
|
|
|
|
return -1; \
|
|
|
|
i++; \
|
2016-06-24 14:32:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PARALLELS_BLOCK_STATS_FOREACH(PARALLELS_BLOCK_STATS_ASSIGN_PARAM)
|
|
|
|
|
|
|
|
#undef PARALLELS_BLOCK_STATS_ASSIGN_PARAM
|
|
|
|
|
|
|
|
*nparams = i;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-09 07:35:53 +00:00
|
|
|
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;
|
2016-06-24 14:32:32 +00:00
|
|
|
virDomainObjPtr dom;
|
2015-06-09 07:35:53 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
|
|
|
|
/* We don't return strings, and thus trivially support this flag. */
|
|
|
|
flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-24 14:32:32 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainBlockStatsFlagsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:32 +00:00
|
|
|
if (vzDomainBlockStatsImpl(dom, path, &stats) < 0)
|
2015-06-09 07:35:53 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:33 +00:00
|
|
|
if (vzDomainBlockStatsToParams(&stats, params, nparams) < 0)
|
2015-06-09 07:35:53 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2016-06-24 14:32:32 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
2015-06-09 07:35:53 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-26 11:24:00 +00:00
|
|
|
static int
|
|
|
|
vzDomainInterfaceStats(virDomainPtr domain,
|
2017-10-13 20:25:42 +00:00
|
|
|
const char *device,
|
2015-06-26 11:24:00 +00:00
|
|
|
virDomainInterfaceStatsPtr stats)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
2016-06-03 07:11:44 +00:00
|
|
|
vzDomObjPtr privdom;
|
2016-06-24 14:32:38 +00:00
|
|
|
int ret = -1;
|
2015-06-26 11:24:00 +00:00
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2015-06-26 11:24:00 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainInterfaceStatsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-03 07:11:44 +00:00
|
|
|
privdom = dom->privateData;
|
|
|
|
|
2017-10-13 20:25:42 +00:00
|
|
|
ret = prlsdkGetNetStats(privdom->stats, privdom->sdkdom, device, stats);
|
2016-06-24 14:32:38 +00:00
|
|
|
|
|
|
|
cleanup:
|
2015-06-26 11:24:00 +00:00
|
|
|
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;
|
2016-06-03 07:11:44 +00:00
|
|
|
vzDomObjPtr privdom;
|
2015-06-26 11:24:00 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2015-06-26 11:24:00 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainMemoryStatsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-03 07:11:44 +00:00
|
|
|
privdom = dom->privateData;
|
|
|
|
|
|
|
|
ret = prlsdkGetMemoryStats(privdom->stats, stats, nr_stats);
|
2016-06-24 14:32:38 +00:00
|
|
|
|
|
|
|
cleanup:
|
2015-06-26 11:24:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-19 19:02:00 +00:00
|
|
|
static int
|
2016-06-03 07:11:43 +00:00
|
|
|
vzDomainGetVcpusFlags(virDomainPtr domain,
|
2015-10-19 19:02:00 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2016-06-14 08:45:52 +00:00
|
|
|
virDomainObjPtr dom;
|
2016-06-24 14:32:38 +00:00
|
|
|
int ret = -1;
|
2015-10-19 19:02:00 +00:00
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_AFFECT_CONFIG |
|
|
|
|
VIR_DOMAIN_VCPU_MAXIMUM, -1);
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-14 08:45:52 +00:00
|
|
|
return -1;
|
2015-10-19 19:02:00 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainGetVcpusFlagsEnsureACL(domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-10-19 19:02:00 +00:00
|
|
|
if (flags & VIR_DOMAIN_VCPU_MAXIMUM)
|
2016-06-03 07:11:43 +00:00
|
|
|
ret = virDomainDefGetVcpusMax(dom->def);
|
2015-10-19 19:02:00 +00:00
|
|
|
else
|
2016-06-03 07:11:43 +00:00
|
|
|
ret = virDomainDefGetVcpus(dom->def);
|
2015-10-19 19:02:00 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2015-10-19 19:02:00 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
static int vzDomainGetMaxVcpus(virDomainPtr domain)
|
2015-10-19 19:02:00 +00:00
|
|
|
{
|
2016-06-03 07:11:43 +00:00
|
|
|
return vzDomainGetVcpusFlags(domain, (VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_VCPU_MAXIMUM));
|
2015-10-19 19:02:00 +00:00
|
|
|
}
|
|
|
|
|
2016-06-03 07:11:43 +00:00
|
|
|
static int vzDomainIsUpdated(virDomainPtr domain)
|
2015-10-19 19:02:00 +00:00
|
|
|
{
|
2016-06-03 07:11:43 +00:00
|
|
|
virDomainObjPtr dom;
|
2016-06-24 14:32:38 +00:00
|
|
|
int ret = -1;
|
2015-10-19 19:02:00 +00:00
|
|
|
|
|
|
|
/* As far as VZ domains are always updated (e.g. current==persistent),
|
|
|
|
* we just check for domain existence */
|
2016-06-03 07:11:43 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-14 08:45:52 +00:00
|
|
|
return -1;
|
2015-10-19 19:02:00 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainIsUpdatedEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-06-24 14:32:38 +00:00
|
|
|
return ret;
|
2015-10-19 19:02:00 +00:00
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
static int vzConnectGetMaxVcpus(virConnectPtr conn,
|
2015-10-19 19:02:00 +00:00
|
|
|
const char *type)
|
|
|
|
{
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectGetMaxVcpusEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2015-10-19 19:02:00 +00:00
|
|
|
/* 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
|
2016-06-24 14:32:38 +00:00
|
|
|
vzNodeGetCPUStats(virConnectPtr conn,
|
2015-10-19 19:02:00 +00:00
|
|
|
int cpuNum,
|
|
|
|
virNodeCPUStatsPtr params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virNodeGetCPUStatsEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-04-13 17:16:16 +00:00
|
|
|
return virHostCPUGetStats(cpuNum, params, nparams, flags);
|
2015-10-19 19:02:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2016-06-24 14:32:38 +00:00
|
|
|
vzNodeGetMemoryStats(virConnectPtr conn,
|
2015-10-19 19:02:00 +00:00
|
|
|
int cellNum,
|
|
|
|
virNodeMemoryStatsPtr params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virNodeGetMemoryStatsEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-04-13 17:16:16 +00:00
|
|
|
return virHostMemGetStats(cellNum, params, nparams, flags);
|
2015-10-19 19:02:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2016-06-24 14:32:38 +00:00
|
|
|
vzNodeGetCellsFreeMemory(virConnectPtr conn,
|
2015-10-19 19:02:00 +00:00
|
|
|
unsigned long long *freeMems,
|
|
|
|
int startCell,
|
|
|
|
int maxCells)
|
|
|
|
{
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virNodeGetCellsFreeMemoryEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-04-13 17:16:16 +00:00
|
|
|
return virHostMemGetCellsFree(freeMems, startCell, maxCells);
|
2015-10-19 19:02:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned long long
|
2016-06-24 14:32:38 +00:00
|
|
|
vzNodeGetFreeMemory(virConnectPtr conn)
|
2015-10-19 19:02:00 +00:00
|
|
|
{
|
|
|
|
unsigned long long freeMem;
|
2016-06-24 14:32:38 +00:00
|
|
|
|
|
|
|
if (virNodeGetFreeMemoryEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-04-13 17:16:16 +00:00
|
|
|
if (virHostMemGetInfo(NULL, &freeMem) < 0)
|
2015-10-19 19:02:00 +00:00
|
|
|
return 0;
|
|
|
|
return freeMem;
|
|
|
|
}
|
|
|
|
|
2016-02-17 12:15:03 +00:00
|
|
|
static int
|
|
|
|
vzConnectRegisterCloseCallback(virConnectPtr conn,
|
|
|
|
virConnectCloseFunc cb,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
|
|
|
{
|
|
|
|
vzConnPtr privconn = conn->privateData;
|
|
|
|
int ret = -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectRegisterCloseCallbackEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-06-14 08:45:53 +00:00
|
|
|
virObjectLock(privconn->driver);
|
|
|
|
|
2016-02-17 12:15:03 +00:00
|
|
|
if (virConnectCloseCallbackDataGetCallback(privconn->closeCallback) != NULL) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("A close callback is already registered"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
virConnectCloseCallbackDataRegister(privconn->closeCallback, conn, cb,
|
|
|
|
opaque, freecb);
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2016-06-14 08:45:53 +00:00
|
|
|
virObjectUnlock(privconn->driver);
|
2016-02-17 12:15:03 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzConnectUnregisterCloseCallback(virConnectPtr conn, virConnectCloseFunc cb)
|
|
|
|
{
|
|
|
|
vzConnPtr privconn = conn->privateData;
|
|
|
|
int ret = -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectUnregisterCloseCallbackEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2016-06-14 08:45:53 +00:00
|
|
|
virObjectLock(privconn->driver);
|
2016-02-17 12:15:03 +00:00
|
|
|
|
|
|
|
if (virConnectCloseCallbackDataGetCallback(privconn->closeCallback) != cb) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("A different callback was requested"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
virConnectCloseCallbackDataUnregister(privconn->closeCallback, cb);
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2016-06-14 08:45:53 +00:00
|
|
|
virObjectUnlock(privconn->driver);
|
2016-02-17 12:15:03 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-06-24 14:32:35 +00:00
|
|
|
static int vzDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory,
|
|
|
|
unsigned int flags)
|
2016-04-08 09:36:45 +00:00
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int ret = -1;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
bool job = false;
|
2016-04-08 09:36:45 +00:00
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-04-08 09:36:45 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:35 +00:00
|
|
|
if (vzCheckConfigUpdateFlags(dom, &flags) < 0)
|
2016-04-08 09:36:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSetMemoryFlagsEnsureACL(domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-04-08 09:36:45 +00:00
|
|
|
ret = prlsdkSetMemsize(dom, memory >> 10);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
2016-04-08 09:36:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vzDomainSetMemory(virDomainPtr domain, unsigned long memory)
|
|
|
|
{
|
2016-06-24 14:32:35 +00:00
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-24 14:32:35 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSetMemoryEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:35 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = prlsdkSetMemsize(dom, memory >> 10);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
return ret;
|
2016-04-08 09:36:45 +00:00
|
|
|
}
|
|
|
|
|
2019-03-22 04:45:25 +00:00
|
|
|
static virDomainMomentObjPtr
|
2016-05-02 09:33:07 +00:00
|
|
|
vzSnapObjFromName(virDomainSnapshotObjListPtr snapshots, const char *name)
|
|
|
|
{
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr snap = NULL;
|
2016-05-02 09:33:07 +00:00
|
|
|
snap = virDomainSnapshotFindByName(snapshots, name);
|
|
|
|
if (!snap)
|
|
|
|
virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
|
|
|
|
_("no domain snapshot with matching name '%s'"), name);
|
|
|
|
|
|
|
|
return snap;
|
|
|
|
}
|
|
|
|
|
2019-03-22 04:45:25 +00:00
|
|
|
static virDomainMomentObjPtr
|
2016-05-02 09:33:07 +00:00
|
|
|
vzSnapObjFromSnapshot(virDomainSnapshotObjListPtr snapshots,
|
|
|
|
virDomainSnapshotPtr snapshot)
|
|
|
|
{
|
|
|
|
return vzSnapObjFromName(snapshots, snapshot->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainSnapshotNum(virDomainPtr domain, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
int n = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
|
|
|
|
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotNumEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
n = virDomainSnapshotObjListNum(snapshots, NULL, flags);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainSnapshotListNames(virDomainPtr domain,
|
|
|
|
char **names,
|
|
|
|
int nameslen,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
int n = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
|
|
|
|
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotListNamesEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
n = virDomainSnapshotObjListGetNames(snapshots, NULL, names, nameslen, flags);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainListAllSnapshots(virDomainPtr domain,
|
|
|
|
virDomainSnapshotPtr **snaps,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
int n = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
|
|
|
|
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainListAllSnapshotsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
n = virDomainListSnapshots(snapshots, NULL, domain, snaps, flags);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
vzDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
char *xml = NULL;
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr snap;
|
2016-05-02 09:33:07 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
vzConnPtr privconn = snapshot->domain->conn->privateData;
|
|
|
|
|
snapshot: Define explicit flags for snapshot xml
Commit f609cb85 (0.9.5) introduced virDomainSnapshotGetXMLDesc()'s use
of @flags as a subset of virDomainXMLFlags, documenting that 2 of the
3 flags defined at the time would never be valid. Later, commit
28f8dfdc (1.0.0) introduced a new flag, VIR_DOMAIN_XML_MIGRATABLE, but
did not adjust the snapshot documentation to declare it as invalid.
However, since the flag is not accepted as valid by any of the
drivers (remote is just passthrough; esx and vbox don't support flags;
qemu, test, and vz only support VIR_DOMAIN_XML_SECURE), and it is
unlikely that the domain state saved off during a snapshot creation
needs to be migration-friendly (as the snapshot is not the source of
a migration), it is easier to just define an explicit set of supported
flags directly related to the snapshot API rather than trying to
borrow from domain API, and risking confusion if even more domain
flags are added later (in fact, I have an upcoming patch that plans to
add a new flag to virDomainGetXMLDesc that makes no sense for
snapshots).
There is no API or ABI impact (since we purposefully used unsigned int
rather than an enum type in public API, and since the new flag name
carries the same value as the reused name).
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2019-02-13 21:09:05 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_XML_SECURE, NULL);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(snapshot->domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return NULL;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotGetXMLDescEnsureACL(snapshot->domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(snap = vzSnapObjFromSnapshot(snapshots, snapshot)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
virUUIDFormat(snapshot->domain->uuid, uuidstr);
|
|
|
|
|
2019-04-05 14:49:25 +00:00
|
|
|
xml = virDomainSnapshotDefFormat(uuidstr, virDomainSnapshotObjGetDef(snap),
|
|
|
|
privconn->driver->caps,
|
2017-06-01 22:27:33 +00:00
|
|
|
privconn->driver->xmlopt,
|
2019-02-15 20:43:43 +00:00
|
|
|
virDomainSnapshotFormatConvertXMLFlags(flags));
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return xml;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr snap;
|
2016-05-02 09:33:07 +00:00
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
int n = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
|
|
|
|
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(snapshot->domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotNumChildrenEnsureACL(snapshot->domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(snap = vzSnapObjFromSnapshot(snapshots, snapshot)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
n = virDomainSnapshotObjListNum(snapshots, snap, flags);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
|
|
|
|
char **names,
|
|
|
|
int nameslen,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr snap;
|
2016-05-02 09:33:07 +00:00
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
int n = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
|
|
|
|
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(snapshot->domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotListChildrenNamesEnsureACL(snapshot->domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(snap = vzSnapObjFromSnapshot(snapshots, snapshot)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
n = virDomainSnapshotObjListGetNames(snapshots, snap, names, nameslen, flags);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainSnapshotListAllChildren(virDomainSnapshotPtr snapshot,
|
|
|
|
virDomainSnapshotPtr **snaps,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr snap;
|
2016-05-02 09:33:07 +00:00
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
int n = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
|
|
|
|
VIR_DOMAIN_SNAPSHOT_FILTERS_ALL, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(snapshot->domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotListAllChildrenEnsureACL(snapshot->domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(snap = vzSnapObjFromSnapshot(snapshots, snapshot)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
n = virDomainListSnapshots(snapshots, snap, snapshot->domain, snaps, flags);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainSnapshotPtr
|
|
|
|
vzDomainSnapshotLookupByName(virDomainPtr domain,
|
|
|
|
const char *name,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr snap;
|
2016-05-02 09:33:07 +00:00
|
|
|
virDomainSnapshotPtr snapshot = NULL;
|
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
|
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return NULL;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotLookupByNameEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(snap = vzSnapObjFromName(snapshots, name)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
snapshot = virGetDomainSnapshot(domain, snap->def->name);
|
|
|
|
|
|
|
|
cleanup:
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
|
|
|
|
|
|
|
return snapshot;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainHasCurrentSnapshotEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
2019-04-05 14:33:49 +00:00
|
|
|
ret = virDomainSnapshotGetCurrent(snapshots) != NULL;
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainSnapshotPtr
|
|
|
|
vzDomainSnapshotGetParent(virDomainSnapshotPtr snapshot, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr snap;
|
2016-05-02 09:33:07 +00:00
|
|
|
virDomainSnapshotPtr parent = NULL;
|
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
|
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(snapshot->domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return NULL;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotGetParentEnsureACL(snapshot->domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(snap = vzSnapObjFromSnapshot(snapshots, snapshot)))
|
|
|
|
goto cleanup;
|
|
|
|
|
2019-05-28 10:33:22 +00:00
|
|
|
if (!snap->def->parent_name) {
|
2016-05-02 09:33:07 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
|
|
|
|
_("snapshot '%s' does not have a parent"),
|
|
|
|
snap->def->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2019-05-28 10:33:22 +00:00
|
|
|
parent = virGetDomainSnapshot(snapshot->domain, snap->def->parent_name);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainSnapshotPtr
|
|
|
|
vzDomainSnapshotCurrent(virDomainPtr domain, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
virDomainSnapshotPtr snapshot = NULL;
|
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr current;
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return NULL;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotCurrentEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
2019-04-05 14:33:49 +00:00
|
|
|
if (!(current = virDomainSnapshotGetCurrent(snapshots))) {
|
2016-05-02 09:33:07 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s",
|
|
|
|
_("the domain does not have a current snapshot"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
snapshot = virGetDomainSnapshot(domain, current->def->name);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return snapshot;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr current;
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(snapshot->domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotIsCurrentEnsureACL(snapshot->domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
2019-04-05 14:33:49 +00:00
|
|
|
current = virDomainSnapshotGetCurrent(snapshots);
|
2016-05-02 09:33:07 +00:00
|
|
|
ret = current && STREQ(snapshot->name, current->def->name);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainSnapshotHasMetadata(virDomainSnapshotPtr snapshot,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr snap;
|
2016-05-02 09:33:07 +00:00
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(snapshot->domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotHasMetadataEnsureACL(snapshot->domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(snap = vzSnapObjFromSnapshot(snapshots, snapshot)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 1;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainSnapshotPtr
|
|
|
|
vzDomainSnapshotCreateXML(virDomainPtr domain,
|
|
|
|
const char *xmlDesc,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainSnapshotPtr snapshot = NULL;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
|
|
|
vzDriverPtr driver = privconn->driver;
|
|
|
|
unsigned int parse_flags = VIR_DOMAIN_SNAPSHOT_PARSE_DISKS;
|
|
|
|
virDomainSnapshotObjListPtr snapshots = NULL;
|
2019-03-22 04:45:25 +00:00
|
|
|
virDomainMomentObjPtr current;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
bool job = false;
|
2019-10-15 12:47:50 +00:00
|
|
|
g_autoptr(virDomainSnapshotDef) def = NULL;
|
2016-05-02 09:33:07 +00:00
|
|
|
|
snapshot: Add VIR_DOMAIN_SNAPSHOT_CREATE_VALIDATE flag
We've been doing a terrible job of performing XML validation in our
various API that parse XML with a corresponding schema (we started
with domains back in commit dd69a14f, v1.2.12, but didn't catch all
domain-related APIs, didn't document the use of the flag, and didn't
cover other XML). New APIs (like checkpoints) should do the validation
unconditionally, but it doesn't hurt to continue retrofitting existing
APIs to at least allow the option.
While there are many APIs that could be improved, this patch focuses
on wiring up a new snapshot XML creation flag through all the
hypervisors that support snapshots, as well as exposing it in 'virsh
snapshot-create'. For 'virsh snapshot-create-as', we blindly set the
flag without a command-line option, since the XML we create from the
command line should generally always comply (note that validation
might cause failures where it used to succeed, such as if we tighten
the RNG to reject a name of '../\n'); but blindly passing the flag
means we also have to add in fallback code to disable validation if
the server is too old to understand the flag.
Signed-off-by: Eric Blake <eblake@redhat.com>
Acked-by: Peter Krempa <pkrempa@redhat.com>
2019-07-06 03:05:37 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_VALIDATE, NULL);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return NULL;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotCreateXMLEnsureACL(domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
snapshot: Add VIR_DOMAIN_SNAPSHOT_CREATE_VALIDATE flag
We've been doing a terrible job of performing XML validation in our
various API that parse XML with a corresponding schema (we started
with domains back in commit dd69a14f, v1.2.12, but didn't catch all
domain-related APIs, didn't document the use of the flag, and didn't
cover other XML). New APIs (like checkpoints) should do the validation
unconditionally, but it doesn't hurt to continue retrofitting existing
APIs to at least allow the option.
While there are many APIs that could be improved, this patch focuses
on wiring up a new snapshot XML creation flag through all the
hypervisors that support snapshots, as well as exposing it in 'virsh
snapshot-create'. For 'virsh snapshot-create-as', we blindly set the
flag without a command-line option, since the XML we create from the
command line should generally always comply (note that validation
might cause failures where it used to succeed, such as if we tighten
the RNG to reject a name of '../\n'); but blindly passing the flag
means we also have to add in fallback code to disable validation if
the server is too old to understand the flag.
Signed-off-by: Eric Blake <eblake@redhat.com>
Acked-by: Peter Krempa <pkrempa@redhat.com>
2019-07-06 03:05:37 +00:00
|
|
|
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_VALIDATE)
|
|
|
|
parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_VALIDATE;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
if (!(def = virDomainSnapshotDefParseString(xmlDesc, driver->caps,
|
2019-09-18 06:59:32 +00:00
|
|
|
driver->xmlopt, NULL, NULL,
|
snapshot: Drop virDomainSnapshotDef.current
The only use for the 'current' member of virDomainSnapshotDef was with
the PARSE/FORMAT_INTERNAL flag for controlling an internal-use
<active> element marking whether a particular snapshot definition was
current, and even then, only by the qemu driver on output, and by qemu
and test driver on input. But this duplicates vm->snapshot_current,
and gets in the way of potential simplifications to have qemu store a
single file for all snapshots rather than one file per snapshot. Get
rid of the member by adding a bool* parameter during parse (ignored if
the PARSE_INTERNAL flag is not set), and by adding a new flag during
format (if FORMAT_INTERNAL is set, the value printed in <active>
depends on the new FORMAT_CURRENT).
Then update the qemu driver accordingly, which involves hoisting
assignments to vm->current_snapshot to occur prior to any point where
a snapshot XML file is written (although qemu kept
vm->current_snapshot and snapshot->def_current in sync by the end of
the function, they were not always identical in the middle of
functions, so the shuffling gets a bit interesting). Later patches
will clean up some of that confusing churn to vm->current_snapshot.
Note: even if later patches refactor qemu to no longer use
FORMAT_INTERNAL for output (by storing bulk snapshot XML instead), we
will always need PARSE_INTERNAL for input (because on upgrade, a new
libvirt still has to parse XML left from a previous libvirt).
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2019-03-19 03:56:19 +00:00
|
|
|
parse_flags)))
|
2016-05-02 09:33:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (def->ndisks > 0) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("configuring disks is not supported for vz snapshots"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (def->memory) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("configuring memory location is not supported"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
/* snaphot name is ignored, it will be set to auto generated by sdk uuid */
|
2019-05-08 22:10:58 +00:00
|
|
|
if (prlsdkCreateSnapshot(dom, def->parent.description) < 0)
|
2016-05-02 09:33:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(snapshots = prlsdkLoadSnapshots(dom)))
|
|
|
|
goto cleanup;
|
|
|
|
|
2019-04-05 14:33:49 +00:00
|
|
|
if (!(current = virDomainSnapshotGetCurrent(snapshots))) {
|
2016-05-02 09:33:07 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("can't find created snapshot"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* hopefully new current snapshot is newly created one */
|
|
|
|
snapshot = virGetDomainSnapshot(domain, current->def->name);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotObjListFree(snapshots);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return snapshot;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(snapshot->domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainSnapshotDeleteEnsureACL(snapshot->domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
ret = prlsdkDeleteSnapshot(dom, snapshot->name,
|
|
|
|
flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN);
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
cleanup:
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
bool job = false;
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(snapshot->domain)))
|
2016-05-02 09:33:07 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainRevertToSnapshotEnsureACL(snapshot->domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-02 09:33:07 +00:00
|
|
|
ret = prlsdkSwitchToSnapshot(dom, snapshot->name,
|
|
|
|
flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-02 09:33:07 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-06-08 07:17:19 +00:00
|
|
|
enum vzMigrationCookieFeatures {
|
|
|
|
VZ_MIGRATION_COOKIE_SESSION_UUID = (1 << 0),
|
|
|
|
VZ_MIGRATION_COOKIE_DOMAIN_UUID = (1 << 1),
|
|
|
|
VZ_MIGRATION_COOKIE_DOMAIN_NAME = (1 << 1),
|
|
|
|
};
|
|
|
|
|
2016-05-18 08:11:06 +00:00
|
|
|
typedef struct _vzMigrationCookie vzMigrationCookie;
|
|
|
|
typedef vzMigrationCookie *vzMigrationCookiePtr;
|
|
|
|
struct _vzMigrationCookie {
|
2016-06-08 07:17:19 +00:00
|
|
|
unsigned char *session_uuid;
|
|
|
|
unsigned char *uuid;
|
2016-05-18 08:11:06 +00:00
|
|
|
char *name;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
vzMigrationCookieFree(vzMigrationCookiePtr mig)
|
|
|
|
{
|
|
|
|
if (!mig)
|
|
|
|
return;
|
2016-06-08 07:17:19 +00:00
|
|
|
|
|
|
|
VIR_FREE(mig->session_uuid);
|
|
|
|
VIR_FREE(mig->uuid);
|
2016-05-18 08:11:06 +00:00
|
|
|
VIR_FREE(mig->name);
|
|
|
|
VIR_FREE(mig);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2016-06-08 07:17:19 +00:00
|
|
|
vzBakeCookie(vzDriverPtr driver,
|
|
|
|
virDomainObjPtr dom,
|
|
|
|
char **cookieout, int *cookieoutlen,
|
|
|
|
unsigned int flags)
|
2016-05-18 08:11:06 +00:00
|
|
|
{
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
|
|
|
|
if (!cookieout || !cookieoutlen) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Migration cookie parameters are not provided."));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*cookieout = NULL;
|
|
|
|
*cookieoutlen = 0;
|
|
|
|
|
|
|
|
virBufferAddLit(&buf, "<vz-migration>\n");
|
|
|
|
virBufferAdjustIndent(&buf, 2);
|
2016-06-08 07:17:19 +00:00
|
|
|
|
|
|
|
if (flags & VZ_MIGRATION_COOKIE_SESSION_UUID) {
|
|
|
|
virUUIDFormat(driver->session_uuid, uuidstr);
|
|
|
|
virBufferAsprintf(&buf, "<session-uuid>%s</session-uuid>\n", uuidstr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & VZ_MIGRATION_COOKIE_DOMAIN_UUID) {
|
|
|
|
unsigned char fakeuuid[VIR_UUID_BUFLEN] = { 0 };
|
|
|
|
|
|
|
|
/* if dom is NULL just pass some parsable uuid for backward compat.
|
|
|
|
* It is not used by peer */
|
|
|
|
virUUIDFormat(dom ? dom->def->uuid : fakeuuid, uuidstr);
|
|
|
|
virBufferAsprintf(&buf, "<uuid>%s</uuid>\n", uuidstr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & VZ_MIGRATION_COOKIE_DOMAIN_NAME) {
|
|
|
|
/* if dom is NULL just pass some name for backward compat.
|
|
|
|
* It is not used by peer */
|
|
|
|
virBufferAsprintf(&buf, "<name>%s</name>\n", dom ? dom->def->name :
|
|
|
|
"__fakename__");
|
|
|
|
}
|
|
|
|
|
2016-05-18 08:11:06 +00:00
|
|
|
virBufferAdjustIndent(&buf, -2);
|
|
|
|
virBufferAddLit(&buf, "</vz-migration>\n");
|
|
|
|
|
|
|
|
if (virBufferCheckError(&buf) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
*cookieout = virBufferContentAndReset(&buf);
|
|
|
|
*cookieoutlen = strlen(*cookieout) + 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static vzMigrationCookiePtr
|
2016-06-08 07:17:19 +00:00
|
|
|
vzEatCookie(const char *cookiein, int cookieinlen, unsigned int flags)
|
2016-05-18 08:11:06 +00:00
|
|
|
{
|
|
|
|
xmlDocPtr doc = NULL;
|
|
|
|
xmlXPathContextPtr ctx = NULL;
|
2016-06-08 07:17:19 +00:00
|
|
|
char *tmp = NULL;
|
2016-05-18 08:11:06 +00:00
|
|
|
vzMigrationCookiePtr mig = NULL;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(mig) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!cookiein || cookieinlen <= 0 || cookiein[cookieinlen - 1] != '\0') {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Invalid migration cookie"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(doc = virXMLParseStringCtxt(cookiein,
|
|
|
|
_("(_migration_cookie)"), &ctx)))
|
|
|
|
goto error;
|
|
|
|
|
2016-06-08 07:17:19 +00:00
|
|
|
if ((flags & VZ_MIGRATION_COOKIE_SESSION_UUID)
|
|
|
|
&& (!(tmp = virXPathString("string(./session-uuid[1])", ctx))
|
|
|
|
|| (VIR_ALLOC_N(mig->session_uuid, VIR_UUID_BUFLEN) < 0)
|
|
|
|
|| (virUUIDParse(tmp, mig->session_uuid) < 0))) {
|
2016-05-18 08:11:06 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
2016-06-08 07:17:19 +00:00
|
|
|
_("missing or malformed session-uuid element "
|
|
|
|
"in migration data"));
|
2016-05-18 08:11:06 +00:00
|
|
|
VIR_FREE(tmp);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
|
2016-06-08 07:17:19 +00:00
|
|
|
if ((flags & VZ_MIGRATION_COOKIE_DOMAIN_UUID)
|
|
|
|
&& (!(tmp = virXPathString("string(./uuid[1])", ctx))
|
|
|
|
|| (VIR_ALLOC_N(mig->uuid, VIR_UUID_BUFLEN) < 0)
|
|
|
|
|| (virUUIDParse(tmp, mig->uuid) < 0))) {
|
2016-05-18 08:11:06 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
2016-06-08 07:17:19 +00:00
|
|
|
_("missing or malformed uuid element in migration data"));
|
2016-05-18 08:11:06 +00:00
|
|
|
VIR_FREE(tmp);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
VIR_FREE(tmp);
|
|
|
|
|
2016-06-08 07:17:19 +00:00
|
|
|
if ((flags & VZ_MIGRATION_COOKIE_DOMAIN_NAME)
|
|
|
|
&& !(mig->name = virXPathString("string(./name[1])", ctx))) {
|
2016-05-18 08:11:06 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("missing name element in migration data"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
xmlXPathFreeContext(ctx);
|
|
|
|
xmlFreeDoc(doc);
|
|
|
|
return mig;
|
|
|
|
|
|
|
|
error:
|
|
|
|
vzMigrationCookieFree(mig);
|
|
|
|
mig = NULL;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2017-11-03 12:09:47 +00:00
|
|
|
#define VZ_MIGRATION_FLAGS (VIR_MIGRATE_PAUSED | \
|
|
|
|
VIR_MIGRATE_PEER2PEER | \
|
|
|
|
VIR_MIGRATE_LIVE | \
|
2016-08-25 14:00:24 +00:00
|
|
|
VIR_MIGRATE_UNDEFINE_SOURCE | \
|
2017-11-03 12:09:47 +00:00
|
|
|
VIR_MIGRATE_PERSIST_DEST | \
|
2016-12-08 08:49:16 +00:00
|
|
|
VIR_MIGRATE_NON_SHARED_INC)
|
2016-05-18 08:11:06 +00:00
|
|
|
|
2017-11-03 12:09:47 +00:00
|
|
|
#define VZ_MIGRATION_PARAMETERS \
|
2016-05-18 08:11:06 +00:00
|
|
|
VIR_MIGRATE_PARAM_DEST_XML, VIR_TYPED_PARAM_STRING, \
|
|
|
|
VIR_MIGRATE_PARAM_URI, VIR_TYPED_PARAM_STRING, \
|
|
|
|
VIR_MIGRATE_PARAM_DEST_NAME, VIR_TYPED_PARAM_STRING, \
|
2016-08-25 14:00:25 +00:00
|
|
|
VIR_MIGRATE_PARAM_BANDWIDTH, VIR_TYPED_PARAM_ULLONG, \
|
2016-05-18 08:11:06 +00:00
|
|
|
NULL
|
|
|
|
|
2016-06-24 14:32:36 +00:00
|
|
|
static char *
|
|
|
|
vzDomainMigrateBeginStep(virDomainObjPtr dom,
|
|
|
|
vzDriverPtr driver,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen)
|
|
|
|
{
|
|
|
|
/* we can't do this check via VZ_MIGRATION_PARAMETERS as on preparation
|
|
|
|
* step domain xml will be passed via this parameter and it is a common
|
|
|
|
* style to use single allowed parameter list definition in all steps */
|
|
|
|
if (virTypedParamsGet(params, nparams, VIR_MIGRATE_PARAM_DEST_XML)) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|
|
|
_("Changing destination XML is not supported"));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* session uuid, domain uuid and domain name are for backward compat */
|
|
|
|
if (vzBakeCookie(driver, dom, cookieout, cookieoutlen,
|
|
|
|
VZ_MIGRATION_COOKIE_SESSION_UUID
|
|
|
|
| VZ_MIGRATION_COOKIE_DOMAIN_UUID
|
|
|
|
| VZ_MIGRATION_COOKIE_DOMAIN_NAME) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return virDomainDefFormat(dom->def, driver->caps,
|
|
|
|
VIR_DOMAIN_XML_MIGRATABLE);
|
|
|
|
}
|
|
|
|
|
2016-05-18 08:11:06 +00:00
|
|
|
static char *
|
|
|
|
vzDomainMigrateBegin3Params(virDomainPtr domain,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
char *xml = NULL;
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
2016-08-25 14:00:25 +00:00
|
|
|
unsigned long long bandwidth = 0;
|
2016-05-18 08:11:06 +00:00
|
|
|
|
|
|
|
virCheckFlags(VZ_MIGRATION_FLAGS, NULL);
|
|
|
|
|
|
|
|
if (virTypedParamsValidate(params, nparams, VZ_MIGRATION_PARAMETERS) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-08-25 14:00:25 +00:00
|
|
|
if (virTypedParamsGetULLong(params, nparams, VIR_MIGRATE_PARAM_BANDWIDTH,
|
|
|
|
&bandwidth) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (bandwidth > 0) {
|
|
|
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|
|
|
_("Bandwidth rate limiting is not supported"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-05-18 08:11:06 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainMigrateBegin3ParamsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:36 +00:00
|
|
|
xml = vzDomainMigrateBeginStep(dom, privconn->driver, params, nparams,
|
|
|
|
cookieout, cookieoutlen);
|
2016-05-18 08:11:06 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-18 08:11:06 +00:00
|
|
|
return xml;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char*
|
|
|
|
vzMigrationCreateURI(void)
|
|
|
|
{
|
|
|
|
char *hostname = NULL;
|
|
|
|
char *uri = NULL;
|
|
|
|
|
|
|
|
if (!(hostname = virGetHostname()))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (STRPREFIX(hostname, "localhost")) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("hostname on destination resolved to localhost,"
|
|
|
|
" but migration requires an FQDN"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virAsprintf(&uri, "vzmigr://%s", hostname) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(hostname);
|
|
|
|
return uri;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainMigratePrepare3Params(virConnectPtr conn,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
2019-10-14 12:45:33 +00:00
|
|
|
const char *cookiein G_GNUC_UNUSED,
|
|
|
|
int cookieinlen G_GNUC_UNUSED,
|
2016-05-18 08:11:06 +00:00
|
|
|
char **cookieout,
|
|
|
|
int *cookieoutlen,
|
|
|
|
char **uri_out,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
vzConnPtr privconn = conn->privateData;
|
2016-06-24 14:32:38 +00:00
|
|
|
vzDriverPtr driver = privconn->driver;
|
2016-05-18 08:11:06 +00:00
|
|
|
const char *miguri = NULL;
|
|
|
|
const char *dname = NULL;
|
2016-06-24 14:32:38 +00:00
|
|
|
const char *dom_xml = NULL;
|
|
|
|
virDomainDefPtr def = NULL;
|
2016-05-18 08:11:06 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(VZ_MIGRATION_FLAGS, -1);
|
|
|
|
|
|
|
|
if (virTypedParamsValidate(params, nparams, VZ_MIGRATION_PARAMETERS) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virTypedParamsGetString(params, nparams,
|
|
|
|
VIR_MIGRATE_PARAM_URI, &miguri) < 0 ||
|
2016-06-24 14:32:38 +00:00
|
|
|
virTypedParamsGetString(params, nparams,
|
|
|
|
VIR_MIGRATE_PARAM_DEST_XML, &dom_xml) < 0 ||
|
2016-05-18 08:11:06 +00:00
|
|
|
virTypedParamsGetString(params, nparams,
|
|
|
|
VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* We must set uri_out if miguri is not set. This is direct
|
|
|
|
* managed migration requirement */
|
|
|
|
if (!miguri && !(*uri_out = vzMigrationCreateURI()))
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-08 07:17:19 +00:00
|
|
|
/* domain uuid and domain name are for backward compat */
|
|
|
|
if (vzBakeCookie(privconn->driver, NULL,
|
|
|
|
cookieout, cookieoutlen,
|
|
|
|
VZ_MIGRATION_COOKIE_SESSION_UUID
|
|
|
|
| VZ_MIGRATION_COOKIE_DOMAIN_UUID
|
|
|
|
| VZ_MIGRATION_COOKIE_DOMAIN_NAME) < 0)
|
2016-05-18 08:11:06 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (!(def = virDomainDefParseString(dom_xml, driver->caps, driver->xmlopt,
|
2016-09-22 15:14:17 +00:00
|
|
|
NULL,
|
2016-06-24 14:32:38 +00:00
|
|
|
VIR_DOMAIN_DEF_PARSE_INACTIVE)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (dname) {
|
|
|
|
VIR_FREE(def->name);
|
|
|
|
if (VIR_STRDUP(def->name, dname) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virDomainMigratePrepare3ParamsEnsureACL(conn, def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-18 08:11:06 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2016-06-24 14:32:38 +00:00
|
|
|
virDomainDefFree(def);
|
2016-05-18 08:11:06 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2019-10-14 12:45:33 +00:00
|
|
|
vzConnectSupportsFeature(virConnectPtr conn G_GNUC_UNUSED, int feature)
|
2016-05-18 08:11:06 +00:00
|
|
|
{
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virConnectSupportsFeatureEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2018-03-08 12:20:24 +00:00
|
|
|
switch ((virDrvFeature) feature) {
|
2016-05-18 08:11:06 +00:00
|
|
|
case VIR_DRV_FEATURE_MIGRATION_PARAMS:
|
2016-05-18 08:11:07 +00:00
|
|
|
case VIR_DRV_FEATURE_MIGRATION_P2P:
|
2016-05-18 08:11:06 +00:00
|
|
|
return 1;
|
2018-03-08 12:20:24 +00:00
|
|
|
case VIR_DRV_FEATURE_FD_PASSING:
|
|
|
|
case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION:
|
|
|
|
case VIR_DRV_FEATURE_MIGRATION_DIRECT:
|
|
|
|
case VIR_DRV_FEATURE_MIGRATION_OFFLINE:
|
|
|
|
case VIR_DRV_FEATURE_MIGRATION_V1:
|
|
|
|
case VIR_DRV_FEATURE_MIGRATION_V2:
|
|
|
|
case VIR_DRV_FEATURE_MIGRATION_V3:
|
|
|
|
case VIR_DRV_FEATURE_PROGRAM_KEEPALIVE:
|
|
|
|
case VIR_DRV_FEATURE_REMOTE:
|
|
|
|
case VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK:
|
|
|
|
case VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK:
|
|
|
|
case VIR_DRV_FEATURE_TYPED_PARAM_STRING:
|
|
|
|
case VIR_DRV_FEATURE_XML_MIGRATABLE:
|
2016-05-18 08:11:06 +00:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static virURIPtr
|
|
|
|
vzParseVzURI(const char *uri_str)
|
|
|
|
{
|
|
|
|
virURIPtr uri = NULL;
|
|
|
|
|
|
|
|
if (!(uri = virURIParse(uri_str)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!uri->scheme || !uri->server) {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("scheme and host are mandatory vz migration URI: %s"),
|
|
|
|
uri_str);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uri->user || uri->path || uri->query || uri->fragment) {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("only scheme, host and port are supported in "
|
|
|
|
"vz migration URI: %s"), uri_str);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (STRNEQ(uri->scheme, "vzmigr")) {
|
|
|
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
|
|
|
|
_("unsupported scheme %s in migration URI %s"),
|
|
|
|
uri->scheme, uri_str);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return uri;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virURIFree(uri);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2016-06-24 14:32:36 +00:00
|
|
|
vzDomainMigratePerformStep(virDomainObjPtr dom,
|
|
|
|
vzDriverPtr driver,
|
2016-05-18 08:11:07 +00:00
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
|
|
|
unsigned int flags)
|
2016-05-18 08:11:06 +00:00
|
|
|
{
|
|
|
|
int ret = -1;
|
2016-06-24 14:32:36 +00:00
|
|
|
vzDomObjPtr privdom = dom->privateData;
|
2016-05-18 08:11:06 +00:00
|
|
|
virURIPtr vzuri = NULL;
|
|
|
|
const char *miguri = NULL;
|
|
|
|
const char *dname = NULL;
|
|
|
|
vzMigrationCookiePtr mig = NULL;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
bool job = false;
|
2016-05-18 08:11:06 +00:00
|
|
|
|
|
|
|
if (virTypedParamsGetString(params, nparams,
|
|
|
|
VIR_MIGRATE_PARAM_URI, &miguri) < 0 ||
|
|
|
|
virTypedParamsGetString(params, nparams,
|
|
|
|
VIR_MIGRATE_PARAM_DEST_NAME, &dname) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!miguri) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("migrate uri is not set"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2016-06-08 07:17:19 +00:00
|
|
|
if (!(mig = vzEatCookie(cookiein, cookieinlen,
|
|
|
|
VZ_MIGRATION_COOKIE_SESSION_UUID)))
|
2016-05-18 08:11:06 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
2016-06-20 10:08:14 +00:00
|
|
|
privdom->job.hasProgress = true;
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
|
2016-07-20 15:00:34 +00:00
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-18 08:11:06 +00:00
|
|
|
if (!(vzuri = vzParseVzURI(miguri)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (prlsdkMigrate(dom, vzuri, mig->session_uuid, dname, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:36 +00:00
|
|
|
virDomainObjListRemove(driver->domains, dom);
|
2016-05-18 08:11:06 +00:00
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
2016-05-18 08:11:06 +00:00
|
|
|
virURIFree(vzuri);
|
|
|
|
vzMigrationCookieFree(mig);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-05-18 08:11:07 +00:00
|
|
|
static int
|
2016-06-24 14:32:36 +00:00
|
|
|
vzDomainMigratePerformP2P(virDomainObjPtr dom,
|
|
|
|
vzDriverPtr driver,
|
2016-05-18 08:11:07 +00:00
|
|
|
const char *dconnuri,
|
|
|
|
virTypedParameterPtr orig_params,
|
|
|
|
int nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainPtr ddomain = NULL;
|
|
|
|
char *uri = NULL;
|
|
|
|
char *cookiein = NULL;
|
|
|
|
char *cookieout = NULL;
|
|
|
|
char *dom_xml = NULL;
|
|
|
|
int cookieinlen = 0;
|
|
|
|
int cookieoutlen = 0;
|
|
|
|
virErrorPtr orig_err = NULL;
|
|
|
|
int cancelled = 1;
|
|
|
|
virConnectPtr dconn = NULL;
|
|
|
|
virTypedParameterPtr params = NULL;
|
|
|
|
int ret = -1;
|
2016-11-14 15:20:30 +00:00
|
|
|
int maxparams = nparams;
|
2016-05-18 08:11:07 +00:00
|
|
|
|
|
|
|
if (virTypedParamsCopy(¶ms, orig_params, nparams) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!(dconn = virConnectOpen(dconnuri)))
|
|
|
|
goto done;
|
|
|
|
|
2016-06-24 14:32:36 +00:00
|
|
|
if (!(dom_xml = vzDomainMigrateBeginStep(dom, driver, params, nparams,
|
|
|
|
&cookieout, &cookieoutlen)))
|
2016-05-18 08:11:07 +00:00
|
|
|
goto done;
|
|
|
|
|
2016-11-14 15:20:30 +00:00
|
|
|
if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
|
|
|
|
VIR_MIGRATE_PARAM_DEST_XML, dom_xml) < 0)
|
|
|
|
goto done;
|
|
|
|
|
2019-10-16 11:45:15 +00:00
|
|
|
cookiein = g_steal_pointer(&cookieout);
|
2016-05-18 08:11:07 +00:00
|
|
|
cookieinlen = cookieoutlen;
|
|
|
|
cookieoutlen = 0;
|
2016-06-24 14:32:36 +00:00
|
|
|
virObjectUnlock(dom);
|
|
|
|
ret = dconn->driver->domainMigratePrepare3Params
|
2016-05-18 08:11:07 +00:00
|
|
|
(dconn, params, nparams, cookiein, cookieinlen,
|
2016-06-24 14:32:36 +00:00
|
|
|
&cookieout, &cookieoutlen, &uri, flags);
|
|
|
|
virObjectLock(dom);
|
|
|
|
if (ret < 0)
|
2016-05-18 08:11:07 +00:00
|
|
|
goto done;
|
2016-06-24 14:32:36 +00:00
|
|
|
ret = -1;
|
2016-05-18 08:11:07 +00:00
|
|
|
|
|
|
|
/* preparation step was successful, thus on any error we must perform
|
|
|
|
* finish step to finalize migration on target
|
|
|
|
*/
|
|
|
|
if (uri && virTypedParamsReplaceString(¶ms, &nparams,
|
|
|
|
VIR_MIGRATE_PARAM_URI, uri) < 0) {
|
|
|
|
orig_err = virSaveLastError();
|
|
|
|
goto finish;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(cookiein);
|
2019-10-16 11:45:15 +00:00
|
|
|
cookiein = g_steal_pointer(&cookieout);
|
2016-05-18 08:11:07 +00:00
|
|
|
cookieinlen = cookieoutlen;
|
|
|
|
cookieoutlen = 0;
|
2016-06-24 14:32:36 +00:00
|
|
|
if (vzDomainMigratePerformStep(dom, driver, params, nparams, cookiein,
|
2016-05-18 08:11:07 +00:00
|
|
|
cookieinlen, flags) < 0) {
|
|
|
|
orig_err = virSaveLastError();
|
|
|
|
goto finish;
|
|
|
|
}
|
|
|
|
|
|
|
|
cancelled = 0;
|
|
|
|
|
|
|
|
finish:
|
|
|
|
if (virTypedParamsGetString(params, nparams,
|
|
|
|
VIR_MIGRATE_PARAM_DEST_NAME, NULL) <= 0 &&
|
|
|
|
virTypedParamsReplaceString(¶ms, &nparams,
|
|
|
|
VIR_MIGRATE_PARAM_DEST_NAME,
|
2016-06-24 14:32:36 +00:00
|
|
|
dom->def->name) < 0)
|
2016-05-18 08:11:07 +00:00
|
|
|
goto done;
|
|
|
|
|
2016-06-24 14:32:36 +00:00
|
|
|
virObjectUnlock(dom);
|
2016-05-18 08:11:07 +00:00
|
|
|
ddomain = dconn->driver->domainMigrateFinish3Params(dconn, params, nparams,
|
|
|
|
NULL, 0, NULL, NULL,
|
|
|
|
flags, cancelled);
|
2016-06-24 14:32:36 +00:00
|
|
|
virObjectLock(dom);
|
2016-05-18 08:11:07 +00:00
|
|
|
if (ddomain)
|
|
|
|
ret = 0;
|
|
|
|
virObjectUnref(ddomain);
|
|
|
|
|
|
|
|
/* confirm step is NOOP thus no need to call it */
|
|
|
|
|
|
|
|
done:
|
|
|
|
if (orig_err) {
|
|
|
|
virSetError(orig_err);
|
|
|
|
virFreeError(orig_err);
|
|
|
|
}
|
|
|
|
VIR_FREE(dom_xml);
|
|
|
|
VIR_FREE(uri);
|
|
|
|
VIR_FREE(cookiein);
|
|
|
|
VIR_FREE(cookieout);
|
|
|
|
virTypedParamsFree(params, nparams);
|
|
|
|
virObjectUnref(dconn);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainMigratePerform3Params(virDomainPtr domain,
|
|
|
|
const char *dconnuri,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
|
|
|
const char *cookiein,
|
|
|
|
int cookieinlen,
|
2019-10-14 12:45:33 +00:00
|
|
|
char **cookieout G_GNUC_UNUSED,
|
|
|
|
int *cookieoutlen G_GNUC_UNUSED,
|
2016-05-18 08:11:07 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2016-06-24 14:32:38 +00:00
|
|
|
int ret = -1;
|
2016-06-24 14:32:36 +00:00
|
|
|
virDomainObjPtr dom;
|
|
|
|
vzConnPtr privconn = domain->conn->privateData;
|
|
|
|
|
2016-05-18 08:11:07 +00:00
|
|
|
virCheckFlags(VZ_MIGRATION_FLAGS, -1);
|
|
|
|
|
|
|
|
if (virTypedParamsValidate(params, nparams, VZ_MIGRATION_PARAMETERS) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2016-06-24 14:32:36 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainMigratePerform3ParamsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-05-18 08:11:07 +00:00
|
|
|
if (flags & VIR_MIGRATE_PEER2PEER)
|
2016-06-24 14:32:36 +00:00
|
|
|
ret = vzDomainMigratePerformP2P(dom, privconn->driver, dconnuri,
|
|
|
|
params, nparams, flags);
|
2016-05-18 08:11:07 +00:00
|
|
|
else
|
2016-06-24 14:32:36 +00:00
|
|
|
ret = vzDomainMigratePerformStep(dom, privconn->driver, params, nparams,
|
|
|
|
cookiein, cookieinlen, flags);
|
2016-05-18 08:11:07 +00:00
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
cleanup:
|
2016-06-24 14:32:36 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
2016-05-18 08:11:07 +00:00
|
|
|
}
|
|
|
|
|
2016-05-18 08:11:06 +00:00
|
|
|
static virDomainPtr
|
|
|
|
vzDomainMigrateFinish3Params(virConnectPtr dconn,
|
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
2019-10-14 12:45:33 +00:00
|
|
|
const char *cookiein G_GNUC_UNUSED,
|
|
|
|
int cookieinlen G_GNUC_UNUSED,
|
|
|
|
char **cookieout G_GNUC_UNUSED,
|
|
|
|
int *cookieoutlen G_GNUC_UNUSED,
|
2016-05-18 08:11:06 +00:00
|
|
|
unsigned int flags,
|
|
|
|
int cancelled)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
virDomainPtr domain = NULL;
|
|
|
|
vzConnPtr privconn = dconn->privateData;
|
|
|
|
vzDriverPtr driver = privconn->driver;
|
|
|
|
const char *name = NULL;
|
|
|
|
|
|
|
|
virCheckFlags(VZ_MIGRATION_FLAGS, NULL);
|
|
|
|
|
|
|
|
if (virTypedParamsValidate(params, nparams, VZ_MIGRATION_PARAMETERS) < 0)
|
2016-06-08 07:17:22 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (cancelled)
|
|
|
|
return NULL;
|
2016-05-18 08:11:06 +00:00
|
|
|
|
|
|
|
if (virTypedParamsGetString(params, nparams,
|
|
|
|
VIR_MIGRATE_PARAM_DEST_NAME, &name) < 0)
|
2016-06-08 07:17:22 +00:00
|
|
|
return NULL;
|
2016-05-18 08:11:06 +00:00
|
|
|
|
|
|
|
|
2016-06-14 08:45:57 +00:00
|
|
|
if (!(dom = prlsdkAddDomainByName(driver, name)))
|
2016-05-18 08:11:06 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
/* At first glace at may look strange that we add domain and
|
|
|
|
* then check ACL but we touch only cache and not real system state */
|
|
|
|
if (virDomainMigrateFinish3ParamsEnsureACL(dconn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2017-03-28 15:08:03 +00:00
|
|
|
domain = virGetDomain(dconn, dom->def->name, dom->def->uuid, dom->def->id);
|
2016-05-18 08:11:06 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
/* In this situation we have to restore domain on source. But the migration
|
|
|
|
* is already finished. */
|
2016-06-08 07:17:22 +00:00
|
|
|
if (!domain)
|
2018-12-04 17:08:14 +00:00
|
|
|
VIR_WARN("Can't provide domain '%s' after successful migration.", name);
|
vz: make vz driver more responsive
Current vz driver implementation is not usable when it comes to
long runnig operations. Migration or saving a domain blocks all
other operations even query ones which are expecteted to be available.
This patch addresses this problem.
All vz driver API calls fall into next 3 groups:
1. only query domain cache (virDomainObj, vz cache statistic)
examples are vzDomainGetState, vzDomainGetXMLDesc etc.
2. use thread shared sdkdom object
examples are vzDomainSetMemoryFlags, vzDomainAttachDevice etc.
3. use no thread shared sdkdom object nor domain cache
examples are vzDomainSnapshotListNames, vzDomainSnapshotGetXMLDesc etc
API calls from group 1 don't need to be changed as they hold domain lock only
for short period of time. These calls [1] are easily distinguished. They query
domain object thru libvirt common code or query vz sdk statistics handle thru
vz sdk sync operations.
vzDomainInterfaceStats is the only exception. It uses sdkdom object to
convert interface name to its vz sdk stack index which could not be saved in
domain cache. Interface statistics is available thru this stack index as a key
rather than name. As a result we can have accidental 'not known interface'
errors on quering intrerface stats. The reason is that in the process of
updating domain configuration we drop all devices and then recreate them again
in sdkdom object and domain lock can be dropped meanwhile (to remove networks
for existing bridged interfaces and(or) (re)create new ones). We can fix this
by changing the way we support bridged interfaces or by reordering operations
and changing bridged networks beforehand. Anyway this is better than moving
this API call into 2 group and making it an exclusive job.
As to API calls from group 2, first thread shared sdkdom object needs to be
explained. vz sdk has only one handle for a given domain, thus threads need
exclusive access to operate on it. These calls are fixed to drop and reacquire
domain lock on any lengthy operations - namely waiting the result of async vz
sdk operation. As lock is dropped we need to take extra reference to domain
object if it is not taken already as domain object can be deleted from list
while lock is dropped. As this operations use thread shared sdkdom object, the
simplest way to make calls from group 2 be consistent to each other is to make
them mutually exclusive. This is done by taking/releasing job condition thru
calling correspondent job routine. This approach makes group 1 and group
2 calls consistent to each other too. Not all calls of group 2 change the
domain cache but those that do update it thru prlsdkUpdateDomain which holds
the lock thoughout the update.
API calls from group [2] are easily distinguished too. They use
beginEdit/commit to change domain configuration (vzDomainSetMemoryFlags) or/and
update domain cache from sdkdom at the end of operation (vzDomainSuspend).
There is a known issue however. Frankly speaking it was introduced by ealier
patch '[PATCH 6/9] vz: cleanup loading domain code' from a different series.
The patch significantly reduced amount of time when the driver lock is held when
creating domain from API call or as a result of domain added event from vz sdk.
The problem is these two paths race on using thread shared sdkdom as we don't
have libvirt domain object and can not lock on it. However this don't
invalidates the patch as we can't use the former approach of preadding domain
into the list as we need name at least and name is not given by event. Anyway
i'm against adding half baked object into the list. Eventually this race can be
fixed by extra measures. As to current situation races with different
configurations are unlikely and race when adding domain thru vz driver and
simultaneous event from vz sdk is not dangerous as configuration is the same.
The last group [3] is API calls that need only sdkdom object to make vz sdk
call and don't change thread shared sdkdom object or domain cache in any way.
For now these are mostly domain snapshot API calls. The changes are similar to
those of group 2 - they add extra reference and drop/reacquire the lock on waiting
vz async call result. One can simply take the immutable sdkdom object from the
cache and drop the lock for the rest of operations but the chosen approach
makes implementation of these API calls somewhat similar to those of from group
2 and thus a bit futureproof. As calls of group 3 don't need vz driver
domain/vz sdk cache in any way, they are consistent with respect to API calls from
groups 1 and 3.
There is another exception. Calls to make-snapshot/revert-to-snapshot/migrate
are moved to group 2. That is they are made mutually exclusive. The reason
is that libvirt API supports control/query only for one job per domain and
these are jobs that are likely to be queried/aborted.
Appendix.
[1] API calls that only query domain cache.
(marked [*] are included for a different reason)
.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 */
.domainIsActive = vzDomainIsActive, /* 1.2.10 */
.domainIsUpdated = vzDomainIsUpdated, /* 1.2.21 */
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
.domainHasManagedSaveImage = vzDomainHasManagedSaveImage, /* 1.2.13 */
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.2.17 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.2.17 */
.domainInterfaceStats = vzDomainInterfaceStats, /* 1.2.17 */ [*]
.domainMemoryStats = vzDomainMemoryStats, /* 1.2.17 */
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
[2] API calls that use thread shared sdkdom object
(marked [*] are included for a different reason)
.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 */
.domainReboot = vzDomainReboot, /* 1.3.0 */
.domainDefineXML = vzDomainDefineXML, /* 0.10.0 */
.domainDefineXMLFlags = vzDomainDefineXMLFlags, /* 1.2.12 */ (update part)
.domainUndefine = vzDomainUndefine, /* 1.2.10 */
.domainAttachDevice = vzDomainAttachDevice, /* 1.2.15 */
.domainAttachDeviceFlags = vzDomainAttachDeviceFlags, /* 1.2.15 */
.domainDetachDevice = vzDomainDetachDevice, /* 1.2.15 */
.domainDetachDeviceFlags = vzDomainDetachDeviceFlags, /* 1.2.15 */
.domainSetUserPassword = vzDomainSetUserPassword, /* 1.3.6 */
.domainManagedSave = vzDomainManagedSave, /* 1.2.14 */
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */ [*]
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */ [*]
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */ [*]
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
prlsdkHandleVmConfigEvent
[3] API calls that do not use thread shared sdkdom object
.domainManagedSaveRemove = vzDomainManagedSaveRemove, /* 1.2.14 */
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
[4] Known issues.
1. accidental errors on getting network statistics
2. race with simultaneous use of thread shared domain object on paths
of adding domain thru API and adding domain on vz sdk domain added event.
2016-07-20 15:00:33 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-05-18 08:11:06 +00:00
|
|
|
return domain;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2019-10-14 12:45:33 +00:00
|
|
|
vzDomainMigrateConfirm3Params(virDomainPtr domain G_GNUC_UNUSED,
|
2016-05-18 08:11:06 +00:00
|
|
|
virTypedParameterPtr params,
|
|
|
|
int nparams,
|
2019-10-14 12:45:33 +00:00
|
|
|
const char *cookiein G_GNUC_UNUSED,
|
|
|
|
int cookieinlen G_GNUC_UNUSED,
|
2016-05-18 08:11:06 +00:00
|
|
|
unsigned int flags,
|
2019-10-14 12:45:33 +00:00
|
|
|
int cancelled G_GNUC_UNUSED)
|
2016-05-18 08:11:06 +00:00
|
|
|
{
|
|
|
|
virCheckFlags(VZ_MIGRATION_FLAGS, -1);
|
|
|
|
|
|
|
|
if (virTypedParamsValidate(params, nparams, VZ_MIGRATION_PARAMETERS) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-06-20 10:08:14 +00:00
|
|
|
static int
|
|
|
|
vzDomainGetJobInfoImpl(virDomainObjPtr dom, virDomainJobInfoPtr info)
|
|
|
|
{
|
|
|
|
vzDomObjPtr privdom = dom->privateData;
|
|
|
|
vzDomainJobObjPtr job = &privdom->job;
|
|
|
|
|
|
|
|
memset(info, 0, sizeof(*info));
|
|
|
|
|
|
|
|
if (!job->active || !job->hasProgress)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (vzDomainJobUpdateTime(job) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
info->type = VIR_DOMAIN_JOB_UNBOUNDED;
|
|
|
|
info->dataTotal = 100;
|
|
|
|
info->dataProcessed = job->progress;
|
|
|
|
info->dataRemaining = 100 - job->progress;
|
|
|
|
info->timeElapsed = job->elapsed;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainGetJobInfo(virDomainPtr domain, virDomainJobInfoPtr info)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
2016-06-24 14:32:38 +00:00
|
|
|
int ret = -1;
|
2016-06-20 10:08:14 +00:00
|
|
|
|
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainGetJobInfoEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-20 10:08:14 +00:00
|
|
|
ret = vzDomainGetJobInfoImpl(dom, info);
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-06-20 10:08:14 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-06-20 10:08:15 +00:00
|
|
|
static int
|
|
|
|
vzDomainJobInfoToParams(virDomainJobInfoPtr info,
|
|
|
|
int *type,
|
|
|
|
virTypedParameterPtr *params,
|
|
|
|
int *nparams)
|
|
|
|
{
|
|
|
|
virTypedParameterPtr par = NULL;
|
|
|
|
int maxpar = 0;
|
|
|
|
int npar = 0;
|
|
|
|
|
|
|
|
if (virTypedParamsAddULLong(&par, &npar, &maxpar,
|
|
|
|
VIR_DOMAIN_JOB_TIME_ELAPSED,
|
|
|
|
info->timeElapsed) < 0 ||
|
|
|
|
virTypedParamsAddULLong(&par, &npar, &maxpar,
|
|
|
|
VIR_DOMAIN_JOB_DATA_TOTAL,
|
|
|
|
info->dataTotal) < 0 ||
|
|
|
|
virTypedParamsAddULLong(&par, &npar, &maxpar,
|
|
|
|
VIR_DOMAIN_JOB_DATA_PROCESSED,
|
|
|
|
info->dataProcessed) < 0 ||
|
|
|
|
virTypedParamsAddULLong(&par, &npar, &maxpar,
|
|
|
|
VIR_DOMAIN_JOB_DATA_REMAINING,
|
|
|
|
info->dataRemaining) < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
|
|
|
|
*type = info->type;
|
|
|
|
*params = par;
|
|
|
|
*nparams = npar;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virTypedParamsFree(par, npar);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainGetJobStats(virDomainPtr domain,
|
|
|
|
int *type,
|
|
|
|
virTypedParameterPtr *params,
|
|
|
|
int *nparams,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainJobInfo info;
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
|
|
|
return -1;
|
|
|
|
|
2016-06-24 14:32:38 +00:00
|
|
|
if (virDomainGetJobStatsEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2016-06-20 10:08:15 +00:00
|
|
|
if (vzDomainGetJobInfoImpl(dom, &info) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (info.type == VIR_DOMAIN_JOB_NONE) {
|
|
|
|
*type = VIR_DOMAIN_JOB_NONE;
|
|
|
|
*params = NULL;
|
|
|
|
*nparams = 0;
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = vzDomainJobInfoToParams(&info, type, params, nparams);
|
|
|
|
|
|
|
|
cleanup:
|
2018-03-09 14:59:00 +00:00
|
|
|
virDomainObjEndAPI(&dom);
|
2016-06-20 10:08:15 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-11-03 12:09:47 +00:00
|
|
|
#define VZ_ADD_STAT_PARAM_UUL(group, field, counter) \
|
|
|
|
do { \
|
|
|
|
if (stat.field != -1) { \
|
|
|
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
|
|
|
|
group ".%zu." counter, i); \
|
|
|
|
if (virTypedParamsAddULLong(&record->params, \
|
|
|
|
&record->nparams, \
|
|
|
|
maxparams, \
|
|
|
|
param_name, \
|
|
|
|
stat.field) < 0) \
|
|
|
|
return -1; \
|
|
|
|
} \
|
2016-12-12 07:56:34 +00:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzDomainGetBlockStats(virDomainObjPtr dom,
|
|
|
|
virDomainStatsRecordPtr record,
|
|
|
|
int *maxparams)
|
|
|
|
{
|
|
|
|
vzDomObjPtr privdom = dom->privateData;
|
|
|
|
size_t i;
|
|
|
|
char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
|
|
|
|
|
|
|
|
if (virTypedParamsAddUInt(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
"block.count",
|
|
|
|
dom->def->ndisks) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
for (i = 0; i < dom->def->ndisks; i++) {
|
|
|
|
virDomainBlockStatsStruct stat;
|
|
|
|
virDomainDiskDefPtr disk = dom->def->disks[i];
|
|
|
|
|
|
|
|
if (prlsdkGetBlockStats(privdom->stats,
|
|
|
|
disk,
|
|
|
|
&stat,
|
|
|
|
IS_CT(dom->def)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
|
|
|
|
"block.%zu.name", i);
|
|
|
|
if (virTypedParamsAddString(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
param_name,
|
|
|
|
disk->dst) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (virStorageSourceIsLocalStorage(disk->src) && disk->src->path) {
|
|
|
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
|
|
|
|
"block.%zu.path", i);
|
|
|
|
if (virTypedParamsAddString(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
param_name,
|
|
|
|
disk->src->path) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
VZ_ADD_STAT_PARAM_UUL("block", rd_req, "rd.reqs");
|
|
|
|
VZ_ADD_STAT_PARAM_UUL("block", rd_bytes, "rd.bytes");
|
|
|
|
VZ_ADD_STAT_PARAM_UUL("block", wr_req, "wr.reqs");
|
|
|
|
VZ_ADD_STAT_PARAM_UUL("block", wr_bytes, "wr.bytes");
|
|
|
|
|
|
|
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
|
|
|
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
|
|
|
|
"block.%zu.capacity", i);
|
|
|
|
if (virTypedParamsAddULLong(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
param_name,
|
|
|
|
disk->src->capacity) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-12-12 07:56:35 +00:00
|
|
|
static int
|
|
|
|
vzDomainGetNetStats(virDomainObjPtr dom,
|
|
|
|
virDomainStatsRecordPtr record,
|
|
|
|
int *maxparams)
|
|
|
|
{
|
|
|
|
vzDomObjPtr privdom = dom->privateData;
|
|
|
|
size_t i;
|
|
|
|
char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
|
|
|
|
|
|
|
|
if (virTypedParamsAddUInt(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
"net.count",
|
|
|
|
dom->def->nnets) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
for (i = 0; i < dom->def->nnets; i++) {
|
|
|
|
virDomainInterfaceStatsStruct stat;
|
|
|
|
virDomainNetDefPtr net = dom->def->nets[i];
|
|
|
|
|
|
|
|
if (prlsdkGetNetStats(privdom->stats, privdom->sdkdom, net->ifname,
|
|
|
|
&stat) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "net.%zu.name", i);
|
|
|
|
if (virTypedParamsAddString(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
param_name,
|
|
|
|
net->ifname) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
VZ_ADD_STAT_PARAM_UUL("net", rx_bytes, "rx.bytes");
|
|
|
|
VZ_ADD_STAT_PARAM_UUL("net", rx_packets, "rx.pkts");
|
|
|
|
VZ_ADD_STAT_PARAM_UUL("net", tx_bytes, "tx.bytes");
|
|
|
|
VZ_ADD_STAT_PARAM_UUL("net", tx_packets, "tx.pkts");
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-12-12 07:56:36 +00:00
|
|
|
static int
|
|
|
|
vzDomainGetVCPUStats(virDomainObjPtr dom,
|
|
|
|
virDomainStatsRecordPtr record,
|
|
|
|
int *maxparams)
|
|
|
|
{
|
|
|
|
vzDomObjPtr privdom = dom->privateData;
|
|
|
|
size_t i;
|
|
|
|
char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
|
|
|
|
|
|
|
|
if (virTypedParamsAddUInt(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
"vcpu.current",
|
|
|
|
virDomainDefGetVcpus(dom->def)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (virTypedParamsAddUInt(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
"vcpu.maximum",
|
|
|
|
virDomainDefGetVcpusMax(dom->def)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
for (i = 0; i < virDomainDefGetVcpusMax(dom->def); i++) {
|
|
|
|
int state = dom->def->vcpus[i]->online ? VIR_VCPU_RUNNING :
|
|
|
|
VIR_VCPU_OFFLINE;
|
|
|
|
unsigned long long time;
|
|
|
|
|
|
|
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "vcpu.%zu.state", i);
|
|
|
|
if (virTypedParamsAddInt(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
param_name,
|
|
|
|
state) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (prlsdkGetVcpuStats(privdom->stats, i, &time) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "vcpu.%zu.time", i);
|
|
|
|
if (virTypedParamsAddULLong(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
param_name,
|
|
|
|
time) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-12-12 07:56:37 +00:00
|
|
|
static int
|
|
|
|
vzDomainGetBalloonStats(virDomainObjPtr dom,
|
|
|
|
virDomainStatsRecordPtr record,
|
|
|
|
int *maxparams)
|
|
|
|
{
|
|
|
|
vzDomObjPtr privdom = dom->privateData;
|
|
|
|
virDomainMemoryStatStruct stats[VIR_DOMAIN_MEMORY_STAT_NR];
|
|
|
|
size_t i;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
if (virTypedParamsAddULLong(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
"balloon.maximum",
|
|
|
|
virDomainDefGetMemoryTotal(dom->def)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (virTypedParamsAddULLong(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
"balloon.current",
|
|
|
|
virDomainDefGetMemoryTotal(dom->def)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
n = prlsdkGetMemoryStats(privdom->stats, stats, VIR_DOMAIN_MEMORY_STAT_NR);
|
|
|
|
if (n < 0)
|
|
|
|
return -1;
|
|
|
|
|
2017-11-03 12:09:47 +00:00
|
|
|
#define STORE_MEM_RECORD(TAG, NAME) \
|
|
|
|
if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_ ##TAG) \
|
|
|
|
if (virTypedParamsAddULLong(&record->params, \
|
|
|
|
&record->nparams, \
|
|
|
|
maxparams, \
|
|
|
|
"balloon." NAME, \
|
|
|
|
stats[i].val) < 0) \
|
2016-12-12 07:56:37 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
STORE_MEM_RECORD(SWAP_IN, "swap_in")
|
|
|
|
STORE_MEM_RECORD(SWAP_OUT, "swap_out")
|
|
|
|
STORE_MEM_RECORD(MAJOR_FAULT, "major_fault")
|
|
|
|
STORE_MEM_RECORD(MINOR_FAULT, "minor_fault")
|
|
|
|
STORE_MEM_RECORD(AVAILABLE, "available")
|
|
|
|
STORE_MEM_RECORD(UNUSED, "unused")
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef STORE_MEM_RECORD
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-12-12 07:56:38 +00:00
|
|
|
static int
|
|
|
|
vzDomainGetStateStats(virDomainObjPtr dom,
|
|
|
|
virDomainStatsRecordPtr record,
|
|
|
|
int *maxparams)
|
|
|
|
{
|
|
|
|
if (virTypedParamsAddInt(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
"state.state",
|
|
|
|
dom->state.state) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (virTypedParamsAddInt(&record->params,
|
|
|
|
&record->nparams,
|
|
|
|
maxparams,
|
|
|
|
"state.reason",
|
|
|
|
dom->state.reason) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-12-12 07:56:34 +00:00
|
|
|
static virDomainStatsRecordPtr
|
|
|
|
vzDomainGetAllStats(virConnectPtr conn,
|
|
|
|
virDomainObjPtr dom)
|
|
|
|
{
|
|
|
|
virDomainStatsRecordPtr stat;
|
|
|
|
int maxparams = 0;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(stat) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
2016-12-12 07:56:38 +00:00
|
|
|
if (vzDomainGetStateStats(dom, stat, &maxparams) < 0)
|
|
|
|
goto error;
|
|
|
|
|
2016-12-12 07:56:34 +00:00
|
|
|
if (vzDomainGetBlockStats(dom, stat, &maxparams) < 0)
|
|
|
|
goto error;
|
2016-12-12 07:56:35 +00:00
|
|
|
|
|
|
|
if (vzDomainGetNetStats(dom, stat, &maxparams) < 0)
|
|
|
|
goto error;
|
2016-12-12 07:56:36 +00:00
|
|
|
|
|
|
|
if (vzDomainGetVCPUStats(dom, stat, &maxparams) < 0)
|
|
|
|
goto error;
|
2016-12-12 07:56:37 +00:00
|
|
|
|
|
|
|
if (vzDomainGetBalloonStats(dom, stat, &maxparams) < 0)
|
|
|
|
goto error;
|
2016-12-12 07:56:34 +00:00
|
|
|
|
2017-03-28 15:08:03 +00:00
|
|
|
if (!(stat->dom = virGetDomain(conn, dom->def->name, dom->def->uuid, dom->def->id)))
|
2016-12-12 07:56:34 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
return stat;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virTypedParamsFree(stat->params, stat->nparams);
|
|
|
|
virObjectUnref(stat->dom);
|
|
|
|
VIR_FREE(stat);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vzConnectGetAllDomainStats(virConnectPtr conn,
|
|
|
|
virDomainPtr *domains,
|
|
|
|
unsigned int ndomains,
|
|
|
|
unsigned int stats,
|
|
|
|
virDomainStatsRecordPtr **retStats,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
vzConnPtr privconn = conn->privateData;
|
|
|
|
vzDriverPtr driver = privconn->driver;
|
|
|
|
unsigned int lflags = flags & (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
|
|
|
|
VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
|
|
|
|
VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE);
|
|
|
|
unsigned int supported = VIR_DOMAIN_STATS_STATE |
|
|
|
|
VIR_DOMAIN_STATS_VCPU |
|
|
|
|
VIR_DOMAIN_STATS_INTERFACE |
|
|
|
|
VIR_DOMAIN_STATS_BALLOON |
|
|
|
|
VIR_DOMAIN_STATS_BLOCK;
|
|
|
|
virDomainObjPtr *doms = NULL;
|
|
|
|
size_t ndoms;
|
|
|
|
virDomainStatsRecordPtr *tmpstats = NULL;
|
|
|
|
int nstats = 0;
|
|
|
|
int ret = -1;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
|
|
|
|
VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
|
|
|
|
VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE |
|
|
|
|
VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS, -1);
|
|
|
|
|
|
|
|
if (virConnectGetAllDomainStatsEnsureACL(conn) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!stats) {
|
|
|
|
stats = supported;
|
|
|
|
} else if ((flags & VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS) &&
|
|
|
|
(stats & ~supported)) {
|
|
|
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
|
|
|
|
_("Stats types bits 0x%x are not supported by this daemon"),
|
|
|
|
stats & ~supported);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ndomains) {
|
|
|
|
if (virDomainObjListConvert(driver->domains, conn, domains, ndomains, &doms,
|
|
|
|
&ndoms, virConnectGetAllDomainStatsCheckACL,
|
|
|
|
lflags, true) < 0)
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
if (virDomainObjListCollect(driver->domains, conn, &doms, &ndoms,
|
|
|
|
virConnectGetAllDomainStatsCheckACL,
|
|
|
|
lflags) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(tmpstats, ndoms + 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < ndoms; i++) {
|
|
|
|
virDomainStatsRecordPtr tmp;
|
|
|
|
virDomainObjPtr dom = doms[i];
|
|
|
|
|
|
|
|
virObjectLock(dom);
|
|
|
|
tmp = vzDomainGetAllStats(conn, dom);
|
|
|
|
virObjectUnlock(dom);
|
|
|
|
|
|
|
|
if (!tmp)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
tmpstats[nstats++] = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
*retStats = tmpstats;
|
|
|
|
tmpstats = NULL;
|
|
|
|
ret = nstats;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainStatsRecordListFree(tmpstats);
|
|
|
|
virObjectListFreeCount(doms, ndoms);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef VZ_ADD_STAT_PARAM_UUL
|
|
|
|
|
2017-01-31 07:44:12 +00:00
|
|
|
static int
|
|
|
|
vzDomainAbortJob(virDomainPtr domain)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom;
|
|
|
|
int ret = -1;
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2017-01-31 07:44:12 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (virDomainAbortJobEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = prlsdkCancelJob(dom);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-01-31 07:44:13 +00:00
|
|
|
static int
|
|
|
|
vzDomainReset(virDomainPtr domain, unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2017-01-31 07:44:13 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (virDomainResetEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = prlsdkReset(dom);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-04-14 14:53:52 +00:00
|
|
|
static int vzDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2017-04-14 14:53:52 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (vzCheckConfigUpdateFlags(dom, &flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virDomainSetVcpusFlagsEnsureACL(domain->conn, dom->def, flags) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = prlsdkSetCpuCount(dom, nvcpus);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vzDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
|
|
|
|
{
|
|
|
|
return vzDomainSetVcpusFlags(dom, nvcpus,
|
|
|
|
VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG);
|
|
|
|
}
|
2017-04-14 14:53:53 +00:00
|
|
|
static int
|
|
|
|
vzDomainBlockResize(virDomainPtr domain,
|
|
|
|
const char *path,
|
|
|
|
unsigned long long size,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainObjPtr dom = NULL;
|
|
|
|
virDomainDiskDefPtr disk = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
bool job = false;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_DOMAIN_BLOCK_RESIZE_BYTES, -1);
|
|
|
|
|
2018-03-09 14:59:00 +00:00
|
|
|
if (!(dom = vzDomObjFromDomain(domain)))
|
2017-04-14 14:53:53 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virDomainBlockResizeEnsureACL(domain->conn, dom->def) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (path[0] == '\0') {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
"%s", _("empty path"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* sdk wants Mb */
|
|
|
|
if (flags & VIR_DOMAIN_BLOCK_RESIZE_BYTES)
|
|
|
|
size /= 1024;
|
|
|
|
size /= 1024;
|
|
|
|
|
|
|
|
if (vzDomainObjBeginJob(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
job = true;
|
|
|
|
|
|
|
|
if (vzEnsureDomainExists(dom) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2018-04-17 22:13:34 +00:00
|
|
|
if (virDomainObjCheckActive(dom) < 0)
|
2017-04-14 14:53:53 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2017-05-03 10:44:51 +00:00
|
|
|
if (!(disk = virDomainDiskByName(dom->def, path, false))) {
|
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("invalid path: %s"), path);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2017-04-14 14:53:53 +00:00
|
|
|
ret = prlsdkResizeImage(dom, disk, size);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (job)
|
|
|
|
vzDomainObjEndJob(dom);
|
|
|
|
virDomainObjEndAPI(&dom);
|
|
|
|
return ret;
|
|
|
|
}
|
2017-04-14 14:53:52 +00:00
|
|
|
|
2016-04-06 08:06:18 +00:00
|
|
|
static virHypervisorDriver vzHypervisorDriver = {
|
2015-05-26 17:12:00 +00:00
|
|
|
.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 */
|
2016-04-07 18:52:43 +00:00
|
|
|
.connectGetSysinfo = vzConnectGetSysinfo, /* 1.3.4 */
|
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 */
|
2016-06-24 14:32:34 +00:00
|
|
|
.domainDestroyFlags = vzDomainDestroyFlags, /* 2.2.0 */
|
2015-06-10 07:50:00 +00:00
|
|
|
.domainShutdown = vzDomainShutdown, /* 0.10.0 */
|
2016-06-24 14:32:34 +00:00
|
|
|
.domainShutdownFlags = vzDomainShutdownFlags, /* 2.2.0 */
|
2015-06-10 07:50:00 +00:00
|
|
|
.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 */
|
2017-04-14 14:53:52 +00:00
|
|
|
.domainSetVcpus = vzDomainSetVcpus, /* 3.3.0 */
|
|
|
|
.domainSetVcpusFlags = vzDomainSetVcpusFlags, /* 3.3.0 */
|
2015-10-19 19:02:00 +00:00
|
|
|
.domainGetVcpusFlags = vzDomainGetVcpusFlags, /* 1.2.21 */
|
|
|
|
.domainGetMaxVcpus = vzDomainGetMaxVcpus, /* 1.2.21 */
|
2016-06-14 09:15:18 +00:00
|
|
|
.domainSetUserPassword = vzDomainSetUserPassword, /* 2.0.0 */
|
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 */
|
2016-02-17 12:15:03 +00:00
|
|
|
.connectRegisterCloseCallback = vzConnectRegisterCloseCallback, /* 1.3.2 */
|
|
|
|
.connectUnregisterCloseCallback = vzConnectUnregisterCloseCallback, /* 1.3.2 */
|
2016-04-08 09:36:45 +00:00
|
|
|
.domainSetMemoryFlags = vzDomainSetMemoryFlags, /* 1.3.4 */
|
|
|
|
.domainSetMemory = vzDomainSetMemory, /* 1.3.4 */
|
2016-05-02 09:33:07 +00:00
|
|
|
.domainSnapshotNum = vzDomainSnapshotNum, /* 1.3.5 */
|
|
|
|
.domainSnapshotListNames = vzDomainSnapshotListNames, /* 1.3.5 */
|
|
|
|
.domainListAllSnapshots = vzDomainListAllSnapshots, /* 1.3.5 */
|
|
|
|
.domainSnapshotGetXMLDesc = vzDomainSnapshotGetXMLDesc, /* 1.3.5 */
|
|
|
|
.domainSnapshotNumChildren = vzDomainSnapshotNumChildren, /* 1.3.5 */
|
|
|
|
.domainSnapshotListChildrenNames = vzDomainSnapshotListChildrenNames, /* 1.3.5 */
|
|
|
|
.domainSnapshotListAllChildren = vzDomainSnapshotListAllChildren, /* 1.3.5 */
|
|
|
|
.domainSnapshotLookupByName = vzDomainSnapshotLookupByName, /* 1.3.5 */
|
|
|
|
.domainHasCurrentSnapshot = vzDomainHasCurrentSnapshot, /* 1.3.5 */
|
|
|
|
.domainSnapshotGetParent = vzDomainSnapshotGetParent, /* 1.3.5 */
|
|
|
|
.domainSnapshotCurrent = vzDomainSnapshotCurrent, /* 1.3.5 */
|
|
|
|
.domainSnapshotIsCurrent = vzDomainSnapshotIsCurrent, /* 1.3.5 */
|
|
|
|
.domainSnapshotHasMetadata = vzDomainSnapshotHasMetadata, /* 1.3.5 */
|
|
|
|
.domainSnapshotCreateXML = vzDomainSnapshotCreateXML, /* 1.3.5 */
|
|
|
|
.domainSnapshotDelete = vzDomainSnapshotDelete, /* 1.3.5 */
|
|
|
|
.domainRevertToSnapshot = vzDomainRevertToSnapshot, /* 1.3.5 */
|
2016-05-18 08:11:06 +00:00
|
|
|
.connectSupportsFeature = vzConnectSupportsFeature, /* 1.3.5 */
|
|
|
|
.domainMigrateBegin3Params = vzDomainMigrateBegin3Params, /* 1.3.5 */
|
|
|
|
.domainMigratePrepare3Params = vzDomainMigratePrepare3Params, /* 1.3.5 */
|
|
|
|
.domainMigratePerform3Params = vzDomainMigratePerform3Params, /* 1.3.5 */
|
|
|
|
.domainMigrateFinish3Params = vzDomainMigrateFinish3Params, /* 1.3.5 */
|
|
|
|
.domainMigrateConfirm3Params = vzDomainMigrateConfirm3Params, /* 1.3.5 */
|
2016-04-20 14:05:31 +00:00
|
|
|
.domainUpdateDeviceFlags = vzDomainUpdateDeviceFlags, /* 2.0.0 */
|
2016-06-20 10:08:14 +00:00
|
|
|
.domainGetJobInfo = vzDomainGetJobInfo, /* 2.2.0 */
|
2016-06-20 10:08:15 +00:00
|
|
|
.domainGetJobStats = vzDomainGetJobStats, /* 2.2.0 */
|
2016-12-12 07:56:34 +00:00
|
|
|
.connectGetAllDomainStats = vzConnectGetAllDomainStats, /* 3.1.0 */
|
2017-01-31 07:44:12 +00:00
|
|
|
.domainAbortJob = vzDomainAbortJob, /* 3.1.0 */
|
2017-01-31 07:44:13 +00:00
|
|
|
.domainReset = vzDomainReset, /* 3.1.0 */
|
2017-04-14 14:53:53 +00:00
|
|
|
.domainBlockResize = vzDomainBlockResize, /* 3.3.0 */
|
2012-07-31 18:56:05 +00:00
|
|
|
};
|
|
|
|
|
2015-05-26 17:12:00 +00:00
|
|
|
static virConnectDriver vzConnectDriver = {
|
2018-03-28 09:53:31 +00:00
|
|
|
.localOnly = true,
|
2018-03-27 14:51:45 +00:00
|
|
|
.uriSchemes = (const char *[]){ "vz", NULL },
|
2016-04-06 08:06:18 +00:00
|
|
|
.hypervisorDriver = &vzHypervisorDriver,
|
2015-01-20 16:16:26 +00:00
|
|
|
};
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
static int
|
|
|
|
vzStateCleanup(void)
|
|
|
|
{
|
2019-05-23 10:34:08 +00:00
|
|
|
if (vz_driver_privileged) {
|
|
|
|
virObjectUnref(vz_driver);
|
|
|
|
vz_driver = NULL;
|
|
|
|
if (vz_driver_lock_fd != -1)
|
|
|
|
virPidFileRelease(VZ_STATEDIR, "driver", vz_driver_lock_fd);
|
|
|
|
virMutexDestroy(&vz_driver_lock);
|
|
|
|
prlsdkDeinit();
|
|
|
|
}
|
2016-03-28 19:11:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2019-05-23 10:34:08 +00:00
|
|
|
vzStateInitialize(bool privileged,
|
2019-10-14 12:45:33 +00:00
|
|
|
virStateInhibitCallback callback G_GNUC_UNUSED,
|
|
|
|
void *opaque G_GNUC_UNUSED)
|
2016-03-28 19:11:30 +00:00
|
|
|
{
|
2019-05-23 10:34:08 +00:00
|
|
|
if (!privileged)
|
2019-07-23 12:05:18 +00:00
|
|
|
return VIR_DRV_STATE_INIT_SKIPPED;
|
2019-05-23 10:34:08 +00:00
|
|
|
|
|
|
|
vz_driver_privileged = privileged;
|
|
|
|
|
|
|
|
if (virFileMakePathWithMode(VZ_STATEDIR, S_IRWXU) < 0) {
|
|
|
|
virReportSystemError(errno, _("cannot create state directory '%s'"),
|
|
|
|
VZ_STATEDIR);
|
2019-07-23 12:05:18 +00:00
|
|
|
return VIR_DRV_STATE_INIT_ERROR;
|
2019-05-23 10:34:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((vz_driver_lock_fd =
|
2019-07-11 14:57:34 +00:00
|
|
|
virPidFileAcquire(VZ_STATEDIR, "driver", false, getpid())) < 0)
|
2019-07-23 12:05:18 +00:00
|
|
|
return VIR_DRV_STATE_INIT_ERROR;
|
2019-05-23 10:34:08 +00:00
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
if (prlsdkInit() < 0) {
|
|
|
|
VIR_DEBUG("%s", _("Can't initialize Parallels SDK"));
|
2019-07-23 12:05:18 +00:00
|
|
|
return VIR_DRV_STATE_INIT_ERROR;
|
2016-03-28 19:11:30 +00:00
|
|
|
}
|
|
|
|
|
2019-07-23 12:05:18 +00:00
|
|
|
if (virMutexInit(&vz_driver_lock) < 0)
|
2016-03-28 19:11:30 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
/* Failing to create driver here is not fatal and only means
|
|
|
|
* that next driver client will try once more when connecting */
|
|
|
|
vz_driver = vzDriverObjNew();
|
2019-07-23 12:05:18 +00:00
|
|
|
return VIR_DRV_STATE_INIT_COMPLETE;
|
2016-03-28 19:11:30 +00:00
|
|
|
|
|
|
|
error:
|
|
|
|
vzStateCleanup();
|
2019-07-23 12:05:18 +00:00
|
|
|
return VIR_DRV_STATE_INIT_ERROR;
|
2016-03-28 19:11:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static virStateDriver vzStateDriver = {
|
|
|
|
.name = "vz",
|
|
|
|
.stateInitialize = vzStateInitialize,
|
|
|
|
.stateCleanup = vzStateCleanup,
|
|
|
|
};
|
|
|
|
|
2015-05-26 17:12:00 +00:00
|
|
|
/* Parallels domain type backward compatibility*/
|
2016-04-06 08:06:18 +00:00
|
|
|
static virHypervisorDriver parallelsHypervisorDriver;
|
2018-04-18 13:37:27 +00:00
|
|
|
static virConnectDriver parallelsConnectDriver = {
|
|
|
|
.localOnly = true,
|
|
|
|
.uriSchemes = (const char *[]){ "parallels", NULL },
|
|
|
|
.hypervisorDriver = ¶llelsHypervisorDriver,
|
|
|
|
};
|
2015-05-26 17:12:00 +00:00
|
|
|
|
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 */
|
2016-04-06 08:06:18 +00:00
|
|
|
parallelsHypervisorDriver = vzHypervisorDriver;
|
|
|
|
parallelsHypervisorDriver.name = "Parallels";
|
2016-04-14 14:52:32 +00:00
|
|
|
if (virRegisterConnectDriver(¶llelsConnectDriver, true) < 0)
|
2012-12-11 10:59:45 +00:00
|
|
|
return -1;
|
2012-07-31 18:56:05 +00:00
|
|
|
|
2016-04-14 14:52:32 +00:00
|
|
|
if (virRegisterConnectDriver(&vzConnectDriver, true) < 0)
|
2015-05-26 17:12:00 +00:00
|
|
|
return -1;
|
|
|
|
|
2016-03-28 19:11:30 +00:00
|
|
|
if (virRegisterStateDriver(&vzStateDriver) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2012-07-31 18:56:05 +00:00
|
|
|
return 0;
|
|
|
|
}
|