/*
* qemu_domain.c: QEMU domain private state
*
* Copyright (C) 2006-2019 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* .
*/
#include
#include "qemu_domain.h"
#include "qemu_alias.h"
#include "qemu_block.h"
#include "qemu_cgroup.h"
#include "qemu_command.h"
#include "qemu_process.h"
#include "qemu_capabilities.h"
#include "qemu_hostdev.h"
#include "qemu_migration.h"
#include "qemu_migration_params.h"
#include "qemu_security.h"
#include "qemu_slirp.h"
#include "qemu_extdevice.h"
#include "qemu_blockjob.h"
#include "qemu_checkpoint.h"
#include "qemu_validate.h"
#include "qemu_namespace.h"
#include "viralloc.h"
#include "virlog.h"
#include "virerror.h"
#include "cpu/cpu.h"
#include "viruuid.h"
#include "virfile.h"
#include "domain_addr.h"
#include "domain_capabilities.h"
#include "domain_driver.h"
#include "domain_event.h"
#include "domain_validate.h"
#include "virtime.h"
#include "virnetdevopenvswitch.h"
#include "virstoragefile.h"
#include "virstring.h"
#include "virthreadjob.h"
#include "virprocess.h"
#include "vircrypto.h"
#include "virrandom.h"
#include "virsystemd.h"
#include "virsecret.h"
#include "logging/log_manager.h"
#include "locking/domain_lock.h"
#include "virdomainsnapshotobjlist.h"
#include "virdomaincheckpointobjlist.h"
#include "backup_conf.h"
#include "virutil.h"
#include "virqemu.h"
#include
#include
#define QEMU_QXL_VGAMEM_DEFAULT 16 * 1024
#define VIR_FROM_THIS VIR_FROM_QEMU
VIR_LOG_INIT("qemu.qemu_domain");
static void *
qemuJobAllocPrivate(void)
{
return g_new0(qemuDomainJobPrivate, 1);
}
static void
qemuJobFreePrivate(void *opaque)
{
qemuDomainJobPrivatePtr priv = opaque;
if (!priv)
return;
qemuMigrationParamsFree(priv->migParams);
VIR_FREE(priv);
}
static void
qemuJobResetPrivate(void *opaque)
{
qemuDomainJobPrivatePtr priv = opaque;
priv->spiceMigration = false;
priv->spiceMigrated = false;
priv->dumpCompleted = false;
qemuMigrationParamsFree(priv->migParams);
priv->migParams = NULL;
}
static int
qemuDomainObjPrivateXMLFormatNBDMigrationSource(virBufferPtr buf,
virStorageSourcePtr src,
virDomainXMLOptionPtr xmlopt)
{
g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
virBufferAsprintf(&attrBuf, " type='%s' format='%s'",
virStorageTypeToString(src->type),
virStorageFileFormatTypeToString(src->format));
if (virDomainDiskSourceFormat(&childBuf, src, "source", 0, false,
VIR_DOMAIN_DEF_FORMAT_STATUS,
false, false, xmlopt) < 0)
return -1;
virXMLFormatElement(buf, "migrationSource", &attrBuf, &childBuf);
return 0;
}
static int
qemuDomainObjPrivateXMLFormatNBDMigration(virBufferPtr buf,
virDomainObjPtr vm)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
size_t i;
virDomainDiskDefPtr disk;
qemuDomainDiskPrivatePtr diskPriv;
for (i = 0; i < vm->def->ndisks; i++) {
g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
disk = vm->def->disks[i];
diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
virBufferAsprintf(&attrBuf, " dev='%s' migrating='%s'",
disk->dst, diskPriv->migrating ? "yes" : "no");
if (diskPriv->migrSource &&
qemuDomainObjPrivateXMLFormatNBDMigrationSource(&childBuf,
diskPriv->migrSource,
priv->driver->xmlopt) < 0)
return -1;
virXMLFormatElement(buf, "disk", &attrBuf, &childBuf);
}
return 0;
}
static int
qemuDomainFormatJobPrivate(virBufferPtr buf,
qemuDomainJobObjPtr job,
virDomainObjPtr vm)
{
qemuDomainJobPrivatePtr priv = job->privateData;
if (job->asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT &&
qemuDomainObjPrivateXMLFormatNBDMigration(buf, vm) < 0)
return -1;
if (priv->migParams)
qemuMigrationParamsFormat(buf, priv->migParams);
return 0;
}
static int
qemuDomainObjPrivateXMLParseJobNBDSource(xmlNodePtr node,
xmlXPathContextPtr ctxt,
virDomainDiskDefPtr disk,
virDomainXMLOptionPtr xmlopt)
{
VIR_XPATH_NODE_AUTORESTORE(ctxt)
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
g_autofree char *format = NULL;
g_autofree char *type = NULL;
g_autoptr(virStorageSource) migrSource = NULL;
xmlNodePtr sourceNode;
ctxt->node = node;
if (!(ctxt->node = virXPathNode("./migrationSource", ctxt)))
return 0;
if (!(type = virXMLPropString(ctxt->node, "type"))) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing storage source type"));
return -1;
}
if (!(format = virXMLPropString(ctxt->node, "format"))) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing storage source format"));
return -1;
}
if (!(migrSource = virDomainStorageSourceParseBase(type, format, NULL)))
return -1;
/* newer libvirt uses the