2
* qemu_driver.c: core driver methods for managing qemu guests
4
* Copyright (C) 2006-2011 Red Hat, Inc.
5
* Copyright (C) 2006 Daniel P. Berrange
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
* Author: Daniel P. Berrange <berrange@redhat.com>
26
#include <sys/types.h>
37
#include <sys/utsname.h>
44
#include <sys/ioctl.h>
49
#include "qemu_driver.h"
50
#include "qemu_conf.h"
51
#include "qemu_capabilities.h"
52
#include "qemu_command.h"
53
#include "qemu_cgroup.h"
54
#include "qemu_hostdev.h"
55
#include "qemu_hotplug.h"
56
#include "qemu_monitor.h"
57
#include "qemu_bridge_filter.h"
58
#include "qemu_process.h"
59
#include "qemu_migration.h"
61
#include "virterror_internal.h"
63
#include "datatypes.h"
67
#include "stats_linux.h"
68
#include "capabilities.h"
71
#include "domain_conf.h"
72
#include "domain_audit.h"
73
#include "node_device_conf.h"
76
#include "processinfo.h"
77
#include "libvirt_internal.h"
81
#include "domain_nwfilter.h"
83
#include "storage_file.h"
86
#include "configmake.h"
87
#include "threadpool.h"
88
#include "locking/lock_manager.h"
89
#include "locking/domain_lock.h"
90
#include "virkeycode.h"
91
#include "virnodesuspend.h"
94
#define VIR_FROM_THIS VIR_FROM_QEMU
96
#define QEMU_NB_MEM_PARAM 3
98
#define QEMU_NB_BLOCK_IO_TUNE_PARAM 6
101
# include <linux/kvm.h>
104
/* device for kvm ioctls */
105
#define KVM_DEVICE "/dev/kvm"
107
/* add definitions missing in older linux/kvm.h */
111
#ifndef KVM_CHECK_EXTENSION
112
# define KVM_CHECK_EXTENSION _IO(KVMIO, 0x03)
114
#ifndef KVM_CAP_NR_VCPUS
115
# define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */
118
#define QEMU_NB_BLKIO_PARAM 2
120
static void processWatchdogEvent(void *data, void *opaque);
122
static int qemudShutdown(void);
124
static int qemuDomainObjStart(virConnectPtr conn,
125
struct qemud_driver *driver,
129
static int qemudDomainGetMaxVcpus(virDomainPtr dom);
131
struct qemud_driver *qemu_driver = NULL;
134
struct qemuAutostartData {
135
struct qemud_driver *driver;
140
qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED,
143
virDomainObjPtr vm = payload;
144
struct qemuAutostartData *data = opaque;
148
if (data->driver->autoStartBypassCache)
149
flags |= VIR_DOMAIN_START_BYPASS_CACHE;
151
virDomainObjLock(vm);
154
!virDomainObjIsActive(vm)) {
155
if (qemuDomainObjBeginJobWithDriver(data->driver, vm,
156
QEMU_JOB_MODIFY) < 0) {
157
err = virGetLastError();
158
VIR_ERROR(_("Failed to start job on VM '%s': %s"),
160
err ? err->message : _("unknown error"));
164
if (qemuDomainObjStart(data->conn, data->driver, vm, flags) < 0) {
165
err = virGetLastError();
166
VIR_ERROR(_("Failed to autostart VM '%s': %s"),
168
err ? err->message : _("unknown error"));
171
if (qemuDomainObjEndJob(data->driver, vm) == 0)
177
virDomainObjUnlock(vm);
182
qemuAutostartDomains(struct qemud_driver *driver)
184
/* XXX: Figure out a better way todo this. The domain
185
* startup code needs a connection handle in order
186
* to lookup the bridge associated with a virtual
189
virConnectPtr conn = virConnectOpen(driver->privileged ?
192
/* Ignoring NULL conn which is mostly harmless here */
193
struct qemuAutostartData data = { driver, conn };
195
qemuDriverLock(driver);
196
virHashForEach(driver->domains.objs, qemuAutostartDomain, &data);
197
qemuDriverUnlock(driver);
200
virConnectClose(conn);
204
qemuSecurityInit(struct qemud_driver *driver)
206
virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName,
207
driver->allowDiskFormatProbing);
211
if (driver->privileged) {
212
virSecurityManagerPtr dac = virSecurityManagerNewDAC(driver->user,
214
driver->allowDiskFormatProbing,
215
driver->dynamicOwnership);
219
if (!(driver->securityManager = virSecurityManagerNewStack(mgr,
222
virSecurityManagerFree(dac);
226
driver->securityManager = mgr;
232
VIR_ERROR(_("Failed to initialize security drivers"));
233
virSecurityManagerFree(mgr);
239
qemuCreateCapabilities(virCapsPtr oldcaps,
240
struct qemud_driver *driver)
244
/* Basic host arch / guest machine capabilities */
245
if (!(caps = qemuCapsInit(oldcaps))) {
250
if (driver->allowDiskFormatProbing) {
251
caps->defaultDiskDriverName = NULL;
252
caps->defaultDiskDriverType = NULL;
254
caps->defaultDiskDriverName = "qemu";
255
caps->defaultDiskDriverType = "raw";
258
qemuDomainSetPrivateDataHooks(caps);
259
qemuDomainSetNamespaceHooks(caps);
261
if (virGetHostUUID(caps->host.host_uuid)) {
262
qemuReportError(VIR_ERR_INTERNAL_ERROR,
263
"%s", _("cannot get the host uuid"));
267
/* Security driver data */
268
const char *doi, *model;
270
doi = virSecurityManagerGetDOI(driver->securityManager);
271
model = virSecurityManagerGetModel(driver->securityManager);
272
if (STRNEQ(model, "none")) {
273
if (!(caps->host.secModel.model = strdup(model)))
275
if (!(caps->host.secModel.doi = strdup(doi)))
279
VIR_DEBUG("Initialized caps for security driver \"%s\" with "
280
"DOI \"%s\"", model, doi);
287
virCapabilitiesFree(caps);
291
static void qemuDomainSnapshotLoad(void *payload,
292
const void *name ATTRIBUTE_UNUSED,
295
virDomainObjPtr vm = (virDomainObjPtr)payload;
296
char *baseDir = (char *)data;
297
char *snapDir = NULL;
299
struct dirent *entry;
303
virDomainSnapshotDefPtr def = NULL;
304
virDomainSnapshotObjPtr snap = NULL;
305
virDomainSnapshotObjPtr current = NULL;
307
unsigned int flags = (VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE |
308
VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
309
VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL);
311
virDomainObjLock(vm);
312
if (virAsprintf(&snapDir, "%s/%s", baseDir, vm->def->name) < 0) {
313
VIR_ERROR(_("Failed to allocate memory for snapshot directory for domain %s"),
318
VIR_INFO("Scanning for snapshots for domain %s in %s", vm->def->name,
321
if (!(dir = opendir(snapDir))) {
323
VIR_ERROR(_("Failed to open snapshot directory %s for domain %s: %s"),
324
snapDir, vm->def->name,
325
virStrerror(errno, ebuf, sizeof(ebuf)));
329
while ((entry = readdir(dir))) {
330
if (entry->d_name[0] == '.')
333
/* NB: ignoring errors, so one malformed config doesn't
334
kill the whole process */
335
VIR_INFO("Loading snapshot file '%s'", entry->d_name);
337
if (virAsprintf(&fullpath, "%s/%s", snapDir, entry->d_name) < 0) {
338
VIR_ERROR(_("Failed to allocate memory for path"));
342
ret = virFileReadAll(fullpath, 1024*1024*1, &xmlStr);
344
/* Nothing we can do here, skip this one */
345
VIR_ERROR(_("Failed to read snapshot file %s: %s"), fullpath,
346
virStrerror(errno, ebuf, sizeof(ebuf)));
351
def = virDomainSnapshotDefParseString(xmlStr, qemu_driver->caps,
352
QEMU_EXPECTED_VIRT_TYPES,
355
/* Nothing we can do here, skip this one */
356
VIR_ERROR(_("Failed to parse snapshot XML from file '%s'"),
363
snap = virDomainSnapshotAssignDef(&vm->snapshots, def);
365
virDomainSnapshotDefFree(def);
366
} else if (snap->def->current) {
368
if (!vm->current_snapshot)
369
vm->current_snapshot = snap;
376
if (vm->current_snapshot != current) {
377
VIR_ERROR(_("Too many snapshots claiming to be current for domain %s"),
379
vm->current_snapshot = NULL;
382
if (virDomainSnapshotUpdateRelations(&vm->snapshots) < 0)
383
VIR_ERROR(_("Snapshots have inconsistent relations for domain %s"),
386
/* FIXME: qemu keeps internal track of snapshots. We can get access
387
* to this info via the "info snapshots" monitor command for running
388
* domains, or via "qemu-img snapshot -l" for shutoff domains. It would
389
* be nice to update our internal state based on that, but there is a
390
* a problem. qemu doesn't track all of the same metadata that we do.
391
* In particular we wouldn't be able to fill in the <parent>, which is
392
* pretty important in our metadata.
401
virDomainObjUnlock(vm);
407
* Initialization function for the QEmu daemon
410
qemudStartup(int privileged) {
412
char *driverConf = NULL;
414
virConnectPtr conn = NULL;
416
if (VIR_ALLOC(qemu_driver) < 0)
419
if (virMutexInit(&qemu_driver->lock) < 0) {
420
VIR_ERROR(_("cannot initialize mutex"));
421
VIR_FREE(qemu_driver);
424
qemuDriverLock(qemu_driver);
425
qemu_driver->privileged = privileged;
427
/* Don't have a dom0 so start from 1 */
428
qemu_driver->nextvmid = 1;
430
if (virDomainObjListInit(&qemu_driver->domains) < 0)
433
/* Init domain events */
434
qemu_driver->domainEventState = virDomainEventStateNew(qemuDomainEventFlush,
438
if (!qemu_driver->domainEventState)
441
/* Allocate bitmap for vnc port reservation */
442
if ((qemu_driver->reservedVNCPorts =
443
virBitmapAlloc(QEMU_VNC_PORT_MAX - QEMU_VNC_PORT_MIN)) == NULL)
446
/* read the host sysinfo */
448
qemu_driver->hostsysinfo = virSysinfoRead();
451
if (virAsprintf(&qemu_driver->logDir,
452
"%s/log/libvirt/qemu", LOCALSTATEDIR) == -1)
455
if ((base = strdup (SYSCONFDIR "/libvirt")) == NULL)
458
if (virAsprintf(&qemu_driver->stateDir,
459
"%s/run/libvirt/qemu", LOCALSTATEDIR) == -1)
462
if (virAsprintf(&qemu_driver->libDir,
463
"%s/lib/libvirt/qemu", LOCALSTATEDIR) == -1)
466
if (virAsprintf(&qemu_driver->cacheDir,
467
"%s/cache/libvirt/qemu", LOCALSTATEDIR) == -1)
469
if (virAsprintf(&qemu_driver->saveDir,
470
"%s/lib/libvirt/qemu/save", LOCALSTATEDIR) == -1)
472
if (virAsprintf(&qemu_driver->snapshotDir,
473
"%s/lib/libvirt/qemu/snapshot", LOCALSTATEDIR) == -1)
475
if (virAsprintf(&qemu_driver->autoDumpPath,
476
"%s/lib/libvirt/qemu/dump", LOCALSTATEDIR) == -1)
479
uid_t uid = geteuid();
480
char *userdir = virGetUserDirectory(uid);
484
if (virAsprintf(&qemu_driver->logDir,
485
"%s/.libvirt/qemu/log", userdir) == -1) {
490
if (virAsprintf(&base, "%s/.libvirt", userdir) == -1) {
496
if (virAsprintf(&qemu_driver->stateDir, "%s/qemu/run", base) == -1)
498
if (virAsprintf(&qemu_driver->libDir, "%s/qemu/lib", base) == -1)
500
if (virAsprintf(&qemu_driver->cacheDir, "%s/qemu/cache", base) == -1)
502
if (virAsprintf(&qemu_driver->saveDir, "%s/qemu/save", base) == -1)
504
if (virAsprintf(&qemu_driver->snapshotDir, "%s/qemu/snapshot", base) == -1)
506
if (virAsprintf(&qemu_driver->autoDumpPath, "%s/qemu/dump", base) == -1)
510
if (virFileMakePath(qemu_driver->stateDir) < 0) {
512
VIR_ERROR(_("Failed to create state dir '%s': %s"),
513
qemu_driver->stateDir, virStrerror(errno, ebuf, sizeof ebuf));
516
if (virFileMakePath(qemu_driver->libDir) < 0) {
518
VIR_ERROR(_("Failed to create lib dir '%s': %s"),
519
qemu_driver->libDir, virStrerror(errno, ebuf, sizeof ebuf));
522
if (virFileMakePath(qemu_driver->cacheDir) < 0) {
524
VIR_ERROR(_("Failed to create cache dir '%s': %s"),
525
qemu_driver->cacheDir, virStrerror(errno, ebuf, sizeof ebuf));
528
if (virFileMakePath(qemu_driver->saveDir) < 0) {
530
VIR_ERROR(_("Failed to create save dir '%s': %s"),
531
qemu_driver->saveDir, virStrerror(errno, ebuf, sizeof ebuf));
534
if (virFileMakePath(qemu_driver->snapshotDir) < 0) {
536
VIR_ERROR(_("Failed to create save dir '%s': %s"),
537
qemu_driver->snapshotDir, virStrerror(errno, ebuf, sizeof ebuf));
540
if (virFileMakePath(qemu_driver->autoDumpPath) < 0) {
542
VIR_ERROR(_("Failed to create dump dir '%s': %s"),
543
qemu_driver->autoDumpPath, virStrerror(errno, ebuf, sizeof ebuf));
547
/* Configuration paths are either ~/.libvirt/qemu/... (session) or
548
* /etc/libvirt/qemu/... (system).
550
if (virAsprintf(&driverConf, "%s/qemu.conf", base) < 0 ||
551
virAsprintf(&qemu_driver->configDir, "%s/qemu", base) < 0 ||
552
virAsprintf(&qemu_driver->autostartDir, "%s/qemu/autostart", base) < 0)
557
rc = virCgroupForDriver("qemu", &qemu_driver->cgroup, privileged, 1);
560
VIR_INFO("Unable to create cgroup for driver: %s",
561
virStrerror(-rc, buf, sizeof(buf)));
564
if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) {
567
VIR_FREE(driverConf);
569
/* We should always at least have the 'nop' manager, so
570
* NULLs here are a fatal error
572
if (!qemu_driver->lockManager) {
573
VIR_ERROR(_("Missing lock manager implementation"));
577
if (qemuSecurityInit(qemu_driver) < 0)
580
if ((qemu_driver->caps = qemuCreateCapabilities(NULL,
581
qemu_driver)) == NULL)
584
if ((qemu_driver->activePciHostdevs = pciDeviceListNew()) == NULL)
588
if (chown(qemu_driver->libDir, qemu_driver->user, qemu_driver->group) < 0) {
589
virReportSystemError(errno,
590
_("unable to set ownership of '%s' to user %d:%d"),
591
qemu_driver->libDir, qemu_driver->user, qemu_driver->group);
594
if (chown(qemu_driver->cacheDir, qemu_driver->user, qemu_driver->group) < 0) {
595
virReportSystemError(errno,
596
_("unable to set ownership of '%s' to %d:%d"),
597
qemu_driver->cacheDir, qemu_driver->user, qemu_driver->group);
600
if (chown(qemu_driver->saveDir, qemu_driver->user, qemu_driver->group) < 0) {
601
virReportSystemError(errno,
602
_("unable to set ownership of '%s' to %d:%d"),
603
qemu_driver->saveDir, qemu_driver->user, qemu_driver->group);
606
if (chown(qemu_driver->snapshotDir, qemu_driver->user, qemu_driver->group) < 0) {
607
virReportSystemError(errno,
608
_("unable to set ownership of '%s' to %d:%d"),
609
qemu_driver->snapshotDir, qemu_driver->user, qemu_driver->group);
614
/* If hugetlbfs is present, then we need to create a sub-directory within
615
* it, since we can't assume the root mount point has permissions that
616
* will let our spawned QEMU instances use it.
618
* NB the check for '/', since user may config "" to disable hugepages
621
if (qemu_driver->hugetlbfs_mount &&
622
qemu_driver->hugetlbfs_mount[0] == '/') {
623
char *mempath = NULL;
624
if (virAsprintf(&mempath, "%s/libvirt/qemu", qemu_driver->hugetlbfs_mount) < 0)
627
if (virFileMakePath(mempath) < 0) {
628
virReportSystemError(errno,
629
_("unable to create hugepage path %s"), mempath);
633
if (qemu_driver->privileged &&
634
chown(mempath, qemu_driver->user, qemu_driver->group) < 0) {
635
virReportSystemError(errno,
636
_("unable to set ownership on %s to %d:%d"),
637
mempath, qemu_driver->user, qemu_driver->group);
642
qemu_driver->hugepage_path = mempath;
645
if (qemuProcessAutoDestroyInit(qemu_driver) < 0)
648
/* Get all the running persistent or transient configs first */
649
if (virDomainLoadAllConfigs(qemu_driver->caps,
650
&qemu_driver->domains,
651
qemu_driver->stateDir,
653
1, QEMU_EXPECTED_VIRT_TYPES,
657
conn = virConnectOpen(qemu_driver->privileged ?
661
qemuProcessReconnectAll(conn, qemu_driver);
663
/* Then inactive persistent configs */
664
if (virDomainLoadAllConfigs(qemu_driver->caps,
665
&qemu_driver->domains,
666
qemu_driver->configDir,
667
qemu_driver->autostartDir,
668
0, QEMU_EXPECTED_VIRT_TYPES,
673
virHashForEach(qemu_driver->domains.objs, qemuDomainSnapshotLoad,
674
qemu_driver->snapshotDir);
676
qemu_driver->workerPool = virThreadPoolNew(0, 1, 0, processWatchdogEvent, qemu_driver);
677
if (!qemu_driver->workerPool)
680
qemuDriverUnlock(qemu_driver);
682
qemuAutostartDomains(qemu_driver);
685
virConnectClose(conn);
693
qemuDriverUnlock(qemu_driver);
695
virConnectClose(conn);
697
VIR_FREE(driverConf);
702
static void qemudNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque)
704
struct qemud_driver *driver = opaque;
707
virDomainEventPtr event =
708
virDomainEventNewFromObj(vm,
709
VIR_DOMAIN_EVENT_DEFINED,
710
VIR_DOMAIN_EVENT_DEFINED_ADDED);
712
qemuDomainEventQueue(driver, event);
719
* Function to restart the QEmu daemon, it will recheck the configuration
720
* files and update its state and the networking
727
qemuDriverLock(qemu_driver);
728
virDomainLoadAllConfigs(qemu_driver->caps,
729
&qemu_driver->domains,
730
qemu_driver->configDir,
731
qemu_driver->autostartDir,
732
0, QEMU_EXPECTED_VIRT_TYPES,
733
qemudNotifyLoadDomain, qemu_driver);
734
qemuDriverUnlock(qemu_driver);
736
qemuAutostartDomains(qemu_driver);
744
* Checks if the QEmu daemon is active, i.e. has an active domain or
747
* Returns 1 if active, 0 otherwise
756
/* XXX having to iterate here is not great because it requires many locks */
757
qemuDriverLock(qemu_driver);
758
active = virDomainObjListNumOfDomains(&qemu_driver->domains, 1);
759
qemuDriverUnlock(qemu_driver);
766
* Shutdown the QEmu daemon, it will stop all active domains and networks
769
qemudShutdown(void) {
775
qemuDriverLock(qemu_driver);
776
pciDeviceListFree(qemu_driver->activePciHostdevs);
777
virCapabilitiesFree(qemu_driver->caps);
779
virDomainObjListDeinit(&qemu_driver->domains);
780
virBitmapFree(qemu_driver->reservedVNCPorts);
782
virSysinfoDefFree(qemu_driver->hostsysinfo);
784
qemuProcessAutoDestroyShutdown(qemu_driver);
786
VIR_FREE(qemu_driver->configDir);
787
VIR_FREE(qemu_driver->autostartDir);
788
VIR_FREE(qemu_driver->logDir);
789
VIR_FREE(qemu_driver->stateDir);
790
VIR_FREE(qemu_driver->libDir);
791
VIR_FREE(qemu_driver->cacheDir);
792
VIR_FREE(qemu_driver->saveDir);
793
VIR_FREE(qemu_driver->snapshotDir);
794
VIR_FREE(qemu_driver->qemuImgBinary);
795
VIR_FREE(qemu_driver->autoDumpPath);
796
VIR_FREE(qemu_driver->vncTLSx509certdir);
797
VIR_FREE(qemu_driver->vncListen);
798
VIR_FREE(qemu_driver->vncPassword);
799
VIR_FREE(qemu_driver->vncSASLdir);
800
VIR_FREE(qemu_driver->spiceTLSx509certdir);
801
VIR_FREE(qemu_driver->spiceListen);
802
VIR_FREE(qemu_driver->spicePassword);
803
VIR_FREE(qemu_driver->hugetlbfs_mount);
804
VIR_FREE(qemu_driver->hugepage_path);
805
VIR_FREE(qemu_driver->saveImageFormat);
806
VIR_FREE(qemu_driver->dumpImageFormat);
808
virSecurityManagerFree(qemu_driver->securityManager);
810
ebtablesContextFree(qemu_driver->ebtables);
812
if (qemu_driver->cgroupDeviceACL) {
813
for (i = 0 ; qemu_driver->cgroupDeviceACL[i] != NULL ; i++)
814
VIR_FREE(qemu_driver->cgroupDeviceACL[i]);
815
VIR_FREE(qemu_driver->cgroupDeviceACL);
818
/* Free domain callback list */
819
virDomainEventStateFree(qemu_driver->domainEventState);
821
virCgroupFree(&qemu_driver->cgroup);
823
virLockManagerPluginUnref(qemu_driver->lockManager);
825
qemuDriverUnlock(qemu_driver);
826
virMutexDestroy(&qemu_driver->lock);
827
virThreadPoolFree(qemu_driver->workerPool);
828
VIR_FREE(qemu_driver);
834
static virDrvOpenStatus qemudOpen(virConnectPtr conn,
835
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
838
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
840
if (conn->uri == NULL) {
841
if (qemu_driver == NULL)
842
return VIR_DRV_OPEN_DECLINED;
844
conn->uri = xmlParseURI(qemu_driver->privileged ?
849
return VIR_DRV_OPEN_ERROR;
852
/* If URI isn't 'qemu' its definitely not for us */
853
if (conn->uri->scheme == NULL ||
854
STRNEQ(conn->uri->scheme, "qemu"))
855
return VIR_DRV_OPEN_DECLINED;
857
/* Allow remote driver to deal with URIs with hostname server */
858
if (conn->uri->server != NULL)
859
return VIR_DRV_OPEN_DECLINED;
861
if (qemu_driver == NULL) {
862
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
863
_("qemu state driver is not active"));
864
return VIR_DRV_OPEN_ERROR;
867
if (conn->uri->path == NULL) {
868
qemuReportError(VIR_ERR_INTERNAL_ERROR,
869
_("no QEMU URI path given, try %s"),
870
qemu_driver->privileged
872
: "qemu:///session");
873
return VIR_DRV_OPEN_ERROR;
876
if (qemu_driver->privileged) {
877
if (STRNEQ (conn->uri->path, "/system") &&
878
STRNEQ (conn->uri->path, "/session")) {
879
qemuReportError(VIR_ERR_INTERNAL_ERROR,
880
_("unexpected QEMU URI path '%s', try qemu:///system"),
882
return VIR_DRV_OPEN_ERROR;
885
if (STRNEQ (conn->uri->path, "/session")) {
886
qemuReportError(VIR_ERR_INTERNAL_ERROR,
887
_("unexpected QEMU URI path '%s', try qemu:///session"),
889
return VIR_DRV_OPEN_ERROR;
893
conn->privateData = qemu_driver;
895
return VIR_DRV_OPEN_SUCCESS;
898
static int qemudClose(virConnectPtr conn) {
899
struct qemud_driver *driver = conn->privateData;
901
/* Get rid of callbacks registered for this conn */
902
qemuDriverLock(driver);
903
virDomainEventCallbackListRemoveConn(conn,
904
driver->domainEventState->callbacks);
905
qemuProcessAutoDestroyRun(driver, conn);
906
qemuDriverUnlock(driver);
908
conn->privateData = NULL;
913
/* Which features are supported by this driver? */
915
qemudSupportsFeature (virConnectPtr conn ATTRIBUTE_UNUSED, int feature)
918
case VIR_DRV_FEATURE_MIGRATION_V2:
919
case VIR_DRV_FEATURE_MIGRATION_V3:
920
case VIR_DRV_FEATURE_MIGRATION_P2P:
921
case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION:
922
case VIR_DRV_FEATURE_FD_PASSING:
923
case VIR_DRV_FEATURE_TYPED_PARAM_STRING:
930
static const char *qemudGetType(virConnectPtr conn ATTRIBUTE_UNUSED) {
935
static int qemuIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
937
/* Trivially secure, since always inside the daemon */
941
static int qemuIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
943
/* Not encrypted, but remote driver takes care of that */
947
static int qemuIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
953
static int kvmGetMaxVCPUs(void) {
958
fd = open(KVM_DEVICE, O_RDONLY);
960
virReportSystemError(errno, _("Unable to open %s"), KVM_DEVICE);
964
r = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS);
974
qemuGetSysinfo(virConnectPtr conn, unsigned int flags)
976
struct qemud_driver *driver = conn->privateData;
977
virBuffer buf = VIR_BUFFER_INITIALIZER;
979
virCheckFlags(0, NULL);
981
if (!driver->hostsysinfo) {
982
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
983
_("Host SMBIOS information is not available"));
987
if (virSysinfoFormat(&buf, driver->hostsysinfo) < 0)
989
if (virBufferError(&buf)) {
993
return virBufferContentAndReset(&buf);
996
static int qemudGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED, const char *type) {
1000
if (STRCASEEQ(type, "qemu"))
1003
if (STRCASEEQ(type, "kvm"))
1004
return kvmGetMaxVCPUs();
1006
if (STRCASEEQ(type, "kqemu"))
1009
qemuReportError(VIR_ERR_INVALID_ARG,
1010
_("unknown type '%s'"), type);
1015
static char *qemudGetCapabilities(virConnectPtr conn) {
1016
struct qemud_driver *driver = conn->privateData;
1017
virCapsPtr caps = NULL;
1020
qemuDriverLock(driver);
1022
if ((caps = qemuCreateCapabilities(qemu_driver->caps,
1023
qemu_driver)) == NULL) {
1024
virCapabilitiesFree(caps);
1028
virCapabilitiesFree(qemu_driver->caps);
1029
qemu_driver->caps = caps;
1031
if ((xml = virCapabilitiesFormatXML(driver->caps)) == NULL)
1032
virReportOOMError();
1035
qemuDriverUnlock(driver);
1042
qemudGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, int pid,
1047
unsigned long long usertime, systime;
1052
ret = virAsprintf(&proc, "/proc/%d/task/%d/stat", pid, tid);
1054
ret = virAsprintf(&proc, "/proc/%d/stat", pid);
1058
if (!(pidinfo = fopen(proc, "r"))) {
1059
/* VM probably shut down, so fake 0 */
1069
/* See 'man proc' for information about what all these fields are. We're
1070
* only interested in a very few of them */
1073
"%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %llu %llu"
1074
/* cutime -> endcode */
1075
"%*d %*d %*d %*d %*d %*u %*u %*d %*u %*u %*u %*u"
1076
/* startstack -> processor */
1077
"%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %d",
1078
&usertime, &systime, &cpu) != 3) {
1079
VIR_FORCE_FCLOSE(pidinfo);
1080
VIR_WARN("cannot parse process status data");
1086
* We want nanoseconds
1087
* _SC_CLK_TCK is jiffies per second
1088
* So calulate thus....
1091
*cpuTime = 1000ull * 1000ull * 1000ull * (usertime + systime) / (unsigned long long)sysconf(_SC_CLK_TCK);
1096
VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d",
1097
pid, tid, usertime, systime, cpu);
1099
VIR_FORCE_FCLOSE(pidinfo);
1105
static virDomainPtr qemudDomainLookupByID(virConnectPtr conn,
1107
struct qemud_driver *driver = conn->privateData;
1109
virDomainPtr dom = NULL;
1111
qemuDriverLock(driver);
1112
vm = virDomainFindByID(&driver->domains, id);
1113
qemuDriverUnlock(driver);
1116
qemuReportError(VIR_ERR_NO_DOMAIN,
1117
_("no domain with matching id %d"), id);
1121
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
1122
if (dom) dom->id = vm->def->id;
1126
virDomainObjUnlock(vm);
1130
static virDomainPtr qemudDomainLookupByUUID(virConnectPtr conn,
1131
const unsigned char *uuid) {
1132
struct qemud_driver *driver = conn->privateData;
1134
virDomainPtr dom = NULL;
1136
qemuDriverLock(driver);
1137
vm = virDomainFindByUUID(&driver->domains, uuid);
1138
qemuDriverUnlock(driver);
1141
char uuidstr[VIR_UUID_STRING_BUFLEN];
1142
virUUIDFormat(uuid, uuidstr);
1143
qemuReportError(VIR_ERR_NO_DOMAIN,
1144
_("no domain with matching uuid '%s'"), uuidstr);
1148
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
1149
if (dom) dom->id = vm->def->id;
1153
virDomainObjUnlock(vm);
1157
static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
1159
struct qemud_driver *driver = conn->privateData;
1161
virDomainPtr dom = NULL;
1163
qemuDriverLock(driver);
1164
vm = virDomainFindByName(&driver->domains, name);
1165
qemuDriverUnlock(driver);
1168
qemuReportError(VIR_ERR_NO_DOMAIN,
1169
_("no domain with matching name '%s'"), name);
1173
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
1174
if (dom) dom->id = vm->def->id;
1178
virDomainObjUnlock(vm);
1183
static int qemuDomainIsActive(virDomainPtr dom)
1185
struct qemud_driver *driver = dom->conn->privateData;
1186
virDomainObjPtr obj;
1189
qemuDriverLock(driver);
1190
obj = virDomainFindByUUID(&driver->domains, dom->uuid);
1191
qemuDriverUnlock(driver);
1193
char uuidstr[VIR_UUID_STRING_BUFLEN];
1194
virUUIDFormat(dom->uuid, uuidstr);
1195
qemuReportError(VIR_ERR_NO_DOMAIN,
1196
_("no domain with matching uuid '%s'"), uuidstr);
1199
ret = virDomainObjIsActive(obj);
1203
virDomainObjUnlock(obj);
1207
static int qemuDomainIsPersistent(virDomainPtr dom)
1209
struct qemud_driver *driver = dom->conn->privateData;
1210
virDomainObjPtr obj;
1213
qemuDriverLock(driver);
1214
obj = virDomainFindByUUID(&driver->domains, dom->uuid);
1215
qemuDriverUnlock(driver);
1217
char uuidstr[VIR_UUID_STRING_BUFLEN];
1218
virUUIDFormat(dom->uuid, uuidstr);
1219
qemuReportError(VIR_ERR_NO_DOMAIN,
1220
_("no domain with matching uuid '%s'"), uuidstr);
1223
ret = obj->persistent;
1227
virDomainObjUnlock(obj);
1231
static int qemuDomainIsUpdated(virDomainPtr dom)
1233
struct qemud_driver *driver = dom->conn->privateData;
1234
virDomainObjPtr obj;
1237
qemuDriverLock(driver);
1238
obj = virDomainFindByUUID(&driver->domains, dom->uuid);
1239
qemuDriverUnlock(driver);
1241
char uuidstr[VIR_UUID_STRING_BUFLEN];
1242
virUUIDFormat(dom->uuid, uuidstr);
1243
qemuReportError(VIR_ERR_NO_DOMAIN,
1244
_("no domain with matching uuid '%s'"), uuidstr);
1251
virDomainObjUnlock(obj);
1255
static int qemudGetVersion(virConnectPtr conn, unsigned long *version) {
1256
struct qemud_driver *driver = conn->privateData;
1259
qemuDriverLock(driver);
1260
if (qemuCapsExtractVersion(driver->caps, &driver->qemuVersion) < 0)
1263
*version = driver->qemuVersion;
1267
qemuDriverUnlock(driver);
1271
static int qemudListDomains(virConnectPtr conn, int *ids, int nids) {
1272
struct qemud_driver *driver = conn->privateData;
1275
qemuDriverLock(driver);
1276
n = virDomainObjListGetActiveIDs(&driver->domains, ids, nids);
1277
qemuDriverUnlock(driver);
1282
static int qemudNumDomains(virConnectPtr conn) {
1283
struct qemud_driver *driver = conn->privateData;
1286
qemuDriverLock(driver);
1287
n = virDomainObjListNumOfDomains(&driver->domains, 1);
1288
qemuDriverUnlock(driver);
1293
static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
1294
unsigned int flags) {
1295
struct qemud_driver *driver = conn->privateData;
1296
virDomainDefPtr def;
1297
virDomainObjPtr vm = NULL;
1298
virDomainPtr dom = NULL;
1299
virDomainEventPtr event = NULL;
1300
virDomainEventPtr event2 = NULL;
1302
virCheckFlags(VIR_DOMAIN_START_PAUSED |
1303
VIR_DOMAIN_START_AUTODESTROY, NULL);
1305
qemuDriverLock(driver);
1306
if (!(def = virDomainDefParseString(driver->caps, xml,
1307
QEMU_EXPECTED_VIRT_TYPES,
1308
VIR_DOMAIN_XML_INACTIVE)))
1311
if (virSecurityManagerVerify(driver->securityManager, def) < 0)
1314
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
1317
if (qemudCanonicalizeMachine(driver, def) < 0)
1320
if (qemuDomainAssignPCIAddresses(def) < 0)
1323
if (!(vm = virDomainAssignDef(driver->caps,
1330
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
1331
goto cleanup; /* XXXX free the 'vm' we created ? */
1333
if (qemuProcessStart(conn, driver, vm, NULL,
1334
(flags & VIR_DOMAIN_START_PAUSED) != 0,
1335
(flags & VIR_DOMAIN_START_AUTODESTROY) != 0,
1336
-1, NULL, NULL, VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0) {
1337
virDomainAuditStart(vm, "booted", false);
1338
if (qemuDomainObjEndJob(driver, vm) > 0)
1339
qemuDomainRemoveInactive(driver, vm);
1344
event = virDomainEventNewFromObj(vm,
1345
VIR_DOMAIN_EVENT_STARTED,
1346
VIR_DOMAIN_EVENT_STARTED_BOOTED);
1347
if (event && (flags & VIR_DOMAIN_START_PAUSED)) {
1348
/* There are two classes of event-watching clients - those
1349
* that only care about on/off (and must see a started event
1350
* no matter what, but don't care about suspend events), and
1351
* those that also care about running/paused. To satisfy both
1352
* client types, we have to send two events. */
1353
event2 = virDomainEventNewFromObj(vm,
1354
VIR_DOMAIN_EVENT_SUSPENDED,
1355
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
1357
virDomainAuditStart(vm, "booted", true);
1359
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
1360
if (dom) dom->id = vm->def->id;
1363
qemuDomainObjEndJob(driver, vm) == 0)
1367
virDomainDefFree(def);
1369
virDomainObjUnlock(vm);
1371
qemuDomainEventQueue(driver, event);
1373
qemuDomainEventQueue(driver, event2);
1375
qemuDriverUnlock(driver);
1380
static int qemudDomainSuspend(virDomainPtr dom) {
1381
struct qemud_driver *driver = dom->conn->privateData;
1384
virDomainEventPtr event = NULL;
1385
qemuDomainObjPrivatePtr priv;
1386
virDomainPausedReason reason;
1389
qemuDriverLock(driver);
1390
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
1393
char uuidstr[VIR_UUID_STRING_BUFLEN];
1394
virUUIDFormat(dom->uuid, uuidstr);
1395
qemuReportError(VIR_ERR_NO_DOMAIN,
1396
_("no domain with matching uuid '%s'"), uuidstr);
1399
if (!virDomainObjIsActive(vm)) {
1400
qemuReportError(VIR_ERR_OPERATION_INVALID,
1401
"%s", _("domain is not running"));
1405
priv = vm->privateData;
1407
if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) {
1408
reason = VIR_DOMAIN_PAUSED_MIGRATION;
1409
eventDetail = VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED;
1411
reason = VIR_DOMAIN_PAUSED_USER;
1412
eventDetail = VIR_DOMAIN_EVENT_SUSPENDED_PAUSED;
1415
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_SUSPEND) < 0)
1418
if (!virDomainObjIsActive(vm)) {
1419
qemuReportError(VIR_ERR_OPERATION_INVALID,
1420
"%s", _("domain is not running"));
1423
if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) {
1424
if (qemuProcessStopCPUs(driver, vm, reason, QEMU_ASYNC_JOB_NONE) < 0) {
1427
event = virDomainEventNewFromObj(vm,
1428
VIR_DOMAIN_EVENT_SUSPENDED,
1431
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
1436
if (qemuDomainObjEndJob(driver, vm) == 0)
1441
virDomainObjUnlock(vm);
1444
qemuDomainEventQueue(driver, event);
1445
qemuDriverUnlock(driver);
1450
static int qemudDomainResume(virDomainPtr dom) {
1451
struct qemud_driver *driver = dom->conn->privateData;
1454
virDomainEventPtr event = NULL;
1456
qemuDriverLock(driver);
1457
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
1460
char uuidstr[VIR_UUID_STRING_BUFLEN];
1461
virUUIDFormat(dom->uuid, uuidstr);
1462
qemuReportError(VIR_ERR_NO_DOMAIN,
1463
_("no domain with matching uuid '%s'"), uuidstr);
1467
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
1470
if (!virDomainObjIsActive(vm)) {
1471
qemuReportError(VIR_ERR_OPERATION_INVALID,
1472
"%s", _("domain is not running"));
1475
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
1476
if (qemuProcessStartCPUs(driver, vm, dom->conn,
1477
VIR_DOMAIN_RUNNING_UNPAUSED,
1478
QEMU_ASYNC_JOB_NONE) < 0) {
1479
if (virGetLastError() == NULL)
1480
qemuReportError(VIR_ERR_OPERATION_FAILED,
1481
"%s", _("resume operation failed"));
1484
event = virDomainEventNewFromObj(vm,
1485
VIR_DOMAIN_EVENT_RESUMED,
1486
VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
1488
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
1493
if (qemuDomainObjEndJob(driver, vm) == 0)
1498
virDomainObjUnlock(vm);
1500
qemuDomainEventQueue(driver, event);
1501
qemuDriverUnlock(driver);
1506
static int qemuDomainShutdown(virDomainPtr dom) {
1507
struct qemud_driver *driver = dom->conn->privateData;
1510
qemuDomainObjPrivatePtr priv;
1512
qemuDriverLock(driver);
1513
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
1514
qemuDriverUnlock(driver);
1517
char uuidstr[VIR_UUID_STRING_BUFLEN];
1518
virUUIDFormat(dom->uuid, uuidstr);
1519
qemuReportError(VIR_ERR_NO_DOMAIN,
1520
_("no domain with matching uuid '%s'"), uuidstr);
1524
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
1527
if (!virDomainObjIsActive(vm)) {
1528
qemuReportError(VIR_ERR_OPERATION_INVALID,
1529
"%s", _("domain is not running"));
1533
qemuDomainSetFakeReboot(driver, vm, false);
1535
priv = vm->privateData;
1536
qemuDomainObjEnterMonitor(driver, vm);
1537
ret = qemuMonitorSystemPowerdown(priv->mon);
1538
qemuDomainObjExitMonitor(driver, vm);
1541
if (qemuDomainObjEndJob(driver, vm) == 0)
1546
virDomainObjUnlock(vm);
1551
static int qemuDomainReboot(virDomainPtr dom, unsigned int flags) {
1552
struct qemud_driver *driver = dom->conn->privateData;
1555
qemuDomainObjPrivatePtr priv;
1557
virCheckFlags(0, -1);
1559
qemuDriverLock(driver);
1560
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
1561
qemuDriverUnlock(driver);
1564
char uuidstr[VIR_UUID_STRING_BUFLEN];
1565
virUUIDFormat(dom->uuid, uuidstr);
1566
qemuReportError(VIR_ERR_NO_DOMAIN,
1567
_("no domain with matching uuid '%s'"), uuidstr);
1571
priv = vm->privateData;
1573
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
1574
if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
1575
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
1576
_("Reboot is not supported with this QEMU binary"));
1580
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
1583
if (!virDomainObjIsActive(vm)) {
1584
qemuReportError(VIR_ERR_OPERATION_INVALID,
1585
"%s", _("domain is not running"));
1589
qemuDomainObjEnterMonitor(driver, vm);
1590
ret = qemuMonitorSystemPowerdown(priv->mon);
1591
qemuDomainObjExitMonitor(driver, vm);
1594
qemuDomainSetFakeReboot(driver, vm, true);
1597
if (qemuDomainObjEndJob(driver, vm) == 0)
1600
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
1601
_("Reboot is not supported without the JSON monitor"));
1606
virDomainObjUnlock(vm);
1612
qemuDomainReset(virDomainPtr dom, unsigned int flags)
1614
struct qemud_driver *driver = dom->conn->privateData;
1617
qemuDomainObjPrivatePtr priv;
1619
virCheckFlags(0, -1);
1621
qemuDriverLock(driver);
1622
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
1623
qemuDriverUnlock(driver);
1626
char uuidstr[VIR_UUID_STRING_BUFLEN];
1627
virUUIDFormat(dom->uuid, uuidstr);
1628
qemuReportError(VIR_ERR_NO_DOMAIN,
1629
_("no domain with matching uuid '%s'"), uuidstr);
1633
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
1636
if (!virDomainObjIsActive(vm)) {
1637
qemuReportError(VIR_ERR_OPERATION_INVALID,
1638
"%s", _("domain is not running"));
1642
priv = vm->privateData;
1643
qemuDomainObjEnterMonitor(driver, vm);
1644
ret = qemuMonitorSystemReset(priv->mon);
1645
qemuDomainObjExitMonitor(driver, vm);
1647
priv->fakeReboot = false;
1650
if (qemuDomainObjEndJob(driver, vm) == 0)
1655
virDomainObjUnlock(vm);
1660
/* Count how many snapshots in a set have external disk snapshots. */
1662
qemuDomainSnapshotCountExternal(void *payload,
1663
const void *name ATTRIBUTE_UNUSED,
1666
virDomainSnapshotObjPtr snap = payload;
1669
if (snap->def->state == VIR_DOMAIN_DISK_SNAPSHOT)
1674
qemuDomainDestroyFlags(virDomainPtr dom,
1677
struct qemud_driver *driver = dom->conn->privateData;
1680
virDomainEventPtr event = NULL;
1682
virCheckFlags(0, -1);
1684
qemuDriverLock(driver);
1685
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
1687
char uuidstr[VIR_UUID_STRING_BUFLEN];
1688
virUUIDFormat(dom->uuid, uuidstr);
1689
qemuReportError(VIR_ERR_NO_DOMAIN,
1690
_("no domain with matching uuid '%s'"), uuidstr);
1694
qemuDomainSetFakeReboot(driver, vm, false);
1696
/* Although qemuProcessStop does this already, there may
1697
* be an outstanding job active. We want to make sure we
1698
* can kill the process even if a job is active. Killing
1699
* it now means the job will be released
1701
qemuProcessKill(vm, false);
1703
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_DESTROY) < 0)
1706
if (!virDomainObjIsActive(vm)) {
1707
qemuReportError(VIR_ERR_OPERATION_INVALID,
1708
"%s", _("domain is not running"));
1712
qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_DESTROYED);
1713
event = virDomainEventNewFromObj(vm,
1714
VIR_DOMAIN_EVENT_STOPPED,
1715
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
1716
virDomainAuditStop(vm, "destroyed");
1718
if (!vm->persistent) {
1719
if (qemuDomainObjEndJob(driver, vm) > 0)
1720
qemuDomainRemoveInactive(driver, vm);
1727
qemuDomainObjEndJob(driver, vm) == 0)
1732
virDomainObjUnlock(vm);
1734
qemuDomainEventQueue(driver, event);
1735
qemuDriverUnlock(driver);
1740
qemuDomainDestroy(virDomainPtr dom)
1742
return qemuDomainDestroyFlags(dom, 0);
1745
static char *qemudDomainGetOSType(virDomainPtr dom) {
1746
struct qemud_driver *driver = dom->conn->privateData;
1750
qemuDriverLock(driver);
1751
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
1752
qemuDriverUnlock(driver);
1754
char uuidstr[VIR_UUID_STRING_BUFLEN];
1755
virUUIDFormat(dom->uuid, uuidstr);
1756
qemuReportError(VIR_ERR_NO_DOMAIN,
1757
_("no domain with matching uuid '%s'"), uuidstr);
1761
if (!(type = strdup(vm->def->os.type)))
1762
virReportOOMError();
1766
virDomainObjUnlock(vm);
1770
/* Returns max memory in kb, 0 if error */
1771
static unsigned long qemudDomainGetMaxMemory(virDomainPtr dom) {
1772
struct qemud_driver *driver = dom->conn->privateData;
1774
unsigned long ret = 0;
1776
qemuDriverLock(driver);
1777
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
1778
qemuDriverUnlock(driver);
1781
char uuidstr[VIR_UUID_STRING_BUFLEN];
1782
virUUIDFormat(dom->uuid, uuidstr);
1783
qemuReportError(VIR_ERR_NO_DOMAIN,
1784
_("no domain with matching uuid '%s'"), uuidstr);
1788
ret = vm->def->mem.max_balloon;
1792
virDomainObjUnlock(vm);
1796
static int qemudDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
1797
unsigned int flags) {
1798
struct qemud_driver *driver = dom->conn->privateData;
1799
qemuDomainObjPrivatePtr priv;
1801
virDomainDefPtr persistentDef = NULL;
1805
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
1806
VIR_DOMAIN_AFFECT_CONFIG |
1807
VIR_DOMAIN_MEM_MAXIMUM, -1);
1809
qemuDriverLock(driver);
1810
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
1811
qemuDriverUnlock(driver);
1813
char uuidstr[VIR_UUID_STRING_BUFLEN];
1814
virUUIDFormat(dom->uuid, uuidstr);
1815
qemuReportError(VIR_ERR_NO_DOMAIN,
1816
_("no domain with matching uuid '%s'"), uuidstr);
1820
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
1823
isActive = virDomainObjIsActive(vm);
1825
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
1827
flags = VIR_DOMAIN_AFFECT_LIVE;
1829
flags = VIR_DOMAIN_AFFECT_CONFIG;
1831
if (flags == VIR_DOMAIN_MEM_MAXIMUM) {
1833
flags = VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_MEM_MAXIMUM;
1835
flags = VIR_DOMAIN_AFFECT_CONFIG | VIR_DOMAIN_MEM_MAXIMUM;
1838
if (!isActive && (flags & VIR_DOMAIN_AFFECT_LIVE)) {
1839
qemuReportError(VIR_ERR_OPERATION_INVALID,
1840
"%s", _("domain is not running"));
1844
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
1845
if (!vm->persistent) {
1846
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
1847
_("cannot change persistent config of a transient domain"));
1850
if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
1854
if (flags & VIR_DOMAIN_MEM_MAXIMUM) {
1855
/* resize the maximum memory */
1857
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
1858
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
1859
_("cannot resize the maximum memory on an "
1864
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
1865
/* Help clang 2.8 decipher the logic flow. */
1866
sa_assert(persistentDef);
1867
persistentDef->mem.max_balloon = newmem;
1868
if (persistentDef->mem.cur_balloon > newmem)
1869
persistentDef->mem.cur_balloon = newmem;
1870
ret = virDomainSaveConfig(driver->configDir, persistentDef);
1875
/* resize the current memory */
1877
if (newmem > vm->def->mem.max_balloon) {
1878
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
1879
_("cannot set memory higher than max memory"));
1883
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
1884
priv = vm->privateData;
1885
qemuDomainObjEnterMonitor(driver, vm);
1886
r = qemuMonitorSetBalloon(priv->mon, newmem);
1887
qemuDomainObjExitMonitor(driver, vm);
1888
virDomainAuditMemory(vm, vm->def->mem.cur_balloon, newmem, "update",
1893
/* Lack of balloon support is a fatal error */
1895
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
1896
_("cannot set memory of an active domain"));
1901
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
1902
sa_assert(persistentDef);
1903
persistentDef->mem.cur_balloon = newmem;
1904
ret = virDomainSaveConfig(driver->configDir, persistentDef);
1911
if (qemuDomainObjEndJob(driver, vm) == 0)
1916
virDomainObjUnlock(vm);
1920
static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem)
1922
return qemudDomainSetMemoryFlags(dom, newmem, VIR_DOMAIN_AFFECT_LIVE);
1925
static int qemudDomainSetMaxMemory(virDomainPtr dom, unsigned long memory)
1927
return qemudDomainSetMemoryFlags(dom, memory, VIR_DOMAIN_MEM_MAXIMUM);
1930
static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags)
1932
struct qemud_driver *driver = domain->conn->privateData;
1933
virDomainObjPtr vm = NULL;
1935
qemuDomainObjPrivatePtr priv;
1937
virCheckFlags(0, -1);
1939
qemuDriverLock(driver);
1940
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
1942
char uuidstr[VIR_UUID_STRING_BUFLEN];
1943
virUUIDFormat(domain->uuid, uuidstr);
1944
qemuReportError(VIR_ERR_NO_DOMAIN,
1945
_("no domain with matching uuid '%s'"), uuidstr);
1949
if (!virDomainObjIsActive(vm)) {
1950
qemuReportError(VIR_ERR_OPERATION_INVALID,
1951
"%s", _("domain is not running"));
1955
priv = vm->privateData;
1957
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
1960
if (!virDomainObjIsActive(vm)) {
1961
qemuReportError(VIR_ERR_OPERATION_INVALID,
1962
"%s", _("domain is not running"));
1966
qemuDomainObjEnterMonitorWithDriver(driver, vm);
1967
ret = qemuMonitorInjectNMI(priv->mon);
1968
qemuDomainObjExitMonitorWithDriver(driver, vm);
1971
if (qemuDomainObjEndJob(driver, vm) == 0) {
1978
virDomainObjUnlock(vm);
1979
qemuDriverUnlock(driver);
1983
static int qemuDomainSendKey(virDomainPtr domain,
1984
unsigned int codeset,
1985
unsigned int holdtime,
1986
unsigned int *keycodes,
1990
struct qemud_driver *driver = domain->conn->privateData;
1991
virDomainObjPtr vm = NULL;
1993
qemuDomainObjPrivatePtr priv;
1995
virCheckFlags(0, -1);
1997
/* translate the keycode to RFB for qemu driver */
1998
if (codeset != VIR_KEYCODE_SET_RFB) {
2002
for (i = 0; i < nkeycodes; i++) {
2003
keycode = virKeycodeValueTranslate(codeset, VIR_KEYCODE_SET_RFB,
2006
qemuReportError(VIR_ERR_INTERNAL_ERROR,
2007
_("cannot translate keycode %u of %s codeset to rfb keycode"),
2009
virKeycodeSetTypeToString(codeset));
2012
keycodes[i] = keycode;
2016
qemuDriverLock(driver);
2017
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
2019
char uuidstr[VIR_UUID_STRING_BUFLEN];
2020
virUUIDFormat(domain->uuid, uuidstr);
2021
qemuReportError(VIR_ERR_NO_DOMAIN,
2022
_("no domain with matching uuid '%s'"), uuidstr);
2026
priv = vm->privateData;
2028
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
2031
if (!virDomainObjIsActive(vm)) {
2032
qemuReportError(VIR_ERR_OPERATION_INVALID,
2033
"%s", _("domain is not running"));
2037
qemuDomainObjEnterMonitorWithDriver(driver, vm);
2038
ret = qemuMonitorSendKey(priv->mon, holdtime, keycodes, nkeycodes);
2039
qemuDomainObjExitMonitorWithDriver(driver, vm);
2042
if (qemuDomainObjEndJob(driver, vm) == 0)
2047
virDomainObjUnlock(vm);
2048
qemuDriverUnlock(driver);
2052
static int qemudDomainGetInfo(virDomainPtr dom,
2053
virDomainInfoPtr info)
2055
struct qemud_driver *driver = dom->conn->privateData;
2059
unsigned long balloon;
2061
qemuDriverLock(driver);
2062
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
2063
qemuDriverUnlock(driver);
2065
char uuidstr[VIR_UUID_STRING_BUFLEN];
2066
virUUIDFormat(dom->uuid, uuidstr);
2067
qemuReportError(VIR_ERR_NO_DOMAIN,
2068
_("no domain with matching uuid '%s'"), uuidstr);
2072
info->state = virDomainObjGetState(vm, NULL);
2074
if (!virDomainObjIsActive(vm)) {
2077
if (qemudGetProcessInfo(&(info->cpuTime), NULL, vm->pid, 0) < 0) {
2078
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
2079
_("cannot read cputime for domain"));
2084
info->maxMem = vm->def->mem.max_balloon;
2086
if (virDomainObjIsActive(vm)) {
2087
qemuDomainObjPrivatePtr priv = vm->privateData;
2089
if ((vm->def->memballoon != NULL) &&
2090
(vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_NONE)) {
2091
info->memory = vm->def->mem.max_balloon;
2092
} else if (qemuDomainJobAllowed(priv, QEMU_JOB_QUERY)) {
2093
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
2095
if (!virDomainObjIsActive(vm))
2098
qemuDomainObjEnterMonitor(driver, vm);
2099
err = qemuMonitorGetBalloonInfo(priv->mon, &balloon);
2100
qemuDomainObjExitMonitor(driver, vm);
2102
if (qemuDomainObjEndJob(driver, vm) == 0) {
2108
/* We couldn't get current memory allocation but that's not
2109
* a show stopper; we wouldn't get it if there was a job
2112
info->memory = vm->def->mem.cur_balloon;
2113
} else if (err == 0) {
2114
/* Balloon not supported, so maxmem is always the allocation */
2115
info->memory = vm->def->mem.max_balloon;
2117
info->memory = balloon;
2120
info->memory = vm->def->mem.cur_balloon;
2123
info->memory = vm->def->mem.cur_balloon;
2126
info->nrVirtCpu = vm->def->vcpus;
2131
virDomainObjUnlock(vm);
2136
qemuDomainGetState(virDomainPtr dom,
2141
struct qemud_driver *driver = dom->conn->privateData;
2145
virCheckFlags(0, -1);
2147
qemuDriverLock(driver);
2148
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
2149
qemuDriverUnlock(driver);
2152
char uuidstr[VIR_UUID_STRING_BUFLEN];
2153
virUUIDFormat(dom->uuid, uuidstr);
2154
qemuReportError(VIR_ERR_NO_DOMAIN,
2155
_("no domain with matching uuid '%s'"), uuidstr);
2159
*state = virDomainObjGetState(vm, reason);
2164
virDomainObjUnlock(vm);
2169
qemuDomainGetControlInfo(virDomainPtr dom,
2170
virDomainControlInfoPtr info,
2173
struct qemud_driver *driver = dom->conn->privateData;
2175
qemuDomainObjPrivatePtr priv;
2178
virCheckFlags(0, -1);
2180
qemuDriverLock(driver);
2181
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
2182
qemuDriverUnlock(driver);
2185
char uuidstr[VIR_UUID_STRING_BUFLEN];
2186
virUUIDFormat(dom->uuid, uuidstr);
2187
qemuReportError(VIR_ERR_NO_DOMAIN,
2188
_("no domain with matching uuid '%s'"), uuidstr);
2192
if (!virDomainObjIsActive(vm)) {
2193
qemuReportError(VIR_ERR_OPERATION_INVALID,
2194
"%s", _("domain is not running"));
2198
priv = vm->privateData;
2200
memset(info, 0, sizeof(*info));
2202
if (priv->monError) {
2203
info->state = VIR_DOMAIN_CONTROL_ERROR;
2204
} else if (priv->job.active) {
2205
if (!priv->monStart) {
2206
info->state = VIR_DOMAIN_CONTROL_JOB;
2207
if (virTimeMillisNow(&info->stateTime) < 0)
2209
info->stateTime -= priv->job.start;
2211
info->state = VIR_DOMAIN_CONTROL_OCCUPIED;
2212
if (virTimeMillisNow(&info->stateTime) < 0)
2214
info->stateTime -= priv->monStart;
2217
info->state = VIR_DOMAIN_CONTROL_OK;
2224
virDomainObjUnlock(vm);
2229
#define QEMUD_SAVE_MAGIC "LibvirtQemudSave"
2230
#define QEMUD_SAVE_PARTIAL "LibvirtQemudPart"
2231
#define QEMUD_SAVE_VERSION 2
2233
verify(sizeof(QEMUD_SAVE_MAGIC) == sizeof(QEMUD_SAVE_PARTIAL));
2235
enum qemud_save_formats {
2236
QEMUD_SAVE_FORMAT_RAW = 0,
2237
QEMUD_SAVE_FORMAT_GZIP = 1,
2238
QEMUD_SAVE_FORMAT_BZIP2 = 2,
2240
* Deprecated by xz and never used as part of a release
2241
* QEMUD_SAVE_FORMAT_LZMA
2243
QEMUD_SAVE_FORMAT_XZ = 3,
2244
QEMUD_SAVE_FORMAT_LZOP = 4,
2245
/* Note: add new members only at the end.
2246
These values are used in the on-disk format.
2247
Do not change or re-use numbers. */
2249
QEMUD_SAVE_FORMAT_LAST
2252
VIR_ENUM_DECL(qemudSaveCompression)
2253
VIR_ENUM_IMPL(qemudSaveCompression, QEMUD_SAVE_FORMAT_LAST,
2260
struct qemud_save_header {
2261
char magic[sizeof(QEMUD_SAVE_MAGIC)-1];
2264
uint32_t was_running;
2265
uint32_t compressed;
2266
uint32_t unused[15];
2270
bswap_header(struct qemud_save_header *hdr) {
2271
hdr->version = bswap_32(hdr->version);
2272
hdr->xml_len = bswap_32(hdr->xml_len);
2273
hdr->was_running = bswap_32(hdr->was_running);
2274
hdr->compressed = bswap_32(hdr->compressed);
2278
/* return -errno on failure, or 0 on success */
2280
qemuDomainSaveHeader(int fd, const char *path, char *xml,
2281
struct qemud_save_header *header)
2285
if (safewrite(fd, header, sizeof(*header)) != sizeof(*header)) {
2287
qemuReportError(VIR_ERR_OPERATION_FAILED,
2288
_("failed to write header to domain save file '%s'"),
2293
if (safewrite(fd, xml, header->xml_len) != header->xml_len) {
2295
qemuReportError(VIR_ERR_OPERATION_FAILED,
2296
_("failed to write xml to '%s'"), path);
2303
/* Given a enum qemud_save_formats compression level, return the name
2304
* of the program to run, or NULL if no program is needed. */
2306
qemuCompressProgramName(int compress)
2308
return (compress == QEMUD_SAVE_FORMAT_RAW ? NULL :
2309
qemudSaveCompressionTypeToString(compress));
2312
/* Internal function to properly create or open existing files, with
2313
* ownership affected by qemu driver setup. */
2315
qemuOpenFile(struct qemud_driver *driver, const char *path, int oflags,
2316
bool *needUnlink, bool *bypassSecurityDriver)
2320
bool need_unlink = false;
2321
bool bypass_security = false;
2323
uid_t uid = getuid();
2324
gid_t gid = getgid();
2326
/* path might be a pre-existing block dev, in which case
2327
* we need to skip the create step, and also avoid unlink
2328
* in the failure case */
2329
if (oflags & O_CREAT) {
2331
if (stat(path, &sb) == 0) {
2332
is_reg = !!S_ISREG(sb.st_mode);
2333
/* If the path is regular file which exists
2334
* already and dynamic_ownership is off, we don't
2335
* want to change it's ownership, just open it as-is */
2336
if (is_reg && !driver->dynamicOwnership) {
2343
/* First try creating the file as root */
2345
fd = open(path, oflags & ~O_CREAT);
2347
virReportSystemError(errno, _("unable to open %s"), path);
2351
if ((fd = virFileOpenAs(path, oflags, S_IRUSR | S_IWUSR,
2352
uid, gid, 0)) < 0) {
2353
/* If we failed as root, and the error was permission-denied
2354
(EACCES or EPERM), assume it's on a network-connected share
2355
where root access is restricted (eg, root-squashed NFS). If the
2356
qemu user (driver->user) is non-root, just set a flag to
2357
bypass security driver shenanigans, and retry the operation
2358
after doing setuid to qemu user */
2359
if ((fd != -EACCES && fd != -EPERM) ||
2360
driver->user == getuid()) {
2361
virReportSystemError(-fd,
2362
_("Failed to create file '%s'"),
2367
/* On Linux we can also verify the FS-type of the directory. */
2368
switch (virStorageFileIsSharedFS(path)) {
2370
/* it was on a network share, so we'll continue
2376
virReportSystemError(errno,
2377
_("Failed to create file "
2378
"'%s': couldn't determine fs type"),
2384
/* local file - log the error returned by virFileOpenAs */
2385
virReportSystemError(-fd,
2386
_("Failed to create file '%s'"),
2391
/* Retry creating the file as driver->user */
2393
if ((fd = virFileOpenAs(path, oflags,
2394
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP,
2395
driver->user, driver->group,
2396
VIR_FILE_OPEN_AS_UID)) < 0) {
2397
virReportSystemError(-fd,
2398
_("Error from child process creating '%s'"),
2403
/* Since we had to setuid to create the file, and the fstype
2404
is NFS, we assume it's a root-squashing NFS share, and that
2405
the security driver stuff would have failed anyway */
2407
bypass_security = true;
2412
*needUnlink = need_unlink;
2413
if (bypassSecurityDriver)
2414
*bypassSecurityDriver = bypass_security;
2419
/* This internal function expects the driver lock to already be held on
2420
* entry and the vm must be active + locked. Vm will be unlocked and
2421
* potentially free'd after this returns (eg transient VMs are freed
2422
* shutdown). So 'vm' must not be referenced by the caller after
2423
* this returns (whether returning success or failure).
2426
qemuDomainSaveInternal(struct qemud_driver *driver, virDomainPtr dom,
2427
virDomainObjPtr vm, const char *path,
2428
int compressed, const char *xmlin, unsigned int flags)
2431
struct qemud_save_header header;
2432
bool bypassSecurityDriver = false;
2435
virDomainEventPtr event = NULL;
2436
qemuDomainObjPrivatePtr priv;
2437
bool needUnlink = false;
2439
unsigned long long offset;
2440
unsigned long long pad;
2443
virFileDirectFdPtr directFd = NULL;
2444
bool bypass_cache = flags & VIR_DOMAIN_SAVE_BYPASS_CACHE;
2446
if (qemuProcessAutoDestroyActive(driver, vm)) {
2447
qemuReportError(VIR_ERR_OPERATION_INVALID,
2448
"%s", _("domain is marked for auto destroy"));
2452
memset(&header, 0, sizeof(header));
2453
memcpy(header.magic, QEMUD_SAVE_PARTIAL, sizeof(header.magic));
2454
header.version = QEMUD_SAVE_VERSION;
2456
header.compressed = compressed;
2458
priv = vm->privateData;
2460
if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm,
2461
QEMU_ASYNC_JOB_SAVE) < 0)
2464
memset(&priv->job.info, 0, sizeof(priv->job.info));
2465
priv->job.info.type = VIR_DOMAIN_JOB_UNBOUNDED;
2468
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
2469
header.was_running = 1;
2470
if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_SAVE,
2471
QEMU_ASYNC_JOB_SAVE) < 0)
2474
if (!virDomainObjIsActive(vm)) {
2475
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2476
_("guest unexpectedly quit"));
2480
/* libvirt.c already guaranteed these two flags are exclusive. */
2481
if (flags & VIR_DOMAIN_SAVE_RUNNING)
2482
header.was_running = 1;
2483
else if (flags & VIR_DOMAIN_SAVE_PAUSED)
2484
header.was_running = 0;
2486
/* Get XML for the domain. Restore needs only the inactive xml,
2487
* including secure. We should get the same result whether xmlin
2488
* is NULL or whether it was the live xml of the domain moments
2491
virDomainDefPtr def = NULL;
2493
if (!(def = virDomainDefParseString(driver->caps, xmlin,
2494
QEMU_EXPECTED_VIRT_TYPES,
2495
VIR_DOMAIN_XML_INACTIVE))) {
2498
if (!virDomainDefCheckABIStability(vm->def, def)) {
2499
virDomainDefFree(def);
2502
xml = virDomainDefFormat(def, (VIR_DOMAIN_XML_INACTIVE |
2503
VIR_DOMAIN_XML_SECURE));
2505
xml = virDomainDefFormat(vm->def, (VIR_DOMAIN_XML_INACTIVE |
2506
VIR_DOMAIN_XML_SECURE));
2509
qemuReportError(VIR_ERR_OPERATION_FAILED,
2510
"%s", _("failed to get domain xml"));
2513
len = strlen(xml) + 1;
2514
offset = sizeof(header) + len;
2516
/* Due to way we append QEMU state on our header with dd,
2517
* we need to ensure there's a 512 byte boundary. Unfortunately
2518
* we don't have an explicit offset in the header, so we fake
2519
* it by padding the XML string with NUL bytes. Additionally,
2520
* we want to ensure that virDomainSaveImageDefineXML can supply
2521
* slightly larger XML, so we add a miminum padding prior to
2522
* rounding out to page boundaries.
2525
pad += (QEMU_MONITOR_MIGRATE_TO_FILE_BS -
2526
((offset + pad) % QEMU_MONITOR_MIGRATE_TO_FILE_BS));
2527
if (VIR_EXPAND_N(xml, len, pad) < 0) {
2528
virReportOOMError();
2532
header.xml_len = len;
2534
/* Obtain the file handle. */
2536
directFlag = virFileDirectFdFlag();
2537
if (directFlag < 0) {
2538
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
2539
_("bypass cache unsupported by this system"));
2543
fd = qemuOpenFile(driver, path, O_WRONLY | O_TRUNC | O_CREAT | directFlag,
2544
&needUnlink, &bypassSecurityDriver);
2547
if (bypass_cache && (directFd = virFileDirectFdNew(&fd, path)) == NULL)
2550
/* Write header to file, followed by XML */
2551
if (qemuDomainSaveHeader(fd, path, xml, &header) < 0) {
2552
VIR_FORCE_CLOSE(fd);
2556
/* Perform the migration */
2557
if (qemuMigrationToFile(driver, vm, fd, offset, path,
2558
qemuCompressProgramName(compressed),
2559
bypassSecurityDriver,
2560
QEMU_ASYNC_JOB_SAVE) < 0)
2563
/* Touch up file header to mark image complete. */
2565
/* Reopen the file to touch up the header, since we aren't set
2566
* up to seek backwards on directFd. The reopened fd will
2567
* trigger a single page of file system cache pollution, but
2568
* that's acceptable. */
2569
if (VIR_CLOSE(fd) < 0) {
2570
virReportSystemError(errno, _("unable to close %s"), path);
2573
if (virFileDirectFdClose(directFd) < 0)
2575
fd = qemuOpenFile(driver, path, O_WRONLY, NULL, NULL);
2579
if (lseek(fd, 0, SEEK_SET) != 0) {
2580
virReportSystemError(errno, _("unable to seek %s"), path);
2584
memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
2585
if (safewrite(fd, &header, sizeof(header)) != sizeof(header)) {
2586
virReportSystemError(errno, _("unable to write %s"), path);
2589
if (VIR_CLOSE(fd) < 0) {
2590
virReportSystemError(errno, _("unable to close %s"), path);
2597
qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_SAVED);
2598
virDomainAuditStop(vm, "saved");
2599
event = virDomainEventNewFromObj(vm,
2600
VIR_DOMAIN_EVENT_STOPPED,
2601
VIR_DOMAIN_EVENT_STOPPED_SAVED);
2602
if (!vm->persistent) {
2603
if (qemuDomainObjEndAsyncJob(driver, vm) > 0)
2604
qemuDomainRemoveInactive(driver, vm);
2611
if (header.was_running && virDomainObjIsActive(vm)) {
2612
rc = qemuProcessStartCPUs(driver, vm, dom->conn,
2613
VIR_DOMAIN_RUNNING_SAVE_CANCELED,
2614
QEMU_ASYNC_JOB_SAVE);
2616
VIR_WARN("Unable to resume guest CPUs after save failure");
2619
if (qemuDomainObjEndAsyncJob(driver, vm) == 0)
2624
VIR_FORCE_CLOSE(fd);
2625
virFileDirectFdFree(directFd);
2627
if (ret != 0 && needUnlink)
2630
qemuDomainEventQueue(driver, event);
2632
virDomainObjUnlock(vm);
2636
/* Returns true if a compression program is available in PATH */
2637
static bool qemudCompressProgramAvailable(enum qemud_save_formats compress)
2642
if (compress == QEMUD_SAVE_FORMAT_RAW)
2644
prog = qemudSaveCompressionTypeToString(compress);
2645
c = virFindFileInPath(prog);
2653
qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml,
2656
struct qemud_driver *driver = dom->conn->privateData;
2659
virDomainObjPtr vm = NULL;
2661
virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
2662
VIR_DOMAIN_SAVE_RUNNING |
2663
VIR_DOMAIN_SAVE_PAUSED, -1);
2665
qemuDriverLock(driver);
2667
if (driver->saveImageFormat == NULL)
2668
compressed = QEMUD_SAVE_FORMAT_RAW;
2670
compressed = qemudSaveCompressionTypeFromString(driver->saveImageFormat);
2671
if (compressed < 0) {
2672
qemuReportError(VIR_ERR_OPERATION_FAILED,
2673
"%s", _("Invalid save image format specified "
2674
"in configuration file"));
2677
if (!qemudCompressProgramAvailable(compressed)) {
2678
qemuReportError(VIR_ERR_OPERATION_FAILED,
2679
"%s", _("Compression program for image format "
2680
"in configuration file isn't available"));
2685
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
2687
char uuidstr[VIR_UUID_STRING_BUFLEN];
2688
virUUIDFormat(dom->uuid, uuidstr);
2689
qemuReportError(VIR_ERR_NO_DOMAIN,
2690
_("no domain with matching uuid '%s'"), uuidstr);
2694
if (!virDomainObjIsActive(vm)) {
2695
qemuReportError(VIR_ERR_OPERATION_INVALID,
2696
"%s", _("domain is not running"));
2700
ret = qemuDomainSaveInternal(driver, dom, vm, path, compressed,
2706
virDomainObjUnlock(vm);
2707
qemuDriverUnlock(driver);
2713
qemuDomainSave(virDomainPtr dom, const char *path)
2715
return qemuDomainSaveFlags(dom, path, NULL, 0);
2719
qemuDomainManagedSavePath(struct qemud_driver *driver, virDomainObjPtr vm) {
2722
if (virAsprintf(&ret, "%s/%s.save", driver->saveDir, vm->def->name) < 0) {
2723
virReportOOMError();
2731
qemuDomainManagedSave(virDomainPtr dom, unsigned int flags)
2733
struct qemud_driver *driver = dom->conn->privateData;
2734
virDomainObjPtr vm = NULL;
2739
virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
2740
VIR_DOMAIN_SAVE_RUNNING |
2741
VIR_DOMAIN_SAVE_PAUSED, -1);
2743
qemuDriverLock(driver);
2744
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
2746
char uuidstr[VIR_UUID_STRING_BUFLEN];
2747
virUUIDFormat(dom->uuid, uuidstr);
2748
qemuReportError(VIR_ERR_NO_DOMAIN,
2749
_("no domain with matching uuid '%s'"), uuidstr);
2753
if (!virDomainObjIsActive(vm)) {
2754
qemuReportError(VIR_ERR_OPERATION_INVALID,
2755
"%s", _("domain is not running"));
2758
if (!vm->persistent) {
2759
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
2760
_("cannot do managed save for transient domain"));
2764
name = qemuDomainManagedSavePath(driver, vm);
2768
VIR_INFO("Saving state to %s", name);
2770
compressed = QEMUD_SAVE_FORMAT_RAW;
2771
ret = qemuDomainSaveInternal(driver, dom, vm, name, compressed,
2777
virDomainObjUnlock(vm);
2778
qemuDriverUnlock(driver);
2785
qemuDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
2787
struct qemud_driver *driver = dom->conn->privateData;
2788
virDomainObjPtr vm = NULL;
2792
virCheckFlags(0, -1);
2794
qemuDriverLock(driver);
2795
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
2797
char uuidstr[VIR_UUID_STRING_BUFLEN];
2798
virUUIDFormat(dom->uuid, uuidstr);
2799
qemuReportError(VIR_ERR_NO_DOMAIN,
2800
_("no domain with matching uuid '%s'"), uuidstr);
2804
name = qemuDomainManagedSavePath(driver, vm);
2808
ret = virFileExists(name);
2813
virDomainObjUnlock(vm);
2814
qemuDriverUnlock(driver);
2819
qemuDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
2821
struct qemud_driver *driver = dom->conn->privateData;
2822
virDomainObjPtr vm = NULL;
2826
virCheckFlags(0, -1);
2828
qemuDriverLock(driver);
2829
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
2831
char uuidstr[VIR_UUID_STRING_BUFLEN];
2832
virUUIDFormat(dom->uuid, uuidstr);
2833
qemuReportError(VIR_ERR_NO_DOMAIN,
2834
_("no domain with matching uuid '%s'"), uuidstr);
2838
name = qemuDomainManagedSavePath(driver, vm);
2847
virDomainObjUnlock(vm);
2848
qemuDriverUnlock(driver);
2853
doCoreDump(struct qemud_driver *driver,
2856
enum qemud_save_formats compress,
2861
virFileDirectFdPtr directFd = NULL;
2864
/* Create an empty file with appropriate ownership. */
2866
directFlag = virFileDirectFdFlag();
2867
if (directFlag < 0) {
2868
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
2869
_("bypass cache unsupported by this system"));
2873
/* Core dumps usually imply last-ditch analysis efforts are
2874
* desired, so we intentionally do not unlink even if a file was
2876
if ((fd = qemuOpenFile(driver, path,
2877
O_CREAT | O_TRUNC | O_WRONLY | directFlag,
2881
if (bypass_cache && (directFd = virFileDirectFdNew(&fd, path)) == NULL)
2884
if (qemuMigrationToFile(driver, vm, fd, 0, path,
2885
qemuCompressProgramName(compress), false,
2886
QEMU_ASYNC_JOB_DUMP) < 0)
2889
if (VIR_CLOSE(fd) < 0) {
2890
virReportSystemError(errno,
2891
_("unable to save file %s"),
2895
if (virFileDirectFdClose(directFd) < 0)
2901
VIR_FORCE_CLOSE(fd);
2902
virFileDirectFdFree(directFd);
2908
static enum qemud_save_formats
2909
getCompressionType(struct qemud_driver *driver)
2911
int compress = QEMUD_SAVE_FORMAT_RAW;
2914
* We reuse "save" flag for "dump" here. Then, we can support the same
2915
* format in "save" and "dump".
2917
if (driver->dumpImageFormat) {
2918
compress = qemudSaveCompressionTypeFromString(driver->dumpImageFormat);
2919
/* Use "raw" as the format if the specified format is not valid,
2920
* or the compress program is not available.
2923
VIR_WARN("%s", _("Invalid dump image format specified in "
2924
"configuration file, using raw"));
2925
return QEMUD_SAVE_FORMAT_RAW;
2927
if (!qemudCompressProgramAvailable(compress)) {
2928
VIR_WARN("%s", _("Compression program for dump image format "
2929
"in configuration file isn't available, "
2931
return QEMUD_SAVE_FORMAT_RAW;
2937
static int qemudDomainCoreDump(virDomainPtr dom,
2941
struct qemud_driver *driver = dom->conn->privateData;
2943
qemuDomainObjPrivatePtr priv;
2944
int resume = 0, paused = 0;
2946
virDomainEventPtr event = NULL;
2948
virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH |
2949
VIR_DUMP_BYPASS_CACHE | VIR_DUMP_RESET, -1);
2951
qemuDriverLock(driver);
2952
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
2955
char uuidstr[VIR_UUID_STRING_BUFLEN];
2956
virUUIDFormat(dom->uuid, uuidstr);
2957
qemuReportError(VIR_ERR_NO_DOMAIN,
2958
_("no domain with matching uuid '%s'"), uuidstr);
2962
if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm,
2963
QEMU_ASYNC_JOB_DUMP) < 0)
2966
if (!virDomainObjIsActive(vm)) {
2967
qemuReportError(VIR_ERR_OPERATION_INVALID,
2968
"%s", _("domain is not running"));
2972
/* Migrate will always stop the VM, so the resume condition is
2973
independent of whether the stop command is issued. */
2974
resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING;
2976
/* Pause domain for non-live dump */
2977
if (!(flags & VIR_DUMP_LIVE) &&
2978
virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
2979
if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_DUMP,
2980
QEMU_ASYNC_JOB_DUMP) < 0)
2984
if (!virDomainObjIsActive(vm)) {
2985
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2986
_("guest unexpectedly quit"));
2991
ret = doCoreDump(driver, vm, path, getCompressionType(driver),
2992
(flags & VIR_DUMP_BYPASS_CACHE) != 0);
2999
if ((ret == 0) && (flags & VIR_DUMP_CRASH)) {
3000
qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_CRASHED);
3001
virDomainAuditStop(vm, "crashed");
3002
event = virDomainEventNewFromObj(vm,
3003
VIR_DOMAIN_EVENT_STOPPED,
3004
VIR_DOMAIN_EVENT_STOPPED_CRASHED);
3007
/* Since the monitor is always attached to a pty for libvirt, it
3008
will support synchronous operations so we always get here after
3009
the migration is complete. */
3010
else if (((resume && paused) || (flags & VIR_DUMP_RESET)) &&
3011
virDomainObjIsActive(vm)) {
3012
if ((ret == 0) && (flags & VIR_DUMP_RESET)) {
3013
priv = vm->privateData;
3014
qemuDomainObjEnterMonitorWithDriver(driver, vm);
3015
ret = qemuMonitorSystemReset(priv->mon);
3016
qemuDomainObjExitMonitorWithDriver(driver, vm);
3019
if (resume && qemuProcessStartCPUs(driver, vm, dom->conn,
3020
VIR_DOMAIN_RUNNING_UNPAUSED,
3021
QEMU_ASYNC_JOB_DUMP) < 0) {
3022
if (virGetLastError() == NULL)
3023
qemuReportError(VIR_ERR_OPERATION_FAILED,
3024
"%s", _("resuming after dump failed"));
3028
if (qemuDomainObjEndAsyncJob(driver, vm) == 0)
3030
else if ((ret == 0) && (flags & VIR_DUMP_CRASH) && !vm->persistent) {
3031
qemuDomainRemoveInactive(driver, vm);
3037
virDomainObjUnlock(vm);
3039
qemuDomainEventQueue(driver, event);
3040
qemuDriverUnlock(driver);
3045
qemuDomainScreenshot(virDomainPtr dom,
3047
unsigned int screen,
3050
struct qemud_driver *driver = dom->conn->privateData;
3052
qemuDomainObjPrivatePtr priv;
3056
bool unlink_tmp = false;
3058
virCheckFlags(0, NULL);
3060
qemuDriverLock(driver);
3061
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
3062
qemuDriverUnlock(driver);
3065
char uuidstr[VIR_UUID_STRING_BUFLEN];
3066
virUUIDFormat(dom->uuid, uuidstr);
3067
qemuReportError(VIR_ERR_NO_DOMAIN,
3068
_("no domain matching uuid '%s'"), uuidstr);
3072
priv = vm->privateData;
3074
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
3077
if (!virDomainObjIsActive(vm)) {
3078
qemuReportError(VIR_ERR_OPERATION_INVALID,
3079
"%s", _("domain is not running"));
3083
/* Well, even if qemu allows multiple graphic cards, heads, whatever,
3084
* screenshot command does not */
3086
qemuReportError(VIR_ERR_INVALID_ARG,
3087
"%s", _("currently is supported only taking "
3088
"screenshots of screen ID 0"));
3092
if (virAsprintf(&tmp, "%s/qemu.screendump.XXXXXX", driver->cacheDir) < 0) {
3093
virReportOOMError();
3097
if ((tmp_fd = mkstemp(tmp)) == -1) {
3098
virReportSystemError(errno, _("mkstemp(\"%s\") failed"), tmp);
3103
virSecurityManagerSetSavedStateLabel(qemu_driver->securityManager, vm, tmp);
3105
qemuDomainObjEnterMonitor(driver, vm);
3106
if (qemuMonitorScreendump(priv->mon, tmp) < 0) {
3107
qemuDomainObjExitMonitor(driver, vm);
3110
qemuDomainObjExitMonitor(driver, vm);
3112
if (VIR_CLOSE(tmp_fd) < 0) {
3113
virReportSystemError(errno, _("unable to close %s"), tmp);
3117
if (virFDStreamOpenFile(st, tmp, 0, 0, O_RDONLY) < 0) {
3118
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
3119
_("unable to open stream"));
3123
ret = strdup("image/x-portable-pixmap");
3126
VIR_FORCE_CLOSE(tmp_fd);
3131
if (qemuDomainObjEndJob(driver, vm) == 0)
3136
virDomainObjUnlock(vm);
3140
static void processWatchdogEvent(void *data, void *opaque)
3143
struct qemuDomainWatchdogEvent *wdEvent = data;
3144
struct qemud_driver *driver = opaque;
3146
qemuDriverLock(driver);
3147
virDomainObjLock(wdEvent->vm);
3149
switch (wdEvent->action) {
3150
case VIR_DOMAIN_WATCHDOG_ACTION_DUMP:
3154
if (virAsprintf(&dumpfile, "%s/%s-%u",
3155
driver->autoDumpPath,
3156
wdEvent->vm->def->name,
3157
(unsigned int)time(NULL)) < 0) {
3158
virReportOOMError();
3162
if (qemuDomainObjBeginAsyncJobWithDriver(driver, wdEvent->vm,
3163
QEMU_ASYNC_JOB_DUMP) < 0) {
3168
if (!virDomainObjIsActive(wdEvent->vm)) {
3169
qemuReportError(VIR_ERR_OPERATION_INVALID,
3170
"%s", _("domain is not running"));
3175
ret = doCoreDump(driver, wdEvent->vm, dumpfile,
3176
getCompressionType(driver),
3177
driver->autoDumpBypassCache);
3179
qemuReportError(VIR_ERR_OPERATION_FAILED,
3180
"%s", _("Dump failed"));
3182
ret = qemuProcessStartCPUs(driver, wdEvent->vm, NULL,
3183
VIR_DOMAIN_RUNNING_UNPAUSED,
3184
QEMU_ASYNC_JOB_DUMP);
3187
qemuReportError(VIR_ERR_OPERATION_FAILED,
3188
"%s", _("Resuming after dump failed"));
3198
/* Safe to ignore value since ref count was incremented in
3199
* qemuProcessHandleWatchdog().
3201
ignore_value(qemuDomainObjEndAsyncJob(driver, wdEvent->vm));
3204
if (virDomainObjUnref(wdEvent->vm) > 0)
3205
virDomainObjUnlock(wdEvent->vm);
3206
qemuDriverUnlock(driver);
3210
static int qemudDomainHotplugVcpus(struct qemud_driver *driver,
3212
unsigned int nvcpus)
3214
qemuDomainObjPrivatePtr priv = vm->privateData;
3217
int oldvcpus = vm->def->vcpus;
3218
int vcpus = oldvcpus;
3220
qemuDomainObjEnterMonitor(driver, vm);
3222
/* We need different branches here, because we want to offline
3223
* in reverse order to onlining, so any partial fail leaves us in a
3224
* reasonably sensible state */
3225
if (nvcpus > vcpus) {
3226
for (i = vcpus ; i < nvcpus ; i++) {
3227
/* Online new CPU */
3228
rc = qemuMonitorSetCPU(priv->mon, i, 1);
3237
for (i = vcpus - 1 ; i >= nvcpus ; i--) {
3238
/* Offline old CPU */
3239
rc = qemuMonitorSetCPU(priv->mon, i, 0);
3252
qemuDomainObjExitMonitor(driver, vm);
3253
vm->def->vcpus = vcpus;
3254
virDomainAuditVcpu(vm, oldvcpus, nvcpus, "update", rc == 1);
3258
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3259
_("cannot change vcpu count of this domain"));
3265
qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
3268
struct qemud_driver *driver = dom->conn->privateData;
3270
virDomainDefPtr persistentDef;
3277
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
3278
VIR_DOMAIN_AFFECT_CONFIG |
3279
VIR_DOMAIN_VCPU_MAXIMUM, -1);
3281
if (!nvcpus || (unsigned short) nvcpus != nvcpus) {
3282
qemuReportError(VIR_ERR_INVALID_ARG,
3283
_("argument out of range: %d"), nvcpus);
3287
qemuDriverLock(driver);
3288
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
3289
qemuDriverUnlock(driver);
3292
char uuidstr[VIR_UUID_STRING_BUFLEN];
3293
virUUIDFormat(dom->uuid, uuidstr);
3294
qemuReportError(VIR_ERR_NO_DOMAIN,
3295
_("no domain with matching uuid '%s'"), uuidstr);
3299
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
3302
isActive = virDomainObjIsActive(vm);
3303
maximum = (flags & VIR_DOMAIN_VCPU_MAXIMUM) != 0;
3304
flags &= ~VIR_DOMAIN_VCPU_MAXIMUM;
3306
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
3308
flags |= VIR_DOMAIN_AFFECT_LIVE;
3310
flags |= VIR_DOMAIN_AFFECT_CONFIG;
3313
/* MAXIMUM cannot be mixed with LIVE. */
3314
if (maximum && (flags & VIR_DOMAIN_AFFECT_LIVE)) {
3315
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
3316
_("cannot adjust maximum on running domain"));
3320
if (!isActive && (flags & VIR_DOMAIN_AFFECT_LIVE)) {
3321
qemuReportError(VIR_ERR_OPERATION_INVALID,
3322
"%s", _("domain is not running"));
3326
if (!vm->persistent && (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
3327
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
3328
_("cannot change persistent config of a transient domain"));
3332
if (!(type = virDomainVirtTypeToString(vm->def->virtType))) {
3333
qemuReportError(VIR_ERR_INTERNAL_ERROR,
3334
_("unknown virt type in domain definition '%d'"),
3339
if ((max = qemudGetMaxVCPUs(NULL, type)) < 0) {
3340
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3341
_("could not determine max vcpus for the domain"));
3345
if (!maximum && vm->def->maxvcpus < max) {
3346
max = vm->def->maxvcpus;
3350
qemuReportError(VIR_ERR_INVALID_ARG,
3351
_("requested vcpus is greater than max allowable"
3352
" vcpus for the domain: %d > %d"), nvcpus, max);
3356
if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
3360
case VIR_DOMAIN_AFFECT_CONFIG:
3362
persistentDef->maxvcpus = nvcpus;
3363
if (nvcpus < persistentDef->vcpus)
3364
persistentDef->vcpus = nvcpus;
3366
persistentDef->vcpus = nvcpus;
3371
case VIR_DOMAIN_AFFECT_LIVE:
3372
ret = qemudDomainHotplugVcpus(driver, vm, nvcpus);
3375
case VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG:
3376
ret = qemudDomainHotplugVcpus(driver, vm, nvcpus);
3378
persistentDef->vcpus = nvcpus;
3383
/* Save the persistent config to disk */
3384
if (flags & VIR_DOMAIN_AFFECT_CONFIG)
3385
ret = virDomainSaveConfig(driver->configDir, persistentDef);
3388
if (qemuDomainObjEndJob(driver, vm) == 0)
3393
virDomainObjUnlock(vm);
3398
qemuDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
3400
return qemuDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_AFFECT_LIVE);
3405
qemudDomainPinVcpuFlags(virDomainPtr dom,
3407
unsigned char *cpumap,
3409
unsigned int flags) {
3411
struct qemud_driver *driver = dom->conn->privateData;
3413
virDomainDefPtr persistentDef = NULL;
3414
int maxcpu, hostcpus;
3415
virNodeInfo nodeinfo;
3418
qemuDomainObjPrivatePtr priv;
3419
bool canResetting = true;
3422
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
3423
VIR_DOMAIN_AFFECT_CONFIG, -1);
3425
qemuDriverLock(driver);
3426
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
3427
qemuDriverUnlock(driver);
3430
char uuidstr[VIR_UUID_STRING_BUFLEN];
3431
virUUIDFormat(dom->uuid, uuidstr);
3432
qemuReportError(VIR_ERR_NO_DOMAIN,
3433
_("no domain with matching uuid '%s'"), uuidstr);
3437
isActive = virDomainObjIsActive(vm);
3438
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
3440
flags = VIR_DOMAIN_AFFECT_LIVE;
3442
flags = VIR_DOMAIN_AFFECT_CONFIG;
3445
if (!isActive && (flags & VIR_DOMAIN_AFFECT_LIVE)) {
3446
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
3447
_("a domain is inactive; can change only "
3448
"persistent config"));
3452
priv = vm->privateData;
3454
if (vcpu > (priv->nvcpupids-1)) {
3455
qemuReportError(VIR_ERR_INVALID_ARG,
3456
_("vcpu number out of range %d > %d"),
3457
vcpu, priv->nvcpupids);
3461
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
3462
if (!vm->persistent) {
3463
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
3464
_("cannot change persistent config of a transient domain"));
3467
if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
3471
if (nodeGetInfo(dom->conn, &nodeinfo) < 0)
3473
hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo);
3474
maxcpu = maplen * 8;
3475
if (maxcpu > hostcpus)
3477
/* pinning to all physical cpus means resetting,
3478
* so check if we can reset setting.
3480
for (pcpu = 0; pcpu < hostcpus; pcpu++) {
3481
if ((cpumap[pcpu/8] & (1 << (pcpu % 8))) == 0) {
3482
canResetting = false;
3487
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
3489
if (priv->vcpupids != NULL) {
3490
if (virProcessInfoSetAffinity(priv->vcpupids[vcpu],
3491
cpumap, maplen, maxcpu) < 0)
3494
qemuReportError(VIR_ERR_OPERATION_INVALID,
3495
"%s", _("cpu affinity is not supported"));
3500
if (virDomainVcpuPinDel(vm->def, vcpu) < 0) {
3501
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3502
_("failed to delete vcpupin xml of "
3503
"a running domain"));
3507
if (virDomainVcpuPinAdd(vm->def, cpumap, maplen, vcpu) < 0) {
3508
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3509
_("failed to update or add vcpupin xml of "
3510
"a running domain"));
3515
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
3519
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
3522
if (virDomainVcpuPinDel(persistentDef, vcpu) < 0) {
3523
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3524
_("failed to delete vcpupin xml of "
3525
"a persistent domain"));
3529
if (virDomainVcpuPinAdd(persistentDef, cpumap, maplen, vcpu) < 0) {
3530
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3531
_("failed to update or add vcpupin xml of "
3532
"a persistent domain"));
3537
ret = virDomainSaveConfig(driver->configDir, persistentDef);
3545
virDomainObjUnlock(vm);
3550
qemudDomainPinVcpu(virDomainPtr dom,
3552
unsigned char *cpumap,
3554
return qemudDomainPinVcpuFlags(dom, vcpu, cpumap, maplen,
3555
VIR_DOMAIN_AFFECT_LIVE);
3559
qemudDomainGetVcpuPinInfo(virDomainPtr dom,
3561
unsigned char *cpumaps,
3563
unsigned int flags) {
3565
struct qemud_driver *driver = dom->conn->privateData;
3566
virDomainObjPtr vm = NULL;
3567
virNodeInfo nodeinfo;
3568
virDomainDefPtr targetDef = NULL;
3571
int maxcpu, hostcpus, vcpu, pcpu;
3573
virDomainVcpuPinDefPtr *vcpupin_list;
3574
char *cpumask = NULL;
3575
unsigned char *cpumap;
3577
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
3578
VIR_DOMAIN_AFFECT_CONFIG, -1);
3580
qemuDriverLock(driver);
3581
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
3582
qemuDriverUnlock(driver);
3585
char uuidstr[VIR_UUID_STRING_BUFLEN];
3586
virUUIDFormat(dom->uuid, uuidstr);
3587
qemuReportError(VIR_ERR_NO_DOMAIN,
3588
_("no domain with matching uuid '%s'"), uuidstr);
3592
isActive = virDomainObjIsActive(vm);
3593
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
3595
flags = VIR_DOMAIN_AFFECT_LIVE;
3597
flags = VIR_DOMAIN_AFFECT_CONFIG;
3600
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
3602
qemuReportError(VIR_ERR_OPERATION_INVALID,
3603
"%s", _("domain is not running"));
3606
targetDef = vm->def;
3609
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
3610
if (!vm->persistent) {
3611
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
3612
_("cannot get persistent config of a transient domain"));
3615
if (!(targetDef = virDomainObjGetPersistentDef(driver->caps, vm)))
3619
/* Coverity didn't realize that targetDef must be set if we got here. */
3620
sa_assert(targetDef);
3622
if (nodeGetInfo(dom->conn, &nodeinfo) < 0)
3624
hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo);
3625
maxcpu = maplen * 8;
3626
if (maxcpu > hostcpus)
3629
/* Clamp to actual number of vcpus */
3630
if (ncpumaps > targetDef->vcpus)
3631
ncpumaps = targetDef->vcpus;
3637
/* initialize cpumaps */
3638
memset(cpumaps, 0xff, maplen * ncpumaps);
3640
for (vcpu = 0; vcpu < ncpumaps; vcpu++) {
3641
cpumap = VIR_GET_CPUMAP(cpumaps, maplen, vcpu);
3642
cpumap[maplen - 1] &= (1 << maxcpu % 8) - 1;
3646
/* if vcpupin setting exists, there are unused physical cpus */
3647
for (n = 0; n < targetDef->cputune.nvcpupin; n++) {
3648
vcpupin_list = targetDef->cputune.vcpupin;
3649
vcpu = vcpupin_list[n]->vcpuid;
3650
cpumask = vcpupin_list[n]->cpumask;
3651
cpumap = VIR_GET_CPUMAP(cpumaps, maplen, vcpu);
3652
for (pcpu = 0; pcpu < maxcpu; pcpu++) {
3653
if (cpumask[pcpu] == 0)
3654
VIR_UNUSE_CPU(cpumap, pcpu);
3661
virDomainObjUnlock(vm);
3666
qemudDomainGetVcpus(virDomainPtr dom,
3667
virVcpuInfoPtr info,
3669
unsigned char *cpumaps,
3671
struct qemud_driver *driver = dom->conn->privateData;
3673
virNodeInfo nodeinfo;
3674
int i, v, maxcpu, hostcpus;
3676
qemuDomainObjPrivatePtr priv;
3678
qemuDriverLock(driver);
3679
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
3680
qemuDriverUnlock(driver);
3683
char uuidstr[VIR_UUID_STRING_BUFLEN];
3684
virUUIDFormat(dom->uuid, uuidstr);
3685
qemuReportError(VIR_ERR_NO_DOMAIN,
3686
_("no domain with matching uuid '%s'"), uuidstr);
3690
if (!virDomainObjIsActive(vm)) {
3691
qemuReportError(VIR_ERR_OPERATION_INVALID,
3693
_("cannot list vcpu pinning for an inactive domain"));
3697
priv = vm->privateData;
3699
if (nodeGetInfo(dom->conn, &nodeinfo) < 0)
3702
hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo);
3703
maxcpu = maplen * 8;
3704
if (maxcpu > hostcpus)
3707
/* Clamp to actual number of vcpus */
3708
if (maxinfo > priv->nvcpupids)
3709
maxinfo = priv->nvcpupids;
3713
memset(info, 0, sizeof(*info) * maxinfo);
3714
for (i = 0 ; i < maxinfo ; i++) {
3716
info[i].state = VIR_VCPU_RUNNING;
3718
if (priv->vcpupids != NULL &&
3719
qemudGetProcessInfo(&(info[i].cpuTime),
3722
priv->vcpupids[i]) < 0) {
3723
virReportSystemError(errno, "%s",
3724
_("cannot get vCPU placement & pCPU time"));
3730
if (cpumaps != NULL) {
3731
memset(cpumaps, 0, maplen * maxinfo);
3732
if (priv->vcpupids != NULL) {
3733
for (v = 0 ; v < maxinfo ; v++) {
3734
unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, v);
3736
if (virProcessInfoGetAffinity(priv->vcpupids[v],
3737
cpumap, maplen, maxcpu) < 0)
3741
qemuReportError(VIR_ERR_OPERATION_INVALID,
3742
"%s", _("cpu affinity is not available"));
3751
virDomainObjUnlock(vm);
3757
qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
3759
struct qemud_driver *driver = dom->conn->privateData;
3761
virDomainDefPtr def;
3765
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
3766
VIR_DOMAIN_AFFECT_CONFIG |
3767
VIR_DOMAIN_VCPU_MAXIMUM, -1);
3769
qemuDriverLock(driver);
3770
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
3771
qemuDriverUnlock(driver);
3774
char uuidstr[VIR_UUID_STRING_BUFLEN];
3775
virUUIDFormat(dom->uuid, uuidstr);
3776
qemuReportError(VIR_ERR_NO_DOMAIN,
3777
_("no domain with matching uuid '%s'"), uuidstr);
3781
active = virDomainObjIsActive(vm);
3783
if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) {
3785
flags |= VIR_DOMAIN_VCPU_LIVE;
3787
flags |= VIR_DOMAIN_VCPU_CONFIG;
3789
if ((flags & VIR_DOMAIN_AFFECT_LIVE) && (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
3790
qemuReportError(VIR_ERR_INVALID_ARG,
3791
_("invalid flag combination: (0x%x)"), flags);
3795
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
3797
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
3798
_("domain not active"));
3803
if (!vm->persistent) {
3804
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
3805
_("domain is transient"));
3808
def = vm->newDef ? vm->newDef : vm->def;
3811
ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;
3815
virDomainObjUnlock(vm);
3820
qemudDomainGetMaxVcpus(virDomainPtr dom)
3822
return qemudDomainGetVcpusFlags(dom, (VIR_DOMAIN_AFFECT_LIVE |
3823
VIR_DOMAIN_VCPU_MAXIMUM));
3826
static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr seclabel)
3828
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
3832
qemuDriverLock(driver);
3833
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
3835
memset(seclabel, 0, sizeof(*seclabel));
3838
char uuidstr[VIR_UUID_STRING_BUFLEN];
3839
virUUIDFormat(dom->uuid, uuidstr);
3840
qemuReportError(VIR_ERR_NO_DOMAIN,
3841
_("no domain with matching uuid '%s'"), uuidstr);
3845
if (!virDomainVirtTypeToString(vm->def->virtType)) {
3846
qemuReportError(VIR_ERR_INTERNAL_ERROR,
3847
_("unknown virt type in domain definition '%d'"),
3853
* Theoretically, the pid can be replaced during this operation and
3854
* return the label of a different process. If atomicity is needed,
3855
* further validation will be required.
3857
* Comment from Dan Berrange:
3859
* Well the PID as stored in the virDomainObjPtr can't be changed
3860
* because you've got a locked object. The OS level PID could have
3861
* exited, though and in extreme circumstances have cycled through all
3862
* PIDs back to ours. We could sanity check that our PID still exists
3863
* after reading the label, by checking that our FD connecting to the
3864
* QEMU monitor hasn't seen SIGHUP/ERR on poll().
3866
if (virDomainObjIsActive(vm)) {
3867
if (virSecurityManagerGetProcessLabel(driver->securityManager,
3868
vm, seclabel) < 0) {
3869
qemuReportError(VIR_ERR_INTERNAL_ERROR,
3870
"%s", _("Failed to get security label"));
3879
virDomainObjUnlock(vm);
3880
qemuDriverUnlock(driver);
3884
static int qemudNodeGetSecurityModel(virConnectPtr conn,
3885
virSecurityModelPtr secmodel)
3887
struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
3891
qemuDriverLock(driver);
3892
memset(secmodel, 0, sizeof(*secmodel));
3894
/* NULL indicates no driver, which we treat as
3895
* success, but simply return no data in *secmodel */
3896
if (driver->caps->host.secModel.model == NULL)
3899
p = driver->caps->host.secModel.model;
3900
if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) {
3901
qemuReportError(VIR_ERR_INTERNAL_ERROR,
3902
_("security model string exceeds max %d bytes"),
3903
VIR_SECURITY_MODEL_BUFLEN-1);
3907
strcpy(secmodel->model, p);
3909
p = driver->caps->host.secModel.doi;
3910
if (strlen(p) >= VIR_SECURITY_DOI_BUFLEN-1) {
3911
qemuReportError(VIR_ERR_INTERNAL_ERROR,
3912
_("security DOI string exceeds max %d bytes"),
3913
VIR_SECURITY_DOI_BUFLEN-1);
3917
strcpy(secmodel->doi, p);
3920
qemuDriverUnlock(driver);
3924
/* Return -1 on most failures after raising error, -2 if edit was specified
3925
* but xmlin and state (-1 for no change, 0 for paused, 1 for running) do
3926
* not represent any changes (no error raised), -3 if corrupt image was
3927
* unlinked (no error raised), and opened fd on success. */
3928
static int ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
3929
qemuDomainSaveImageOpen(struct qemud_driver *driver,
3931
virDomainDefPtr *ret_def,
3932
struct qemud_save_header *ret_header,
3933
bool bypass_cache, virFileDirectFdPtr *directFd,
3934
const char *xmlin, int state, bool edit,
3935
bool unlink_corrupt)
3938
struct qemud_save_header header;
3940
virDomainDefPtr def = NULL;
3941
int oflags = edit ? O_RDWR : O_RDONLY;
3944
int directFlag = virFileDirectFdFlag();
3945
if (directFlag < 0) {
3946
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
3947
_("bypass cache unsupported by this system"));
3950
oflags |= directFlag;
3953
if ((fd = qemuOpenFile(driver, path, oflags, NULL, NULL)) < 0)
3955
if (bypass_cache && (*directFd = virFileDirectFdNew(&fd, path)) == NULL)
3958
if (saferead(fd, &header, sizeof(header)) != sizeof(header)) {
3959
qemuReportError(VIR_ERR_OPERATION_FAILED,
3960
"%s", _("failed to read qemu header"));
3964
if (memcmp(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic)) != 0) {
3965
const char *msg = _("image magic is incorrect");
3967
if (memcmp(header.magic, QEMUD_SAVE_PARTIAL,
3968
sizeof(header.magic)) == 0) {
3969
msg = _("save image is incomplete");
3970
if (unlink_corrupt) {
3971
if (VIR_CLOSE(fd) < 0 || unlink(path) < 0) {
3972
virReportSystemError(errno,
3973
_("cannot remove corrupt file: %s"),
3980
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", msg);
3984
if (header.version > QEMUD_SAVE_VERSION) {
3985
/* convert endianess and try again */
3986
bswap_header(&header);
3989
if (header.version > QEMUD_SAVE_VERSION) {
3990
qemuReportError(VIR_ERR_OPERATION_FAILED,
3991
_("image version is not supported (%d > %d)"),
3992
header.version, QEMUD_SAVE_VERSION);
3996
if (header.xml_len <= 0) {
3997
qemuReportError(VIR_ERR_OPERATION_FAILED,
3998
_("invalid XML length: %d"), header.xml_len);
4002
if (VIR_ALLOC_N(xml, header.xml_len) < 0) {
4003
virReportOOMError();
4007
if (saferead(fd, xml, header.xml_len) != header.xml_len) {
4008
qemuReportError(VIR_ERR_OPERATION_FAILED,
4009
"%s", _("failed to read XML"));
4013
if (edit && STREQ(xml, xmlin) &&
4014
(state < 0 || state == header.was_running)) {
4016
if (VIR_CLOSE(fd) < 0) {
4017
virReportSystemError(errno, _("cannot close file: %s"), path);
4023
header.was_running = state;
4025
/* Create a domain from this XML */
4026
if (!(def = virDomainDefParseString(driver->caps, xml,
4027
QEMU_EXPECTED_VIRT_TYPES,
4028
VIR_DOMAIN_XML_INACTIVE)))
4031
virDomainDefPtr def2 = NULL;
4033
if (!(def2 = virDomainDefParseString(driver->caps, xmlin,
4034
QEMU_EXPECTED_VIRT_TYPES,
4035
VIR_DOMAIN_XML_INACTIVE)))
4037
if (!virDomainDefCheckABIStability(def, def2)) {
4038
virDomainDefFree(def2);
4041
virDomainDefFree(def);
4048
*ret_header = header;
4053
virDomainDefFree(def);
4055
VIR_FORCE_CLOSE(fd);
4060
static int ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6)
4061
qemuDomainSaveImageStartVM(virConnectPtr conn,
4062
struct qemud_driver *driver,
4065
const struct qemud_save_header *header,
4070
virDomainEventPtr event;
4071
int intermediatefd = -1;
4072
virCommandPtr cmd = NULL;
4074
if (header->version == 2) {
4075
const char *prog = qemudSaveCompressionTypeToString(header->compressed);
4077
qemuReportError(VIR_ERR_OPERATION_FAILED,
4078
_("Invalid compressed save format %d"),
4079
header->compressed);
4083
if (header->compressed != QEMUD_SAVE_FORMAT_RAW) {
4084
cmd = virCommandNewArgList(prog, "-dc", NULL);
4085
intermediatefd = *fd;
4088
virCommandSetInputFD(cmd, intermediatefd);
4089
virCommandSetOutputFD(cmd, fd);
4091
if (virCommandRunAsync(cmd, NULL) < 0) {
4092
qemuReportError(VIR_ERR_INTERNAL_ERROR,
4093
_("Failed to start decompression binary %s"),
4095
*fd = intermediatefd;
4101
/* Set the migration source and start it up. */
4102
ret = qemuProcessStart(conn, driver, vm, "stdio", true,
4103
false, *fd, path, NULL, VIR_NETDEV_VPORT_PROFILE_OP_RESTORE);
4105
if (intermediatefd != -1) {
4107
/* if there was an error setting up qemu, the intermediate
4108
* process will wait forever to write to stdout, so we
4109
* must manually kill it.
4111
VIR_FORCE_CLOSE(intermediatefd);
4112
VIR_FORCE_CLOSE(*fd);
4115
if (virCommandWait(cmd, NULL) < 0)
4118
VIR_FORCE_CLOSE(intermediatefd);
4120
if (VIR_CLOSE(*fd) < 0) {
4121
virReportSystemError(errno, _("cannot close file: %s"), path);
4126
virDomainAuditStart(vm, "restored", false);
4130
event = virDomainEventNewFromObj(vm,
4131
VIR_DOMAIN_EVENT_STARTED,
4132
VIR_DOMAIN_EVENT_STARTED_RESTORED);
4133
virDomainAuditStart(vm, "restored", true);
4135
qemuDomainEventQueue(driver, event);
4138
/* If it was running before, resume it now unless caller requested pause. */
4139
if (header->was_running && !start_paused) {
4140
if (qemuProcessStartCPUs(driver, vm, conn,
4141
VIR_DOMAIN_RUNNING_RESTORED,
4142
QEMU_ASYNC_JOB_NONE) < 0) {
4143
if (virGetLastError() == NULL)
4144
qemuReportError(VIR_ERR_OPERATION_FAILED,
4145
"%s", _("failed to resume domain"));
4148
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
4149
VIR_WARN("Failed to save status on vm %s", vm->def->name);
4153
int detail = (start_paused ? VIR_DOMAIN_EVENT_SUSPENDED_PAUSED :
4154
VIR_DOMAIN_EVENT_SUSPENDED_RESTORED);
4155
event = virDomainEventNewFromObj(vm,
4156
VIR_DOMAIN_EVENT_SUSPENDED,
4159
qemuDomainEventQueue(driver, event);
4165
virCommandFree(cmd);
4166
if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
4168
VIR_WARN("failed to restore save state label on %s", path);
4174
qemuDomainRestoreFlags(virConnectPtr conn,
4179
struct qemud_driver *driver = conn->privateData;
4180
virDomainDefPtr def = NULL;
4181
virDomainObjPtr vm = NULL;
4184
struct qemud_save_header header;
4185
virFileDirectFdPtr directFd = NULL;
4188
virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
4189
VIR_DOMAIN_SAVE_RUNNING |
4190
VIR_DOMAIN_SAVE_PAUSED, -1);
4192
qemuDriverLock(driver);
4194
if (flags & VIR_DOMAIN_SAVE_RUNNING)
4196
else if (flags & VIR_DOMAIN_SAVE_PAUSED)
4199
fd = qemuDomainSaveImageOpen(driver, path, &def, &header,
4200
(flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
4201
&directFd, dxml, state, false, false);
4205
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
4208
if (!(vm = virDomainAssignDef(driver->caps,
4211
/* virDomainAssignDef already set the error */
4216
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
4219
ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path,
4221
if (virFileDirectFdClose(directFd) < 0)
4222
VIR_WARN("Failed to close %s", path);
4224
if (qemuDomainObjEndJob(driver, vm) == 0)
4226
else if (ret < 0 && !vm->persistent) {
4227
qemuDomainRemoveInactive(driver, vm);
4232
virDomainDefFree(def);
4233
VIR_FORCE_CLOSE(fd);
4234
virFileDirectFdFree(directFd);
4236
virDomainObjUnlock(vm);
4237
qemuDriverUnlock(driver);
4242
qemuDomainRestore(virConnectPtr conn,
4245
return qemuDomainRestoreFlags(conn, path, NULL, 0);
4249
qemuDomainSaveImageGetXMLDesc(virConnectPtr conn, const char *path,
4252
struct qemud_driver *driver = conn->privateData;
4254
virDomainDefPtr def = NULL;
4256
struct qemud_save_header header;
4258
/* We only take subset of virDomainDefFormat flags. */
4259
virCheckFlags(VIR_DOMAIN_XML_SECURE, NULL);
4261
qemuDriverLock(driver);
4263
fd = qemuDomainSaveImageOpen(driver, path, &def, &header, false, NULL,
4264
NULL, -1, false, false);
4269
ret = qemuDomainDefFormatXML(driver, def, flags);
4272
virDomainDefFree(def);
4273
VIR_FORCE_CLOSE(fd);
4274
qemuDriverUnlock(driver);
4279
qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path,
4280
const char *dxml, unsigned int flags)
4282
struct qemud_driver *driver = conn->privateData;
4284
virDomainDefPtr def = NULL;
4286
struct qemud_save_header header;
4291
virCheckFlags(VIR_DOMAIN_SAVE_RUNNING |
4292
VIR_DOMAIN_SAVE_PAUSED, -1);
4294
qemuDriverLock(driver);
4296
if (flags & VIR_DOMAIN_SAVE_RUNNING)
4298
else if (flags & VIR_DOMAIN_SAVE_PAUSED)
4301
fd = qemuDomainSaveImageOpen(driver, path, &def, &header, false, NULL,
4302
dxml, state, true, false);
4305
/* Check for special case of no change needed. */
4311
xml = qemuDomainDefFormatXML(driver, def, (VIR_DOMAIN_XML_INACTIVE |
4312
VIR_DOMAIN_XML_SECURE));
4315
len = strlen(xml) + 1;
4317
if (len > header.xml_len) {
4318
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
4319
_("new xml too large to fit in file"));
4322
if (VIR_EXPAND_N(xml, len, header.xml_len - len) < 0) {
4323
virReportOOMError();
4327
if (lseek(fd, 0, SEEK_SET) != 0) {
4328
virReportSystemError(errno, _("cannot seek in '%s'"), path);
4331
if (safewrite(fd, &header, sizeof(header)) != sizeof(header) ||
4332
safewrite(fd, xml, len) != len ||
4333
VIR_CLOSE(fd) < 0) {
4334
virReportSystemError(errno, _("failed to write xml to '%s'"), path);
4341
virDomainDefFree(def);
4342
VIR_FORCE_CLOSE(fd);
4344
qemuDriverUnlock(driver);
4348
/* Return 0 on success, 1 if incomplete saved image was silently unlinked,
4349
* and -1 on failure with error raised. */
4351
qemuDomainObjRestore(virConnectPtr conn,
4352
struct qemud_driver *driver,
4358
virDomainDefPtr def = NULL;
4361
struct qemud_save_header header;
4362
virFileDirectFdPtr directFd = NULL;
4364
fd = qemuDomainSaveImageOpen(driver, path, &def, &header,
4365
bypass_cache, &directFd, NULL, -1, false,
4373
if (STRNEQ(vm->def->name, def->name) ||
4374
memcmp(vm->def->uuid, def->uuid, VIR_UUID_BUFLEN)) {
4375
char vm_uuidstr[VIR_UUID_STRING_BUFLEN];
4376
char def_uuidstr[VIR_UUID_STRING_BUFLEN];
4377
virUUIDFormat(vm->def->uuid, vm_uuidstr);
4378
virUUIDFormat(def->uuid, def_uuidstr);
4379
qemuReportError(VIR_ERR_OPERATION_FAILED,
4380
_("cannot restore domain '%s' uuid %s from a file"
4381
" which belongs to domain '%s' uuid %s"),
4382
vm->def->name, vm_uuidstr,
4383
def->name, def_uuidstr);
4387
virDomainObjAssignDef(vm, def, true);
4390
ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path,
4392
if (virFileDirectFdClose(directFd) < 0)
4393
VIR_WARN("Failed to close %s", path);
4396
virDomainDefFree(def);
4397
VIR_FORCE_CLOSE(fd);
4398
virFileDirectFdFree(directFd);
4403
static char *qemuDomainGetXMLDesc(virDomainPtr dom,
4406
struct qemud_driver *driver = dom->conn->privateData;
4409
unsigned long balloon;
4412
/* Flags checked by virDomainDefFormat */
4414
qemuDriverLock(driver);
4415
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
4418
char uuidstr[VIR_UUID_STRING_BUFLEN];
4419
virUUIDFormat(dom->uuid, uuidstr);
4420
qemuReportError(VIR_ERR_NO_DOMAIN,
4421
_("no domain with matching uuid '%s'"), uuidstr);
4425
/* Refresh current memory based on balloon info if supported */
4426
if ((vm->def->memballoon != NULL) &&
4427
(vm->def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) &&
4428
(virDomainObjIsActive(vm))) {
4429
qemuDomainObjPrivatePtr priv = vm->privateData;
4430
/* Don't delay if someone's using the monitor, just use
4431
* existing most recent data instead */
4432
if (qemuDomainJobAllowed(priv, QEMU_JOB_QUERY)) {
4433
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_QUERY) < 0)
4436
if (!virDomainObjIsActive(vm)) {
4437
qemuReportError(VIR_ERR_OPERATION_INVALID,
4438
"%s", _("domain is not running"));
4442
qemuDomainObjEnterMonitorWithDriver(driver, vm);
4443
err = qemuMonitorGetBalloonInfo(priv->mon, &balloon);
4444
qemuDomainObjExitMonitorWithDriver(driver, vm);
4447
if (qemuDomainObjEndJob(driver, vm) == 0) {
4454
vm->def->mem.cur_balloon = balloon;
4455
/* err == 0 indicates no balloon support, so ignore it */
4459
ret = qemuDomainFormatXML(driver, vm, flags);
4463
virDomainObjUnlock(vm);
4464
qemuDriverUnlock(driver);
4469
static char *qemuDomainXMLFromNative(virConnectPtr conn,
4474
struct qemud_driver *driver = conn->privateData;
4475
virDomainDefPtr def = NULL;
4478
virCheckFlags(0, NULL);
4480
if (STRNEQ(format, QEMU_CONFIG_FORMAT_ARGV)) {
4481
qemuReportError(VIR_ERR_INVALID_ARG,
4482
_("unsupported config type %s"), format);
4486
qemuDriverLock(driver);
4487
def = qemuParseCommandLineString(driver->caps, config,
4489
qemuDriverUnlock(driver);
4494
!(def->name = strdup("unnamed"))) {
4495
virReportOOMError();
4499
xml = virDomainDefFormat(def, VIR_DOMAIN_XML_INACTIVE);
4502
virDomainDefFree(def);
4506
static char *qemuDomainXMLToNative(virConnectPtr conn,
4508
const char *xmlData,
4511
struct qemud_driver *driver = conn->privateData;
4512
virDomainDefPtr def = NULL;
4513
virDomainChrSourceDef monConfig;
4514
virBitmapPtr qemuCaps = NULL;
4515
bool monitor_json = false;
4516
virCommandPtr cmd = NULL;
4520
virCheckFlags(0, NULL);
4522
qemuDriverLock(driver);
4524
if (STRNEQ(format, QEMU_CONFIG_FORMAT_ARGV)) {
4525
qemuReportError(VIR_ERR_INVALID_ARG,
4526
_("unsupported config type %s"), format);
4530
def = virDomainDefParseString(driver->caps, xmlData,
4531
QEMU_EXPECTED_VIRT_TYPES, 0);
4535
/* Since we're just exporting args, we can't do bridge/network/direct
4536
* setups, since libvirt will normally create TAP/macvtap devices
4537
* directly. We convert those configs into generic 'ethernet'
4538
* config and assume the user has suitable 'ifup-qemu' scripts
4540
for (i = 0 ; i < def->nnets ; i++) {
4541
virDomainNetDefPtr net = def->nets[i];
4542
int bootIndex = net->bootIndex;
4543
if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
4544
int actualType = virDomainNetGetActualType(net);
4547
VIR_FREE(net->data.network.name);
4548
VIR_FREE(net->data.network.portgroup);
4549
if ((actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) &&
4550
(brname = virDomainNetGetActualBridgeName(net))) {
4552
char *brnamecopy = strdup(brname);
4554
virReportOOMError();
4558
virDomainActualNetDefFree(net->data.network.actual);
4560
memset(net, 0, sizeof *net);
4562
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
4563
net->data.ethernet.dev = brnamecopy;
4564
net->data.ethernet.script = NULL;
4565
net->data.ethernet.ipaddr = NULL;
4567
/* actualType is either NETWORK or DIRECT. In either
4568
* case, the best we can do is NULL everything out.
4570
virDomainActualNetDefFree(net->data.network.actual);
4571
memset(net, 0, sizeof *net);
4573
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
4574
net->data.ethernet.dev = NULL;
4575
net->data.ethernet.script = NULL;
4576
net->data.ethernet.ipaddr = NULL;
4578
} else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
4579
VIR_FREE(net->data.direct.linkdev);
4580
VIR_FREE(net->data.direct.virtPortProfile);
4582
memset(net, 0, sizeof *net);
4584
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
4585
net->data.ethernet.dev = NULL;
4586
net->data.ethernet.script = NULL;
4587
net->data.ethernet.ipaddr = NULL;
4588
} else if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
4589
char *brname = net->data.bridge.brname;
4590
char *script = net->data.bridge.script;
4591
char *ipaddr = net->data.bridge.ipaddr;
4593
memset(net, 0, sizeof *net);
4595
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
4596
net->data.ethernet.dev = brname;
4597
net->data.ethernet.script = script;
4598
net->data.ethernet.ipaddr = ipaddr;
4600
net->bootIndex = bootIndex;
4602
for (i = 0 ; i < def->ngraphics ; i++) {
4603
if (def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
4604
def->graphics[i]->data.vnc.autoport)
4605
def->graphics[i]->data.vnc.port = QEMU_VNC_PORT_MIN;
4608
if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch,
4613
monitor_json = qemuCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON);
4615
if (qemuProcessPrepareMonitorChr(driver, &monConfig, def->name) < 0)
4618
if (qemuAssignDeviceAliases(def, qemuCaps) < 0)
4621
if (!(cmd = qemuBuildCommandLine(conn, driver, def,
4622
&monConfig, monitor_json, qemuCaps,
4623
NULL, -1, NULL, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP)))
4626
ret = virCommandToString(cmd);
4629
qemuDriverUnlock(driver);
4631
qemuCapsFree(qemuCaps);
4632
virCommandFree(cmd);
4633
virDomainDefFree(def);
4638
static int qemudListDefinedDomains(virConnectPtr conn,
4639
char **const names, int nnames) {
4640
struct qemud_driver *driver = conn->privateData;
4643
qemuDriverLock(driver);
4644
n = virDomainObjListGetInactiveNames(&driver->domains, names, nnames);
4645
qemuDriverUnlock(driver);
4649
static int qemudNumDefinedDomains(virConnectPtr conn) {
4650
struct qemud_driver *driver = conn->privateData;
4653
qemuDriverLock(driver);
4654
n = virDomainObjListNumOfDomains(&driver->domains, 0);
4655
qemuDriverUnlock(driver);
4662
qemuDomainObjStart(virConnectPtr conn,
4663
struct qemud_driver *driver,
4669
bool start_paused = (flags & VIR_DOMAIN_START_PAUSED) != 0;
4670
bool autodestroy = (flags & VIR_DOMAIN_START_AUTODESTROY) != 0;
4671
bool bypass_cache = (flags & VIR_DOMAIN_START_BYPASS_CACHE) != 0;
4672
bool force_boot = (flags & VIR_DOMAIN_START_FORCE_BOOT) != 0;
4675
* If there is a managed saved state restore it instead of starting
4676
* from scratch. The old state is removed once the restoring succeeded.
4678
managed_save = qemuDomainManagedSavePath(driver, vm);
4683
if (virFileExists(managed_save)) {
4685
if (unlink(managed_save) < 0) {
4686
virReportSystemError(errno,
4687
_("cannot remove managed save file %s"),
4692
ret = qemuDomainObjRestore(conn, driver, vm, managed_save,
4693
start_paused, bypass_cache);
4695
if (ret == 0 && unlink(managed_save) < 0)
4696
VIR_WARN("Failed to remove the managed state %s", managed_save);
4698
VIR_WARN("Ignoring incomplete managed state %s", managed_save);
4704
ret = qemuProcessStart(conn, driver, vm, NULL, start_paused,
4705
autodestroy, -1, NULL, NULL, VIR_NETDEV_VPORT_PROFILE_OP_CREATE);
4706
virDomainAuditStart(vm, "booted", ret >= 0);
4708
virDomainEventPtr event =
4709
virDomainEventNewFromObj(vm,
4710
VIR_DOMAIN_EVENT_STARTED,
4711
VIR_DOMAIN_EVENT_STARTED_BOOTED);
4713
qemuDomainEventQueue(driver, event);
4715
event = virDomainEventNewFromObj(vm,
4716
VIR_DOMAIN_EVENT_SUSPENDED,
4717
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
4719
qemuDomainEventQueue(driver, event);
4725
VIR_FREE(managed_save);
4730
qemuDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
4732
struct qemud_driver *driver = dom->conn->privateData;
4736
virCheckFlags(VIR_DOMAIN_START_PAUSED |
4737
VIR_DOMAIN_START_AUTODESTROY |
4738
VIR_DOMAIN_START_BYPASS_CACHE |
4739
VIR_DOMAIN_START_FORCE_BOOT, -1);
4741
qemuDriverLock(driver);
4742
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
4745
char uuidstr[VIR_UUID_STRING_BUFLEN];
4746
virUUIDFormat(dom->uuid, uuidstr);
4747
qemuReportError(VIR_ERR_NO_DOMAIN,
4748
_("no domain with matching uuid '%s'"), uuidstr);
4752
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
4755
if (virDomainObjIsActive(vm)) {
4756
qemuReportError(VIR_ERR_OPERATION_INVALID,
4757
"%s", _("domain is already running"));
4761
if (qemuDomainObjStart(dom->conn, driver, vm, flags) < 0)
4767
if (qemuDomainObjEndJob(driver, vm) == 0)
4772
virDomainObjUnlock(vm);
4773
qemuDriverUnlock(driver);
4778
qemuDomainStart(virDomainPtr dom)
4780
return qemuDomainStartWithFlags(dom, 0);
4784
qemudCanonicalizeMachineFromInfo(virDomainDefPtr def,
4785
virCapsGuestDomainInfoPtr info,
4792
for (i = 0; i < info->nmachines; i++) {
4793
virCapsGuestMachinePtr machine = info->machines[i];
4795
if (!machine->canonical)
4798
if (def->os.machine && STRNEQ(def->os.machine, machine->name))
4801
if (!(*canonical = strdup(machine->canonical))) {
4802
virReportOOMError();
4813
qemudCanonicalizeMachineDirect(virDomainDefPtr def, char **canonical)
4815
virCapsGuestMachinePtr *machines = NULL;
4816
int i, nmachines = 0;
4818
if (qemuCapsProbeMachineTypes(def->emulator, &machines, &nmachines) < 0)
4821
for (i = 0; i < nmachines; i++) {
4822
if (!machines[i]->canonical)
4825
if (def->os.machine && STRNEQ(def->os.machine, machines[i]->name))
4828
*canonical = machines[i]->canonical;
4829
machines[i]->canonical = NULL;
4833
virCapabilitiesFreeMachines(machines, nmachines);
4839
qemudCanonicalizeMachine(struct qemud_driver *driver, virDomainDefPtr def)
4841
char *canonical = NULL;
4844
for (i = 0; i < driver->caps->nguests; i++) {
4845
virCapsGuestPtr guest = driver->caps->guests[i];
4846
virCapsGuestDomainInfoPtr info;
4849
for (j = 0; j < guest->arch.ndomains; j++) {
4850
info = &guest->arch.domains[j]->info;
4852
if (!info->emulator || !STREQ(info->emulator, def->emulator))
4855
if (!info->nmachines)
4856
info = &guest->arch.defaultInfo;
4858
if (qemudCanonicalizeMachineFromInfo(def, info, &canonical) < 0)
4863
info = &guest->arch.defaultInfo;
4865
if (info->emulator && STREQ(info->emulator, def->emulator)) {
4866
if (qemudCanonicalizeMachineFromInfo(def, info, &canonical) < 0)
4872
if (qemudCanonicalizeMachineDirect(def, &canonical) < 0)
4877
VIR_FREE(def->os.machine);
4878
def->os.machine = canonical;
4883
static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
4884
struct qemud_driver *driver = conn->privateData;
4885
virDomainDefPtr def;
4886
virDomainObjPtr vm = NULL;
4887
virDomainPtr dom = NULL;
4888
virDomainEventPtr event = NULL;
4891
qemuDriverLock(driver);
4892
if (!(def = virDomainDefParseString(driver->caps, xml,
4893
QEMU_EXPECTED_VIRT_TYPES,
4894
VIR_DOMAIN_XML_INACTIVE)))
4897
if (virSecurityManagerVerify(driver->securityManager, def) < 0)
4900
if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
4903
if (qemudCanonicalizeMachine(driver, def) < 0)
4906
if (qemuDomainAssignPCIAddresses(def) < 0)
4909
if (!(vm = virDomainAssignDef(driver->caps,
4917
if (virDomainSaveConfig(driver->configDir,
4918
vm->newDef ? vm->newDef : vm->def) < 0) {
4919
VIR_INFO("Defining domain '%s'", vm->def->name);
4920
qemuDomainRemoveInactive(driver, vm);
4925
event = virDomainEventNewFromObj(vm,
4926
VIR_DOMAIN_EVENT_DEFINED,
4928
VIR_DOMAIN_EVENT_DEFINED_ADDED :
4929
VIR_DOMAIN_EVENT_DEFINED_UPDATED);
4931
VIR_INFO("Creating domain '%s'", vm->def->name);
4932
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
4933
if (dom) dom->id = vm->def->id;
4936
virDomainDefFree(def);
4938
virDomainObjUnlock(vm);
4940
qemuDomainEventQueue(driver, event);
4941
qemuDriverUnlock(driver);
4946
qemuDomainUndefineFlags(virDomainPtr dom,
4949
struct qemud_driver *driver = dom->conn->privateData;
4951
virDomainEventPtr event = NULL;
4956
virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE |
4957
VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA, -1);
4959
qemuDriverLock(driver);
4960
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
4963
char uuidstr[VIR_UUID_STRING_BUFLEN];
4964
virUUIDFormat(dom->uuid, uuidstr);
4965
qemuReportError(VIR_ERR_NO_DOMAIN,
4966
_("no domain with matching uuid '%s'"), uuidstr);
4970
if (!vm->persistent) {
4971
qemuReportError(VIR_ERR_OPERATION_INVALID,
4972
"%s", _("cannot undefine transient domain"));
4976
if (!virDomainObjIsActive(vm) &&
4977
(nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, 0))) {
4978
if (!(flags & VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA)) {
4979
qemuReportError(VIR_ERR_OPERATION_INVALID,
4980
_("cannot delete inactive domain with %d "
4985
if (qemuDomainSnapshotDiscardAllMetadata(driver, vm) < 0)
4989
name = qemuDomainManagedSavePath(driver, vm);
4993
if (virFileExists(name)) {
4994
if (flags & VIR_DOMAIN_UNDEFINE_MANAGED_SAVE) {
4995
if (unlink(name) < 0) {
4996
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
4997
_("Failed to remove domain managed "
5002
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
5003
_("Refusing to undefine while domain managed "
5004
"save image exists"));
5009
if (virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm) < 0)
5012
event = virDomainEventNewFromObj(vm,
5013
VIR_DOMAIN_EVENT_UNDEFINED,
5014
VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
5016
VIR_INFO("Undefining domain '%s'", vm->def->name);
5018
/* If the domain is active, keep it running but set it as transient.
5019
* domainDestroy and domainShutdown will take care of removing the
5020
* domain obj from the hash table.
5022
if (virDomainObjIsActive(vm)) {
5025
qemuDomainRemoveInactive(driver, vm);
5034
virDomainObjUnlock(vm);
5036
qemuDomainEventQueue(driver, event);
5037
qemuDriverUnlock(driver);
5042
qemudDomainUndefine(virDomainPtr dom)
5044
return qemuDomainUndefineFlags(dom, 0);
5048
qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
5049
struct qemud_driver *driver,
5051
virDomainDeviceDefPtr dev)
5053
virDomainDiskDefPtr disk = dev->data.disk;
5054
virCgroupPtr cgroup = NULL;
5057
if (disk->driverName != NULL && !STREQ(disk->driverName, "qemu")) {
5058
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5059
_("unsupported driver name '%s' for disk '%s'"),
5060
disk->driverName, disk->src);
5064
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
5065
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0)) {
5066
qemuReportError(VIR_ERR_INTERNAL_ERROR,
5067
_("Unable to find cgroup for %s"),
5071
if (qemuSetupDiskCgroup(driver, vm, cgroup, disk) < 0)
5074
switch (disk->device) {
5075
case VIR_DOMAIN_DISK_DEVICE_CDROM:
5076
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
5077
ret = qemuDomainChangeEjectableMedia(driver, vm, disk, false);
5079
case VIR_DOMAIN_DISK_DEVICE_DISK:
5080
if (disk->bus == VIR_DOMAIN_DISK_BUS_USB)
5081
ret = qemuDomainAttachUsbMassstorageDevice(conn, driver, vm,
5083
else if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
5084
ret = qemuDomainAttachPciDiskDevice(conn, driver, vm, disk);
5085
else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI)
5086
ret = qemuDomainAttachSCSIDisk(conn, driver, vm, disk);
5088
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5089
_("disk bus '%s' cannot be hotplugged."),
5090
virDomainDiskBusTypeToString(disk->bus));
5093
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5094
_("disk device type '%s' cannot be hotplugged"),
5095
virDomainDiskDeviceTypeToString(disk->device));
5099
if (ret != 0 && cgroup) {
5100
if (qemuTeardownDiskCgroup(driver, vm, cgroup, disk) < 0)
5101
VIR_WARN("Failed to teardown cgroup for disk path %s",
5102
NULLSTR(disk->src));
5106
virCgroupFree(&cgroup);
5111
qemuDomainAttachDeviceControllerLive(struct qemud_driver *driver,
5113
virDomainDeviceDefPtr dev)
5115
virDomainControllerDefPtr cont = dev->data.controller;
5118
switch (cont->type) {
5119
case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
5120
ret = qemuDomainAttachPciControllerDevice(driver, vm, cont);
5123
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5124
_("disk controller bus '%s' cannot be hotplugged."),
5125
virDomainControllerTypeToString(cont->type));
5132
qemuDomainAttachDeviceLive(virDomainObjPtr vm,
5133
virDomainDeviceDefPtr dev,
5136
struct qemud_driver *driver = dom->conn->privateData;
5139
switch (dev->type) {
5140
case VIR_DOMAIN_DEVICE_DISK:
5141
qemuDomainObjCheckDiskTaint(driver, vm, dev->data.disk, -1);
5142
ret = qemuDomainAttachDeviceDiskLive(dom->conn, driver, vm, dev);
5144
dev->data.disk = NULL;
5147
case VIR_DOMAIN_DEVICE_CONTROLLER:
5148
ret = qemuDomainAttachDeviceControllerLive(driver, vm, dev);
5150
dev->data.controller = NULL;
5153
case VIR_DOMAIN_DEVICE_LEASE:
5154
ret = qemuDomainAttachLease(driver, vm,
5157
dev->data.lease = NULL;
5160
case VIR_DOMAIN_DEVICE_NET:
5161
qemuDomainObjCheckNetTaint(driver, vm, dev->data.net, -1);
5162
ret = qemuDomainAttachNetDevice(dom->conn, driver, vm,
5165
dev->data.net = NULL;
5168
case VIR_DOMAIN_DEVICE_HOSTDEV:
5169
ret = qemuDomainAttachHostDevice(driver, vm,
5172
dev->data.hostdev = NULL;
5175
case VIR_DOMAIN_DEVICE_REDIRDEV:
5176
ret = qemuDomainAttachRedirdevDevice(driver, vm,
5177
dev->data.redirdev);
5179
dev->data.redirdev = NULL;
5183
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5184
_("device type '%s' cannot be attached"),
5185
virDomainDeviceTypeToString(dev->type));
5193
qemuDomainDetachDeviceDiskLive(struct qemud_driver *driver,
5195
virDomainDeviceDefPtr dev)
5197
virDomainDiskDefPtr disk = dev->data.disk;
5200
switch (disk->device) {
5201
case VIR_DOMAIN_DISK_DEVICE_DISK:
5202
if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
5203
ret = qemuDomainDetachPciDiskDevice(driver, vm, dev);
5204
else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI)
5205
ret = qemuDomainDetachDiskDevice(driver, vm, dev);
5206
else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB)
5207
ret = qemuDomainDetachDiskDevice(driver, vm, dev);
5209
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
5210
_("This type of disk cannot be hot unplugged"));
5213
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5214
_("disk device type '%s' cannot be detached"),
5215
virDomainDiskDeviceTypeToString(disk->type));
5222
qemuDomainDetachDeviceControllerLive(struct qemud_driver *driver,
5224
virDomainDeviceDefPtr dev)
5226
virDomainControllerDefPtr cont = dev->data.controller;
5229
switch (cont->type) {
5230
case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
5231
ret = qemuDomainDetachPciControllerDevice(driver, vm, dev);
5234
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5235
_("disk controller bus '%s' cannot be hotunplugged."),
5236
virDomainControllerTypeToString(cont->type));
5242
qemuDomainDetachDeviceLive(virDomainObjPtr vm,
5243
virDomainDeviceDefPtr dev,
5246
struct qemud_driver *driver = dom->conn->privateData;
5249
switch (dev->type) {
5250
case VIR_DOMAIN_DEVICE_DISK:
5251
ret = qemuDomainDetachDeviceDiskLive(driver, vm, dev);
5253
case VIR_DOMAIN_DEVICE_CONTROLLER:
5254
ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev);
5256
case VIR_DOMAIN_DEVICE_LEASE:
5257
ret = qemuDomainDetachLease(driver, vm, dev->data.lease);
5259
case VIR_DOMAIN_DEVICE_NET:
5260
ret = qemuDomainDetachNetDevice(driver, vm, dev);
5262
case VIR_DOMAIN_DEVICE_HOSTDEV:
5263
ret = qemuDomainDetachHostDevice(driver, vm, dev);
5266
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5267
"%s", _("This type of device cannot be hot unplugged"));
5275
qemuDomainChangeDiskMediaLive(virDomainObjPtr vm,
5276
virDomainDeviceDefPtr dev,
5277
struct qemud_driver *driver,
5280
virDomainDiskDefPtr disk = dev->data.disk;
5281
virCgroupPtr cgroup = NULL;
5284
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
5285
if (virCgroupForDomain(driver->cgroup,
5286
vm->def->name, &cgroup, 0) != 0) {
5287
qemuReportError(VIR_ERR_INTERNAL_ERROR,
5288
_("Unable to find cgroup for %s"),
5292
if (qemuSetupDiskCgroup(driver, vm, cgroup, disk) < 0)
5296
switch (disk->device) {
5297
case VIR_DOMAIN_DISK_DEVICE_CDROM:
5298
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
5299
ret = qemuDomainChangeEjectableMedia(driver, vm, disk, force);
5301
dev->data.disk = NULL;
5304
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5305
_("disk bus '%s' cannot be updated."),
5306
virDomainDiskBusTypeToString(disk->bus));
5310
if (ret != 0 && cgroup) {
5311
if (qemuTeardownDiskCgroup(driver, vm, cgroup, disk) < 0)
5312
VIR_WARN("Failed to teardown cgroup for disk path %s",
5313
NULLSTR(disk->src));
5317
virCgroupFree(&cgroup);
5322
qemuDomainUpdateDeviceLive(virDomainObjPtr vm,
5323
virDomainDeviceDefPtr dev,
5327
struct qemud_driver *driver = dom->conn->privateData;
5330
switch (dev->type) {
5331
case VIR_DOMAIN_DEVICE_DISK:
5332
ret = qemuDomainChangeDiskMediaLive(vm, dev, driver, force);
5334
case VIR_DOMAIN_DEVICE_GRAPHICS:
5335
ret = qemuDomainChangeGraphics(driver, vm, dev->data.graphics);
5337
case VIR_DOMAIN_DEVICE_NET:
5338
ret = qemuDomainChangeNet(driver, vm, dom, dev->data.net);
5341
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5342
_("device type '%s' cannot be updated"),
5343
virDomainDeviceTypeToString(dev->type));
5351
qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
5352
virDomainDeviceDefPtr dev)
5354
virDomainDiskDefPtr disk;
5355
virDomainNetDefPtr net;
5356
virDomainLeaseDefPtr lease;
5358
switch (dev->type) {
5359
case VIR_DOMAIN_DEVICE_DISK:
5360
disk = dev->data.disk;
5361
if (virDomainDiskIndexByName(vmdef, disk->dst, true) >= 0) {
5362
qemuReportError(VIR_ERR_INVALID_ARG,
5363
_("target %s already exists."), disk->dst);
5366
if (virDomainDiskInsert(vmdef, disk)) {
5367
virReportOOMError();
5370
/* vmdef has the pointer. Generic codes for vmdef will do all jobs */
5371
dev->data.disk = NULL;
5372
if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO)
5373
if (virDomainDefAddImplicitControllers(vmdef) < 0)
5375
if (qemuDomainAssignPCIAddresses(vmdef) < 0)
5379
case VIR_DOMAIN_DEVICE_NET:
5380
net = dev->data.net;
5381
if (virDomainNetIndexByMac(vmdef, net->mac) >= 0) {
5382
char macbuf[VIR_MAC_STRING_BUFLEN];
5383
virFormatMacAddr(net->mac, macbuf);
5384
qemuReportError(VIR_ERR_INVALID_ARG,
5385
_("mac %s already exists"), macbuf);
5388
if (virDomainNetInsert(vmdef, net)) {
5389
virReportOOMError();
5392
dev->data.net = NULL;
5393
if (qemuDomainAssignPCIAddresses(vmdef) < 0)
5397
case VIR_DOMAIN_DEVICE_LEASE:
5398
lease = dev->data.lease;
5399
if (virDomainLeaseIndex(vmdef, lease) >= 0) {
5400
qemuReportError(VIR_ERR_INVALID_ARG,
5401
_("Lease %s in lockspace %s already exists"),
5402
lease->key, NULLSTR(lease->lockspace));
5405
if (virDomainLeaseInsert(vmdef, lease) < 0)
5408
/* vmdef has the pointer. Generic codes for vmdef will do all jobs */
5409
dev->data.lease = NULL;
5413
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
5414
_("persistent attach of device is not supported"));
5422
qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
5423
virDomainDeviceDefPtr dev)
5425
virDomainDiskDefPtr disk;
5426
virDomainNetDefPtr net;
5427
virDomainLeaseDefPtr lease;
5429
switch (dev->type) {
5430
case VIR_DOMAIN_DEVICE_DISK:
5431
disk = dev->data.disk;
5432
if (virDomainDiskRemoveByName(vmdef, disk->dst)) {
5433
qemuReportError(VIR_ERR_INVALID_ARG,
5434
_("no target device %s"), disk->dst);
5439
case VIR_DOMAIN_DEVICE_NET:
5440
net = dev->data.net;
5441
if (virDomainNetRemoveByMac(vmdef, net->mac)) {
5442
char macbuf[VIR_MAC_STRING_BUFLEN];
5444
virFormatMacAddr(net->mac, macbuf);
5445
qemuReportError(VIR_ERR_INVALID_ARG,
5446
_("no nic of mac %s"), macbuf);
5451
case VIR_DOMAIN_DEVICE_LEASE:
5452
lease = dev->data.lease;
5453
if (virDomainLeaseRemove(vmdef, lease) < 0) {
5454
qemuReportError(VIR_ERR_INVALID_ARG,
5455
_("Lease %s in lockspace %s does not exist"),
5456
lease->key, NULLSTR(lease->lockspace));
5462
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
5463
_("persistent detach of device is not supported"));
5470
qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
5471
virDomainDeviceDefPtr dev)
5473
virDomainDiskDefPtr orig, disk;
5474
virDomainNetDefPtr net;
5477
switch (dev->type) {
5478
case VIR_DOMAIN_DEVICE_DISK:
5479
disk = dev->data.disk;
5480
pos = virDomainDiskIndexByName(vmdef, disk->dst, false);
5482
qemuReportError(VIR_ERR_INVALID_ARG,
5483
_("target %s doesn't exist."), disk->dst);
5486
orig = vmdef->disks[pos];
5487
if (!(orig->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
5488
!(orig->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)) {
5489
qemuReportError(VIR_ERR_INVALID_ARG,
5490
_("this disk doesn't support update"));
5495
* We allow updating src/type//driverType/cachemode/
5497
VIR_FREE(orig->src);
5498
orig->src = disk->src;
5499
orig->type = disk->type;
5500
orig->cachemode = disk->cachemode;
5501
if (disk->driverName) {
5502
VIR_FREE(orig->driverName);
5503
orig->driverName = disk->driverName;
5504
disk->driverName = NULL;
5506
if (disk->driverType) {
5507
VIR_FREE(orig->driverType);
5508
orig->driverType = disk->driverType;
5509
disk->driverType = NULL;
5514
case VIR_DOMAIN_DEVICE_NET:
5515
net = dev->data.net;
5516
if ((pos = virDomainNetIndexByMac(vmdef, net->mac)) < 0) {
5517
char macbuf[VIR_MAC_STRING_BUFLEN];
5518
virFormatMacAddr(net->mac, macbuf);
5519
qemuReportError(VIR_ERR_INVALID_ARG,
5520
_("mac %s doesn't exist"), macbuf);
5524
VIR_FREE(vmdef->nets[pos]);
5526
vmdef->nets[pos] = net;
5527
dev->data.net = NULL;
5529
if (qemuDomainAssignPCIAddresses(vmdef) < 0)
5534
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
5535
_("persistent update of device is not supported"));
5541
/* Actions for qemuDomainModifyDeviceFlags */
5550
qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
5551
unsigned int flags, int action)
5553
struct qemud_driver *driver = dom->conn->privateData;
5554
virDomainObjPtr vm = NULL;
5555
virDomainDefPtr vmdef = NULL;
5556
virDomainDeviceDefPtr dev = NULL;
5557
bool force = (flags & VIR_DOMAIN_DEVICE_MODIFY_FORCE) != 0;
5559
unsigned int affect;
5561
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
5562
VIR_DOMAIN_AFFECT_CONFIG |
5563
(action == QEMU_DEVICE_UPDATE ?
5564
VIR_DOMAIN_DEVICE_MODIFY_FORCE : 0), -1);
5566
affect = flags & (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG);
5568
qemuDriverLock(driver);
5569
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
5571
char uuidstr[VIR_UUID_STRING_BUFLEN];
5572
virUUIDFormat(dom->uuid, uuidstr);
5573
qemuReportError(VIR_ERR_NO_DOMAIN,
5574
_("no domain with matching uuid '%s'"), uuidstr);
5578
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
5581
if (virDomainObjIsActive(vm)) {
5582
if (affect == VIR_DOMAIN_AFFECT_CURRENT)
5583
flags |= VIR_DOMAIN_AFFECT_LIVE;
5585
if (affect == VIR_DOMAIN_AFFECT_CURRENT)
5586
flags |= VIR_DOMAIN_AFFECT_CONFIG;
5587
/* check consistency between flags and the vm state */
5588
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
5589
qemuReportError(VIR_ERR_OPERATION_INVALID,
5591
_("cannot do live update a device on "
5592
"inactive domain"));
5597
if ((flags & VIR_DOMAIN_AFFECT_CONFIG) && !vm->persistent) {
5598
qemuReportError(VIR_ERR_OPERATION_INVALID,
5599
"%s", _("cannot modify device on transient domain"));
5603
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
5604
dev = virDomainDeviceDefParse(driver->caps, vm->def, xml,
5605
VIR_DOMAIN_XML_INACTIVE);
5609
/* Make a copy for updated domain. */
5610
vmdef = virDomainObjCopyPersistentDef(driver->caps, vm);
5614
case QEMU_DEVICE_ATTACH:
5615
ret = qemuDomainAttachDeviceConfig(vmdef, dev);
5617
case QEMU_DEVICE_DETACH:
5618
ret = qemuDomainDetachDeviceConfig(vmdef, dev);
5620
case QEMU_DEVICE_UPDATE:
5621
ret = qemuDomainUpdateDeviceConfig(vmdef, dev);
5624
qemuReportError(VIR_ERR_INTERNAL_ERROR,
5625
_("unknown domain modify action %d"), action);
5633
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
5634
/* If dev exists it was created to modify the domain config. Free it. */
5635
virDomainDeviceDefFree(dev);
5636
dev = virDomainDeviceDefParse(driver->caps, vm->def, xml,
5637
VIR_DOMAIN_XML_INACTIVE);
5644
case QEMU_DEVICE_ATTACH:
5645
ret = qemuDomainAttachDeviceLive(vm, dev, dom);
5647
case QEMU_DEVICE_DETACH:
5648
ret = qemuDomainDetachDeviceLive(vm, dev, dom);
5650
case QEMU_DEVICE_UPDATE:
5651
ret = qemuDomainUpdateDeviceLive(vm, dev, dom, force);
5654
qemuReportError(VIR_ERR_INTERNAL_ERROR,
5655
_("unknown domain modify action %d"), action);
5663
* update domain status forcibly because the domain status may be
5664
* changed even if we failed to attach the device. For example,
5665
* a new controller may be created.
5667
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
5673
/* Finally, if no error until here, we can save config. */
5674
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
5675
ret = virDomainSaveConfig(driver->configDir, vmdef);
5677
virDomainObjAssignDef(vm, vmdef, false);
5683
if (qemuDomainObjEndJob(driver, vm) == 0)
5687
virDomainDefFree(vmdef);
5688
virDomainDeviceDefFree(dev);
5690
virDomainObjUnlock(vm);
5691
qemuDriverUnlock(driver);
5695
static int qemuDomainAttachDeviceFlags(virDomainPtr dom, const char *xml,
5698
return qemuDomainModifyDeviceFlags(dom, xml, flags, QEMU_DEVICE_ATTACH);
5701
static int qemuDomainAttachDevice(virDomainPtr dom, const char *xml)
5703
return qemuDomainAttachDeviceFlags(dom, xml,
5704
VIR_DOMAIN_AFFECT_LIVE);
5708
static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
5712
return qemuDomainModifyDeviceFlags(dom, xml, flags, QEMU_DEVICE_UPDATE);
5715
static int qemuDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
5718
return qemuDomainModifyDeviceFlags(dom, xml, flags, QEMU_DEVICE_DETACH);
5721
static int qemuDomainDetachDevice(virDomainPtr dom, const char *xml)
5723
return qemuDomainDetachDeviceFlags(dom, xml,
5724
VIR_DOMAIN_AFFECT_LIVE);
5727
static int qemudDomainGetAutostart(virDomainPtr dom,
5729
struct qemud_driver *driver = dom->conn->privateData;
5733
qemuDriverLock(driver);
5734
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
5735
qemuDriverUnlock(driver);
5738
char uuidstr[VIR_UUID_STRING_BUFLEN];
5739
virUUIDFormat(dom->uuid, uuidstr);
5740
qemuReportError(VIR_ERR_NO_DOMAIN,
5741
_("no domain with matching uuid '%s'"), uuidstr);
5745
*autostart = vm->autostart;
5750
virDomainObjUnlock(vm);
5754
static int qemudDomainSetAutostart(virDomainPtr dom,
5756
struct qemud_driver *driver = dom->conn->privateData;
5758
char *configFile = NULL, *autostartLink = NULL;
5761
qemuDriverLock(driver);
5762
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
5765
char uuidstr[VIR_UUID_STRING_BUFLEN];
5766
virUUIDFormat(dom->uuid, uuidstr);
5767
qemuReportError(VIR_ERR_NO_DOMAIN,
5768
_("no domain with matching uuid '%s'"), uuidstr);
5772
if (!vm->persistent) {
5773
qemuReportError(VIR_ERR_OPERATION_INVALID,
5774
"%s", _("cannot set autostart for transient domain"));
5778
autostart = (autostart != 0);
5780
if (vm->autostart != autostart) {
5781
if ((configFile = virDomainConfigFile(driver->configDir, vm->def->name)) == NULL)
5783
if ((autostartLink = virDomainConfigFile(driver->autostartDir, vm->def->name)) == NULL)
5787
if (virFileMakePath(driver->autostartDir) < 0) {
5788
virReportSystemError(errno,
5789
_("cannot create autostart directory %s"),
5790
driver->autostartDir);
5794
if (symlink(configFile, autostartLink) < 0) {
5795
virReportSystemError(errno,
5796
_("Failed to create symlink '%s to '%s'"),
5797
autostartLink, configFile);
5801
if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
5802
virReportSystemError(errno,
5803
_("Failed to delete symlink '%s'"),
5809
vm->autostart = autostart;
5814
VIR_FREE(configFile);
5815
VIR_FREE(autostartLink);
5817
virDomainObjUnlock(vm);
5818
qemuDriverUnlock(driver);
5824
* check whether the host supports CFS bandwidth
5826
* Return 1 when CFS bandwidth is supported, 0 when CFS bandwidth is not
5827
* supported, -1 on error.
5829
static int qemuGetCpuBWStatus(virCgroupPtr cgroup)
5831
char *cfs_period_path = NULL;
5837
if (virCgroupPathOfController(cgroup, VIR_CGROUP_CONTROLLER_CPU,
5838
"cpu.cfs_period_us", &cfs_period_path) < 0) {
5839
VIR_INFO("cannot get the path of cgroup CPU controller");
5844
if (access(cfs_period_path, F_OK) < 0) {
5851
VIR_FREE(cfs_period_path);
5856
static char *qemuGetSchedulerType(virDomainPtr dom,
5859
struct qemud_driver *driver = dom->conn->privateData;
5863
qemuDriverLock(driver);
5864
if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
5865
qemuReportError(VIR_ERR_OPERATION_INVALID,
5866
"%s", _("cgroup CPU controller is not mounted"));
5871
rc = qemuGetCpuBWStatus(driver->cgroup);
5880
ret = strdup("posix");
5882
virReportOOMError();
5885
qemuDriverUnlock(driver);
5889
/* deviceWeightStr in the form of /device/path,weight,/device/path,weight
5890
* for example, /dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0,800
5893
qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
5894
virBlkioDeviceWeightPtr *dw, size_t *size)
5900
virBlkioDeviceWeightPtr result = NULL;
5902
temp = deviceWeightStr;
5904
temp = strchr(temp, ',');
5911
/* A valid string must have even number of fields, hence an odd
5912
* number of commas. */
5916
ndevices = (nsep + 1) / 2;
5918
if (VIR_ALLOC_N(result, ndevices) < 0) {
5919
virReportOOMError();
5924
temp = deviceWeightStr;
5933
result[i].path = strndup(temp, p - temp);
5934
if (!result[i].path) {
5935
virReportOOMError();
5942
if (virStrToLong_ui(temp, &p, 10, &result[i].weight) < 0)
5963
qemuReportError(VIR_ERR_INVALID_ARG,
5964
_("unable to parse %s"), deviceWeightStr);
5966
virBlkioDeviceWeightArrayClear(result, ndevices);
5971
/* Modify def to reflect all device weight changes described in tmp. */
5973
qemuDomainMergeDeviceWeights(virBlkioDeviceWeightPtr *def, size_t *def_size,
5974
virBlkioDeviceWeightPtr tmp, size_t tmp_size)
5977
virBlkioDeviceWeightPtr dw;
5979
for (i = 0; i < tmp_size; i++) {
5983
for (j = 0; j < *def_size; j++) {
5984
if (STREQ(dw->path, (*def)[j].path)) {
5986
(*def)[j].weight = dw->weight;
5993
if (VIR_EXPAND_N(*def, *def_size, 1) < 0) {
5994
virReportOOMError();
5997
(*def)[*def_size - 1].path = dw->path;
5998
(*def)[*def_size - 1].weight = dw->weight;
6006
static int qemuDomainSetBlkioParameters(virDomainPtr dom,
6007
virTypedParameterPtr params,
6011
struct qemud_driver *driver = dom->conn->privateData;
6013
virCgroupPtr group = NULL;
6014
virDomainObjPtr vm = NULL;
6015
virDomainDefPtr persistentDef = NULL;
6019
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
6020
VIR_DOMAIN_AFFECT_CONFIG, -1);
6021
qemuDriverLock(driver);
6023
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
6026
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6027
_("No such domain %s"), dom->uuid);
6031
isActive = virDomainObjIsActive(vm);
6033
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
6035
flags = VIR_DOMAIN_AFFECT_LIVE;
6037
flags = VIR_DOMAIN_AFFECT_CONFIG;
6040
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6042
qemuReportError(VIR_ERR_OPERATION_INVALID,
6043
"%s", _("domain is not running"));
6047
if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) {
6048
qemuReportError(VIR_ERR_OPERATION_INVALID, _("blkio cgroup isn't mounted"));
6052
if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
6053
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6054
_("cannot find cgroup for domain %s"), vm->def->name);
6059
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6060
if (!vm->persistent) {
6061
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
6062
_("cannot change persistent config of a transient domain"));
6065
if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
6070
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6071
for (i = 0; i < nparams; i++) {
6073
virTypedParameterPtr param = ¶ms[i];
6075
if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
6076
if (param->type != VIR_TYPED_PARAM_UINT) {
6077
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6078
_("invalid type for blkio weight tunable, expected a 'unsigned int'"));
6083
if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
6084
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6085
_("out of blkio weight range."));
6090
rc = virCgroupSetBlkioWeight(group, params[i].value.ui);
6092
virReportSystemError(-rc, "%s",
6093
_("unable to set blkio weight tunable"));
6096
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
6098
virBlkioDeviceWeightPtr devices = NULL;
6099
if (param->type != VIR_TYPED_PARAM_STRING) {
6100
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6101
_("invalid type for device_weight tunable, "
6102
"expected a 'char *'"));
6107
if (qemuDomainParseDeviceWeightStr(params[i].value.s,
6113
for (i = 0; i < ndevices; i++) {
6114
rc = virCgroupSetBlkioDeviceWeight(group,
6118
virReportSystemError(-rc,
6119
_("Unable to set io device weight "
6125
if (i != ndevices) {
6129
if (qemuDomainMergeDeviceWeights(&vm->def->blkio.devices,
6130
&vm->def->blkio.ndevices,
6131
devices, ndevices) < 0)
6133
virBlkioDeviceWeightArrayClear(devices, ndevices);
6136
qemuReportError(VIR_ERR_INVALID_ARG,
6137
_("Parameter `%s' not supported"),
6145
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6146
/* Clang can't see that if we get here, persistentDef was set. */
6147
sa_assert(persistentDef);
6149
for (i = 0; i < nparams; i++) {
6150
virTypedParameterPtr param = ¶ms[i];
6152
if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
6153
if (param->type != VIR_TYPED_PARAM_UINT) {
6154
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6155
_("invalid type for blkio weight tunable, expected a 'unsigned int'"));
6160
if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
6161
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6162
_("out of blkio weight range."));
6167
persistentDef->blkio.weight = params[i].value.ui;
6168
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
6169
virBlkioDeviceWeightPtr devices = NULL;
6171
if (param->type != VIR_TYPED_PARAM_STRING) {
6172
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6173
_("invalid type for device_weight tunable, "
6174
"expected a 'char *'"));
6178
if (qemuDomainParseDeviceWeightStr(params[i].value.s,
6184
if (qemuDomainMergeDeviceWeights(&vm->def->blkio.devices,
6185
&vm->def->blkio.ndevices,
6186
devices, ndevices) < 0)
6188
virBlkioDeviceWeightArrayClear(devices, ndevices);
6191
qemuReportError(VIR_ERR_INVALID_ARG,
6192
_("Parameter `%s' not supported"),
6198
if (virDomainSaveConfig(driver->configDir, persistentDef) < 0)
6203
virCgroupFree(&group);
6205
virDomainObjUnlock(vm);
6206
qemuDriverUnlock(driver);
6210
static int qemuDomainGetBlkioParameters(virDomainPtr dom,
6211
virTypedParameterPtr params,
6215
struct qemud_driver *driver = dom->conn->privateData;
6217
virCgroupPtr group = NULL;
6218
virDomainObjPtr vm = NULL;
6219
virDomainDefPtr persistentDef = NULL;
6225
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
6226
VIR_DOMAIN_AFFECT_CONFIG |
6227
VIR_TYPED_PARAM_STRING_OKAY, -1);
6228
qemuDriverLock(driver);
6230
/* We blindly return a string, and let libvirt.c and
6231
* remote_driver.c do the filtering on behalf of older clients
6232
* that can't parse it. */
6233
flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
6235
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
6238
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6239
_("No such domain %s"), dom->uuid);
6243
if ((*nparams) == 0) {
6244
/* Current number of blkio parameters supported by cgroups */
6245
*nparams = QEMU_NB_BLKIO_PARAM;
6250
isActive = virDomainObjIsActive(vm);
6252
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
6254
flags = VIR_DOMAIN_AFFECT_LIVE;
6256
flags = VIR_DOMAIN_AFFECT_CONFIG;
6259
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6261
qemuReportError(VIR_ERR_OPERATION_INVALID,
6262
"%s", _("domain is not running"));
6266
if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) {
6267
qemuReportError(VIR_ERR_OPERATION_INVALID, _("blkio cgroup isn't mounted"));
6271
if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
6272
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6273
_("cannot find cgroup for domain %s"), vm->def->name);
6278
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6279
if (!vm->persistent) {
6280
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
6281
_("cannot change persistent config of a transient domain"));
6284
if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
6288
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6289
for (i = 0; i < *nparams && i < QEMU_NB_BLKIO_PARAM; i++) {
6290
virTypedParameterPtr param = ¶ms[i];
6292
param->value.ui = 0;
6293
param->type = VIR_TYPED_PARAM_UINT;
6296
case 0: /* fill blkio weight here */
6297
rc = virCgroupGetBlkioWeight(group, &val);
6299
virReportSystemError(-rc, "%s",
6300
_("unable to get blkio weight"));
6303
if (virStrcpyStatic(param->field, VIR_DOMAIN_BLKIO_WEIGHT) == NULL) {
6304
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6305
_("Field name '%s' too long"),
6306
VIR_DOMAIN_BLKIO_WEIGHT);
6309
param->value.ui = val;
6311
case 1: /* blkiotune.device_weight */
6312
if (vm->def->blkio.ndevices > 0) {
6313
virBuffer buf = VIR_BUFFER_INITIALIZER;
6316
for (j = 0; j < vm->def->blkio.ndevices; j++) {
6317
if (!vm->def->blkio.devices[j].weight)
6320
virBufferAddChar(&buf, ',');
6323
virBufferAsprintf(&buf, "%s,%u",
6324
vm->def->blkio.devices[j].path,
6325
vm->def->blkio.devices[j].weight);
6327
if (virBufferError(&buf)) {
6328
virReportOOMError();
6331
param->value.s = virBufferContentAndReset(&buf);
6333
if (!param->value.s) {
6334
param->value.s = strdup("");
6335
if (!param->value.s) {
6336
virReportOOMError();
6340
param->type = VIR_TYPED_PARAM_STRING;
6341
if (virStrcpyStatic(param->field,
6342
VIR_DOMAIN_BLKIO_DEVICE_WEIGHT) == NULL) {
6343
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6344
_("Field name '%s' too long"),
6345
VIR_DOMAIN_BLKIO_DEVICE_WEIGHT);
6352
/* should not hit here */
6355
} else if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6356
for (i = 0; i < *nparams && i < QEMU_NB_BLKIO_PARAM; i++) {
6357
virTypedParameterPtr param = ¶ms[i];
6359
param->value.ui = 0;
6360
param->type = VIR_TYPED_PARAM_UINT;
6363
case 0: /* fill blkio weight here */
6364
if (virStrcpyStatic(param->field, VIR_DOMAIN_BLKIO_WEIGHT) == NULL) {
6365
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6366
_("Field name '%s' too long"),
6367
VIR_DOMAIN_BLKIO_WEIGHT);
6370
param->value.ui = persistentDef->blkio.weight;
6373
case 1: /* blkiotune.device_weight */
6374
if (persistentDef->blkio.ndevices > 0) {
6375
virBuffer buf = VIR_BUFFER_INITIALIZER;
6378
for (j = 0; j < persistentDef->blkio.ndevices; j++) {
6379
if (!persistentDef->blkio.devices[j].weight)
6382
virBufferAddChar(&buf, ',');
6385
virBufferAsprintf(&buf, "%s,%u",
6386
persistentDef->blkio.devices[j].path,
6387
persistentDef->blkio.devices[j].weight);
6389
if (virBufferError(&buf)) {
6390
virReportOOMError();
6393
param->value.s = virBufferContentAndReset(&buf);
6395
if (!param->value.s) {
6396
param->value.s = strdup("");
6397
if (!param->value.s) {
6398
virReportOOMError();
6402
param->type = VIR_TYPED_PARAM_STRING;
6403
if (virStrcpyStatic(param->field,
6404
VIR_DOMAIN_BLKIO_DEVICE_WEIGHT) == NULL) {
6405
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6406
_("Field name '%s' too long"),
6407
VIR_DOMAIN_BLKIO_DEVICE_WEIGHT);
6414
/* should not hit here */
6419
if (QEMU_NB_BLKIO_PARAM < *nparams)
6420
*nparams = QEMU_NB_BLKIO_PARAM;
6425
virCgroupFree(&group);
6427
virDomainObjUnlock(vm);
6428
qemuDriverUnlock(driver);
6432
static int qemuDomainSetMemoryParameters(virDomainPtr dom,
6433
virTypedParameterPtr params,
6437
struct qemud_driver *driver = dom->conn->privateData;
6439
virDomainDefPtr persistentDef = NULL;
6440
virCgroupPtr group = NULL;
6441
virDomainObjPtr vm = NULL;
6445
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
6446
VIR_DOMAIN_AFFECT_CONFIG, -1);
6448
qemuDriverLock(driver);
6450
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
6453
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6454
_("No such domain %s"), dom->uuid);
6458
isActive = virDomainObjIsActive(vm);
6460
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
6462
flags = VIR_DOMAIN_AFFECT_LIVE;
6464
flags = VIR_DOMAIN_AFFECT_CONFIG;
6467
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6469
qemuReportError(VIR_ERR_OPERATION_INVALID,
6470
"%s", _("domain is not running"));
6474
if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
6475
qemuReportError(VIR_ERR_OPERATION_INVALID,
6476
"%s", _("cgroup memory controller is not mounted"));
6480
if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
6481
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6482
_("cannot find cgroup for domain %s"), vm->def->name);
6487
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6488
if (!vm->persistent) {
6489
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
6490
_("cannot change persistent config of a transient domain"));
6493
if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
6498
for (i = 0; i < nparams; i++) {
6499
virTypedParameterPtr param = ¶ms[i];
6501
if (STREQ(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) {
6503
if (param->type != VIR_TYPED_PARAM_ULLONG) {
6504
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6505
_("invalid type for memory hard_limit tunable, expected a 'ullong'"));
6510
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6511
rc = virCgroupSetMemoryHardLimit(group, params[i].value.ul);
6513
virReportSystemError(-rc, "%s",
6514
_("unable to set memory hard_limit tunable"));
6519
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6520
persistentDef->mem.hard_limit = params[i].value.ul;
6522
} else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) {
6524
if (param->type != VIR_TYPED_PARAM_ULLONG) {
6525
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6526
_("invalid type for memory soft_limit tunable, expected a 'ullong'"));
6531
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6532
rc = virCgroupSetMemorySoftLimit(group, params[i].value.ul);
6534
virReportSystemError(-rc, "%s",
6535
_("unable to set memory soft_limit tunable"));
6540
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6541
persistentDef->mem.soft_limit = params[i].value.ul;
6543
} else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)) {
6545
if (param->type != VIR_TYPED_PARAM_ULLONG) {
6546
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6547
_("invalid type for swap_hard_limit tunable, expected a 'ullong'"));
6552
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6553
rc = virCgroupSetMemSwapHardLimit(group, params[i].value.ul);
6555
virReportSystemError(-rc, "%s",
6556
_("unable to set swap_hard_limit tunable"));
6560
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6561
persistentDef->mem.swap_hard_limit = params[i].value.ul;
6563
} else if (STREQ(param->field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE)) {
6564
qemuReportError(VIR_ERR_INVALID_ARG,
6565
_("Memory tunable `%s' not implemented"),
6569
qemuReportError(VIR_ERR_INVALID_ARG,
6570
_("Parameter `%s' not supported"), param->field);
6575
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6576
if (virDomainSaveConfig(driver->configDir, persistentDef) < 0)
6581
virCgroupFree(&group);
6583
virDomainObjUnlock(vm);
6584
qemuDriverUnlock(driver);
6588
static int qemuDomainGetMemoryParameters(virDomainPtr dom,
6589
virTypedParameterPtr params,
6593
struct qemud_driver *driver = dom->conn->privateData;
6595
virCgroupPtr group = NULL;
6596
virDomainObjPtr vm = NULL;
6597
virDomainDefPtr persistentDef = NULL;
6598
unsigned long long val;
6603
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
6604
VIR_DOMAIN_AFFECT_CONFIG |
6605
VIR_TYPED_PARAM_STRING_OKAY, -1);
6607
qemuDriverLock(driver);
6609
/* We don't return strings, and thus trivially support this flag. */
6610
flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
6612
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
6615
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6616
_("No such domain %s"), dom->uuid);
6620
isActive = virDomainObjIsActive(vm);
6622
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
6624
flags = VIR_DOMAIN_AFFECT_LIVE;
6626
flags = VIR_DOMAIN_AFFECT_CONFIG;
6629
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6631
qemuReportError(VIR_ERR_OPERATION_INVALID,
6632
"%s", _("domain is not running"));
6636
if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
6637
qemuReportError(VIR_ERR_OPERATION_INVALID,
6638
"%s", _("cgroup memory controller is not mounted"));
6642
if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
6643
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6644
_("cannot find cgroup for domain %s"), vm->def->name);
6649
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6650
if (!vm->persistent) {
6651
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
6652
_("cannot change persistent config of a transient domain"));
6655
if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
6659
if ((*nparams) == 0) {
6660
/* Current number of memory parameters supported by cgroups */
6661
*nparams = QEMU_NB_MEM_PARAM;
6666
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6667
for (i = 0; i < *nparams && i < QEMU_NB_MEM_PARAM; i++) {
6668
virMemoryParameterPtr param = ¶ms[i];
6670
param->value.ul = 0;
6671
param->type = VIR_TYPED_PARAM_ULLONG;
6674
case 0: /* fill memory hard limit here */
6675
if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT) == NULL) {
6676
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6677
_("Field name '%s' too long"),
6678
VIR_DOMAIN_MEMORY_HARD_LIMIT);
6681
param->value.ul = persistentDef->mem.hard_limit;
6684
case 1: /* fill memory soft limit here */
6685
if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT) == NULL) {
6686
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6687
_("Field name '%s' too long"),
6688
VIR_DOMAIN_MEMORY_SOFT_LIMIT);
6691
param->value.ul = persistentDef->mem.soft_limit;
6694
case 2: /* fill swap hard limit here */
6695
if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT) == NULL) {
6696
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6697
_("Field name '%s' too long"),
6698
VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT);
6701
param->value.ul = persistentDef->mem.swap_hard_limit;
6706
/* should not hit here */
6712
for (i = 0; i < *nparams && i < QEMU_NB_MEM_PARAM; i++) {
6713
virTypedParameterPtr param = ¶ms[i];
6715
param->value.ul = 0;
6716
param->type = VIR_TYPED_PARAM_ULLONG;
6718
/* Coverity does not realize that if we get here, group is set. */
6722
case 0: /* fill memory hard limit here */
6723
rc = virCgroupGetMemoryHardLimit(group, &val);
6725
virReportSystemError(-rc, "%s",
6726
_("unable to get memory hard limit"));
6729
if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT) == NULL) {
6730
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6731
_("Field name '%s' too long"),
6732
VIR_DOMAIN_MEMORY_HARD_LIMIT);
6735
param->value.ul = val;
6738
case 1: /* fill memory soft limit here */
6739
rc = virCgroupGetMemorySoftLimit(group, &val);
6741
virReportSystemError(-rc, "%s",
6742
_("unable to get memory soft limit"));
6745
if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT) == NULL) {
6746
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6747
_("Field name '%s' too long"),
6748
VIR_DOMAIN_MEMORY_SOFT_LIMIT);
6751
param->value.ul = val;
6754
case 2: /* fill swap hard limit here */
6755
rc = virCgroupGetMemSwapHardLimit(group, &val);
6757
virReportSystemError(-rc, "%s",
6758
_("unable to get swap hard limit"));
6761
if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT) == NULL) {
6762
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6763
_("Field name '%s' too long"),
6764
VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT);
6767
param->value.ul = val;
6772
/* should not hit here */
6777
if (QEMU_NB_MEM_PARAM < *nparams)
6778
*nparams = QEMU_NB_MEM_PARAM;
6783
virCgroupFree(&group);
6785
virDomainObjUnlock(vm);
6786
qemuDriverUnlock(driver);
6791
qemuSetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
6792
unsigned long long period, long long quota)
6795
qemuDomainObjPrivatePtr priv = vm->privateData;
6796
virCgroupPtr cgroup_vcpu = NULL;
6798
long long vm_quota = 0;
6799
long long old_quota = 0;
6800
unsigned long long old_period = 0;
6802
if (period == 0 && quota == 0)
6805
/* Ensure that we can multiply by vcpus without overflowing. */
6806
if (quota > LLONG_MAX / vm->def->vcpus) {
6807
virReportSystemError(EINVAL,
6809
"Unable to set cpu bandwidth quota");
6814
vm_quota = quota * vm->def->vcpus;
6818
rc = virCgroupGetCpuCfsQuota(cgroup, &old_quota);
6820
virReportSystemError(-rc, "%s",
6821
_("unable to get cpu bandwidth tunable"));
6825
rc = virCgroupGetCpuCfsPeriod(cgroup, &old_period);
6827
virReportSystemError(-rc, "%s",
6828
_("unable to get cpu bandwidth period tunable"));
6833
* If quota will be changed to a small value, we should modify vcpu's quota
6834
* first. Otherwise, we should modify vm's quota first.
6836
* If period will be changed to a small value, we should modify vm's period
6837
* first. Otherwise, we should modify vcpu's period first.
6839
* If both quota and period will be changed to a big/small value, we cannot
6840
* modify period and quota together.
6842
if ((quota != 0) && (period != 0)) {
6843
if (((quota > old_quota) && (period > old_period)) ||
6844
((quota < old_quota) && (period < old_period))) {
6846
if (qemuSetVcpusBWLive(vm, cgroup, period, 0) < 0)
6850
if (qemuSetVcpusBWLive(vm, cgroup, 0, quota) < 0)
6856
if (((vm_quota != 0) && (vm_quota > old_quota)) ||
6857
((period != 0) && (period < old_period)))
6858
/* Set cpu bandwidth for the vm */
6859
if (qemuSetupCgroupVcpuBW(cgroup, period, vm_quota) < 0)
6862
/* If we does not know VCPU<->PID mapping or all vcpu runs in the same
6863
* thread, we cannot control each vcpu. So we only modify cpu bandwidth
6864
* when each vcpu has a separated thread.
6866
if (priv->nvcpupids != 0 && priv->vcpupids[0] != vm->pid) {
6867
for (i = 0; i < priv->nvcpupids; i++) {
6868
rc = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 0);
6870
virReportSystemError(-rc,
6871
_("Unable to find vcpu cgroup for %s(vcpu:"
6877
if (qemuSetupCgroupVcpuBW(cgroup_vcpu, period, quota) < 0)
6880
virCgroupFree(&cgroup_vcpu);
6884
if (((vm_quota != 0) && (vm_quota <= old_quota)) ||
6885
((period != 0) && (period >= old_period)))
6886
/* Set cpu bandwidth for the vm */
6887
if (qemuSetupCgroupVcpuBW(cgroup, period, vm_quota) < 0)
6893
virCgroupFree(&cgroup_vcpu);
6897
static int qemuSetSchedulerParametersFlags(virDomainPtr dom,
6898
virTypedParameterPtr params,
6902
struct qemud_driver *driver = dom->conn->privateData;
6904
virCgroupPtr group = NULL;
6905
virDomainObjPtr vm = NULL;
6906
virDomainDefPtr vmdef = NULL;
6911
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
6912
VIR_DOMAIN_AFFECT_CONFIG, -1);
6914
qemuDriverLock(driver);
6916
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
6919
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6920
_("No such domain %s"), dom->uuid);
6924
isActive = virDomainObjIsActive(vm);
6926
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
6928
flags = VIR_DOMAIN_AFFECT_LIVE;
6930
flags = VIR_DOMAIN_AFFECT_CONFIG;
6933
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6934
if (!vm->persistent) {
6935
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
6936
_("cannot change persistent config of a transient domain"));
6940
/* Make a copy for updated domain. */
6941
vmdef = virDomainObjCopyPersistentDef(driver->caps, vm);
6946
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6948
qemuReportError(VIR_ERR_OPERATION_INVALID,
6949
"%s", _("domain is not running"));
6953
if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
6954
qemuReportError(VIR_ERR_OPERATION_INVALID,
6955
"%s", _("cgroup CPU controller is not mounted"));
6958
if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
6959
qemuReportError(VIR_ERR_INTERNAL_ERROR,
6960
_("cannot find cgroup for domain %s"),
6966
for (i = 0; i < nparams; i++) {
6967
virTypedParameterPtr param = ¶ms[i];
6969
if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_CPU_SHARES)) {
6970
if (param->type != VIR_TYPED_PARAM_ULLONG) {
6971
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6972
_("invalid type for cpu_shares tunable, expected a 'ullong'"));
6976
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6977
rc = virCgroupSetCpuShares(group, params[i].value.ul);
6979
virReportSystemError(-rc, "%s",
6980
_("unable to set cpu shares tunable"));
6984
vm->def->cputune.shares = params[i].value.ul;
6987
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
6988
vmdef->cputune.shares = params[i].value.ul;
6990
} else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD)) {
6991
if (param->type != VIR_TYPED_PARAM_ULLONG) {
6992
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
6993
_("invalid type for vcpu_period tunable,"
6994
" expected a 'ullong'"));
6998
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
6999
rc = qemuSetVcpusBWLive(vm, group, params[i].value.ul, 0);
7003
if (params[i].value.ul)
7004
vm->def->cputune.period = params[i].value.ul;
7007
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
7008
vmdef->cputune.period = params[i].value.ul;
7010
} else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA)) {
7011
if (param->type != VIR_TYPED_PARAM_LLONG) {
7012
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
7013
_("invalid type for vcpu_quota tunable,"
7014
" expected a 'llong'"));
7018
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
7019
rc = qemuSetVcpusBWLive(vm, group, 0, params[i].value.l);
7023
if (params[i].value.l)
7024
vm->def->cputune.quota = params[i].value.l;
7027
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
7028
vmdef->cputune.quota = params[i].value.l;
7031
qemuReportError(VIR_ERR_INVALID_ARG,
7032
_("Invalid parameter `%s'"), param->field);
7037
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
7041
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
7042
rc = virDomainSaveConfig(driver->configDir, vmdef);
7046
virDomainObjAssignDef(vm, vmdef, false);
7053
virDomainDefFree(vmdef);
7054
virCgroupFree(&group);
7056
virDomainObjUnlock(vm);
7057
qemuDriverUnlock(driver);
7061
static int qemuSetSchedulerParameters(virDomainPtr dom,
7062
virTypedParameterPtr params,
7065
return qemuSetSchedulerParametersFlags(dom,
7068
VIR_DOMAIN_AFFECT_LIVE);
7072
qemuGetVcpuBWLive(virCgroupPtr cgroup, unsigned long long *period,
7077
rc = virCgroupGetCpuCfsPeriod(cgroup, period);
7079
virReportSystemError(-rc, "%s",
7080
_("unable to get cpu bandwidth period tunable"));
7084
rc = virCgroupGetCpuCfsQuota(cgroup, quota);
7086
virReportSystemError(-rc, "%s",
7087
_("unable to get cpu bandwidth tunable"));
7095
qemuGetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
7096
unsigned long long *period, long long *quota)
7098
virCgroupPtr cgroup_vcpu = NULL;
7099
qemuDomainObjPrivatePtr priv = NULL;
7103
priv = vm->privateData;
7104
if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
7105
/* We do not create sub dir for each vcpu */
7106
rc = qemuGetVcpuBWLive(cgroup, period, quota);
7111
*quota /= vm->def->vcpus;
7115
/* get period and quota for vcpu0 */
7116
rc = virCgroupForVcpu(cgroup, 0, &cgroup_vcpu, 0);
7118
virReportSystemError(-rc,
7119
_("Unable to find vcpu cgroup for %s(vcpu: 0)"),
7124
rc = qemuGetVcpuBWLive(cgroup_vcpu, period, quota);
7132
virCgroupFree(&cgroup_vcpu);
7137
qemuGetSchedulerParametersFlags(virDomainPtr dom,
7138
virTypedParameterPtr params,
7142
struct qemud_driver *driver = dom->conn->privateData;
7143
virCgroupPtr group = NULL;
7144
virDomainObjPtr vm = NULL;
7145
unsigned long long shares;
7146
unsigned long long period;
7151
bool cpu_bw_status = false;
7152
int saved_nparams = 0;
7154
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
7155
VIR_DOMAIN_AFFECT_CONFIG |
7156
VIR_TYPED_PARAM_STRING_OKAY, -1);
7158
qemuDriverLock(driver);
7160
/* We don't return strings, and thus trivially support this flag. */
7161
flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
7164
rc = qemuGetCpuBWStatus(driver->cgroup);
7167
cpu_bw_status = !!rc;
7170
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
7173
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7174
_("No such domain %s"), dom->uuid);
7178
isActive = virDomainObjIsActive(vm);
7180
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
7182
flags = VIR_DOMAIN_AFFECT_LIVE;
7184
flags = VIR_DOMAIN_AFFECT_CONFIG;
7187
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
7188
if (!vm->persistent) {
7189
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
7190
_("cannot query persistent config of a transient domain"));
7195
virDomainDefPtr persistentDef;
7197
persistentDef = virDomainObjGetPersistentDef(driver->caps, vm);
7198
if (!persistentDef) {
7199
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
7200
_("can't get persistentDef"));
7203
shares = persistentDef->cputune.shares;
7204
if (*nparams > 1 && cpu_bw_status) {
7205
period = persistentDef->cputune.period;
7206
quota = persistentDef->cputune.quota;
7209
shares = vm->def->cputune.shares;
7210
if (*nparams > 1 && cpu_bw_status) {
7211
period = vm->def->cputune.period;
7212
quota = vm->def->cputune.quota;
7219
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
7220
_("domain is not running"));
7224
if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
7225
qemuReportError(VIR_ERR_OPERATION_INVALID,
7226
"%s", _("cgroup CPU controller is not mounted"));
7230
if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
7231
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7232
_("cannot find cgroup for domain %s"), vm->def->name);
7236
rc = virCgroupGetCpuShares(group, &shares);
7238
virReportSystemError(-rc, "%s",
7239
_("unable to get cpu shares tunable"));
7243
if (*nparams > 1 && cpu_bw_status) {
7244
rc = qemuGetVcpusBWLive(vm, group, &period, "a);
7249
params[0].value.ul = shares;
7250
params[0].type = VIR_TYPED_PARAM_ULLONG;
7251
if (virStrcpyStatic(params[0].field,
7252
VIR_DOMAIN_SCHEDULER_CPU_SHARES) == NULL) {
7253
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7254
_("Field name '%s' too long"),
7255
VIR_DOMAIN_SCHEDULER_CPU_SHARES);
7261
if (cpu_bw_status) {
7262
if (*nparams > saved_nparams) {
7263
params[1].value.ul = period;
7264
params[1].type = VIR_TYPED_PARAM_ULLONG;
7265
if (virStrcpyStatic(params[1].field,
7266
VIR_DOMAIN_SCHEDULER_VCPU_PERIOD) == NULL) {
7267
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7268
_("Field name '%s' too long"),
7269
VIR_DOMAIN_SCHEDULER_VCPU_PERIOD);
7275
if (*nparams > saved_nparams) {
7276
params[2].value.ul = quota;
7277
params[2].type = VIR_TYPED_PARAM_LLONG;
7278
if (virStrcpyStatic(params[2].field,
7279
VIR_DOMAIN_SCHEDULER_VCPU_QUOTA) == NULL) {
7280
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7281
_("Field name '%s' too long"),
7282
VIR_DOMAIN_SCHEDULER_VCPU_QUOTA);
7289
*nparams = saved_nparams;
7294
virCgroupFree(&group);
7296
virDomainObjUnlock(vm);
7297
qemuDriverUnlock(driver);
7302
qemuGetSchedulerParameters(virDomainPtr dom,
7303
virTypedParameterPtr params,
7306
return qemuGetSchedulerParametersFlags(dom, params, nparams,
7307
VIR_DOMAIN_AFFECT_CURRENT);
7311
* Resize a block device while a guest is running. Resize to a lower size
7312
* is supported, but should be used with extreme caution. Note that it
7313
* only supports to resize image files, it can't resize block devices
7317
qemuDomainBlockResize (virDomainPtr dom,
7319
unsigned long long size,
7322
struct qemud_driver *driver = dom->conn->privateData;
7324
qemuDomainObjPrivatePtr priv;
7326
char *device = NULL;
7327
virDomainDiskDefPtr disk = NULL;
7329
virCheckFlags(0, -1);
7331
if (path[0] == '\0') {
7332
qemuReportError(VIR_ERR_INVALID_ARG,
7333
"%s", _("empty path"));
7337
if (size > ULLONG_MAX / 1024) {
7338
qemuReportError(VIR_ERR_INVALID_ARG,
7339
_("size must be less than %llu"),
7344
qemuDriverLock(driver);
7345
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
7346
qemuDriverUnlock(driver);
7349
char uuidstr[VIR_UUID_STRING_BUFLEN];
7350
virUUIDFormat(dom->uuid, uuidstr);
7351
qemuReportError(VIR_ERR_NO_DOMAIN,
7352
_("no domain matching uuid '%s'"), uuidstr);
7356
priv = vm->privateData;
7358
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
7361
if (!virDomainObjIsActive(vm)) {
7362
qemuReportError(VIR_ERR_OPERATION_INVALID,
7363
"%s", _("domain is not running"));
7367
if ((i = virDomainDiskIndexByName(vm->def, path, false)) < 0) {
7368
qemuReportError(VIR_ERR_INVALID_ARG,
7369
_("invalid path: %s"), path);
7372
disk = vm->def->disks[i];
7374
if (virAsprintf(&device, "%s%s", QEMU_DRIVE_HOST_PREFIX,
7375
disk->info.alias) < 0) {
7376
virReportOOMError();
7380
qemuDomainObjEnterMonitor(driver, vm);
7381
if (qemuMonitorBlockResize(priv->mon, device, size) < 0) {
7382
qemuDomainObjExitMonitor(driver, vm);
7385
qemuDomainObjExitMonitor(driver, vm);
7390
if (qemuDomainObjEndJob(driver, vm) == 0)
7396
virDomainObjUnlock(vm);
7400
/* This uses the 'info blockstats' monitor command which was
7401
* integrated into both qemu & kvm in late 2007. If the command is
7402
* not supported we detect this and return the appropriate error.
7405
qemuDomainBlockStats(virDomainPtr dom,
7407
struct _virDomainBlockStats *stats)
7409
struct qemud_driver *driver = dom->conn->privateData;
7412
virDomainDiskDefPtr disk = NULL;
7413
qemuDomainObjPrivatePtr priv;
7415
qemuDriverLock(driver);
7416
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
7417
qemuDriverUnlock(driver);
7419
char uuidstr[VIR_UUID_STRING_BUFLEN];
7420
virUUIDFormat(dom->uuid, uuidstr);
7421
qemuReportError(VIR_ERR_NO_DOMAIN,
7422
_("no domain with matching uuid '%s'"), uuidstr);
7426
if (!virDomainObjIsActive(vm)) {
7427
qemuReportError(VIR_ERR_OPERATION_INVALID,
7428
"%s", _("domain is not running"));
7432
if ((i = virDomainDiskIndexByName(vm->def, path, false)) < 0) {
7433
qemuReportError(VIR_ERR_INVALID_ARG,
7434
_("invalid path: %s"), path);
7437
disk = vm->def->disks[i];
7439
if (!disk->info.alias) {
7440
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7441
_("missing disk device alias name for %s"), disk->dst);
7445
priv = vm->privateData;
7446
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
7449
if (!virDomainObjIsActive(vm)) {
7450
qemuReportError(VIR_ERR_OPERATION_INVALID,
7451
"%s", _("domain is not running"));
7455
qemuDomainObjEnterMonitor(driver, vm);
7456
ret = qemuMonitorGetBlockStatsInfo(priv->mon,
7467
qemuDomainObjExitMonitor(driver, vm);
7470
if (qemuDomainObjEndJob(driver, vm) == 0)
7475
virDomainObjUnlock(vm);
7480
qemuDomainBlockStatsFlags(virDomainPtr dom,
7482
virTypedParameterPtr params,
7486
struct qemud_driver *driver = dom->conn->privateData;
7487
int i, tmp, ret = -1;
7489
virDomainDiskDefPtr disk = NULL;
7490
qemuDomainObjPrivatePtr priv;
7491
long long rd_req, rd_bytes, wr_req, wr_bytes, rd_total_times;
7492
long long wr_total_times, flush_req, flush_total_times, errs;
7493
virTypedParameterPtr param;
7495
virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
7497
/* We don't return strings, and thus trivially support this flag. */
7498
flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
7500
qemuDriverLock(driver);
7501
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
7502
qemuDriverUnlock(driver);
7504
char uuidstr[VIR_UUID_STRING_BUFLEN];
7505
virUUIDFormat(dom->uuid, uuidstr);
7506
qemuReportError(VIR_ERR_NO_DOMAIN,
7507
_("no domain with matching uuid '%s'"), uuidstr);
7511
if (!virDomainObjIsActive(vm)) {
7512
qemuReportError(VIR_ERR_OPERATION_INVALID,
7513
"%s", _("domain is not running"));
7517
if (*nparams != 0) {
7518
if ((i = virDomainDiskIndexByName(vm->def, path, false)) < 0) {
7519
qemuReportError(VIR_ERR_INVALID_ARG,
7520
_("invalid path: %s"), path);
7523
disk = vm->def->disks[i];
7525
if (!disk->info.alias) {
7526
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7527
_("missing disk device alias name for %s"),
7533
priv = vm->privateData;
7534
VIR_DEBUG("priv=%p, params=%p, flags=%x", priv, params, flags);
7536
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
7539
if (!virDomainObjIsActive(vm)) {
7540
qemuReportError(VIR_ERR_OPERATION_INVALID,
7541
"%s", _("domain is not running"));
7545
qemuDomainObjEnterMonitor(driver, vm);
7547
ret = qemuMonitorGetBlockStatsParamsNumber(priv->mon, nparams);
7549
if (tmp == 0 || ret < 0) {
7550
qemuDomainObjExitMonitor(driver, vm);
7554
ret = qemuMonitorGetBlockStatsInfo(priv->mon,
7566
qemuDomainObjExitMonitor(driver, vm);
7574
if (tmp < *nparams && wr_bytes != -1) {
7575
param = ¶ms[tmp];
7576
if (virStrcpyStatic(param->field,
7577
VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES) == NULL) {
7578
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7579
_("Field name '%s' too long"),
7580
VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES);
7583
param->type = VIR_TYPED_PARAM_LLONG;
7584
param->value.l = wr_bytes;
7588
if (tmp < *nparams && wr_req != -1) {
7589
param = ¶ms[tmp];
7590
if (virStrcpyStatic(param->field,
7591
VIR_DOMAIN_BLOCK_STATS_WRITE_REQ) == NULL) {
7592
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7593
_("Field name '%s' too long"),
7594
VIR_DOMAIN_BLOCK_STATS_WRITE_REQ);
7597
param->type = VIR_TYPED_PARAM_LLONG;
7598
param->value.l = wr_req;
7602
if (tmp < *nparams && rd_bytes != -1) {
7603
param = ¶ms[tmp];
7604
if (virStrcpyStatic(param->field,
7605
VIR_DOMAIN_BLOCK_STATS_READ_BYTES) == NULL) {
7606
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7607
_("Field name '%s' too long"),
7608
VIR_DOMAIN_BLOCK_STATS_READ_BYTES);
7611
param->type = VIR_TYPED_PARAM_LLONG;
7612
param->value.l = rd_bytes;
7616
if (tmp < *nparams && rd_req != -1) {
7617
param = ¶ms[tmp];
7618
if (virStrcpyStatic(param->field,
7619
VIR_DOMAIN_BLOCK_STATS_READ_REQ) == NULL) {
7620
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7621
_("Field name '%s' too long"),
7622
VIR_DOMAIN_BLOCK_STATS_READ_REQ);
7625
param->type = VIR_TYPED_PARAM_LLONG;
7626
param->value.l = rd_req;
7630
if (tmp < *nparams && flush_req != -1) {
7631
param = ¶ms[tmp];
7632
if (virStrcpyStatic(param->field,
7633
VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ) == NULL) {
7634
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7635
_("Field name '%s' too long"),
7636
VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ);
7639
param->type = VIR_TYPED_PARAM_LLONG;
7640
param->value.l = flush_req;
7644
if (tmp < *nparams && wr_total_times != -1) {
7645
param = ¶ms[tmp];
7646
if (virStrcpyStatic(param->field,
7647
VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES) == NULL) {
7648
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7649
_("Field name '%s' too long"),
7650
VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES);
7653
param->type = VIR_TYPED_PARAM_LLONG;
7654
param->value.l = wr_total_times;
7658
if (tmp < *nparams && rd_total_times != -1) {
7659
param = ¶ms[tmp];
7660
if (virStrcpyStatic(param->field,
7661
VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES) == NULL) {
7662
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7663
_("Field name '%s' too long"),
7664
VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES);
7667
param->type = VIR_TYPED_PARAM_LLONG;
7668
param->value.l = rd_total_times;
7672
if (tmp < *nparams && flush_total_times != -1) {
7673
param = ¶ms[tmp];
7674
if (virStrcpyStatic(param->field,
7675
VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES) == NULL) {
7676
qemuReportError(VIR_ERR_INTERNAL_ERROR,
7677
_("Field name '%s' too long"),
7678
VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES);
7681
param->type = VIR_TYPED_PARAM_LLONG;
7682
param->value.l = flush_total_times;
7686
/* Field 'errs' is meaningless for QEMU, won't set it. */
7692
if (qemuDomainObjEndJob(driver, vm) == 0)
7697
virDomainObjUnlock(vm);
7703
qemudDomainInterfaceStats (virDomainPtr dom,
7705
struct _virDomainInterfaceStats *stats)
7707
struct qemud_driver *driver = dom->conn->privateData;
7712
qemuDriverLock(driver);
7713
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
7714
qemuDriverUnlock(driver);
7717
char uuidstr[VIR_UUID_STRING_BUFLEN];
7718
virUUIDFormat(dom->uuid, uuidstr);
7719
qemuReportError(VIR_ERR_NO_DOMAIN,
7720
_("no domain with matching uuid '%s'"), uuidstr);
7724
if (!virDomainObjIsActive(vm)) {
7725
qemuReportError(VIR_ERR_OPERATION_INVALID,
7726
"%s", _("domain is not running"));
7730
/* Check the path is one of the domain's network interfaces. */
7731
for (i = 0 ; i < vm->def->nnets ; i++) {
7732
if (vm->def->nets[i]->ifname &&
7733
STREQ (vm->def->nets[i]->ifname, path)) {
7740
ret = linuxDomainInterfaceStats(path, stats);
7742
qemuReportError(VIR_ERR_INVALID_ARG,
7743
_("invalid path, '%s' is not a known interface"), path);
7747
virDomainObjUnlock(vm);
7752
qemudDomainInterfaceStats (virDomainPtr dom,
7753
const char *path ATTRIBUTE_UNUSED,
7754
struct _virDomainInterfaceStats *stats ATTRIBUTE_UNUSED)
7756
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
7757
_("interface stats not implemented on this platform"));
7763
qemudDomainMemoryStats (virDomainPtr dom,
7764
struct _virDomainMemoryStat *stats,
7765
unsigned int nr_stats,
7768
struct qemud_driver *driver = dom->conn->privateData;
7770
unsigned int ret = -1;
7772
virCheckFlags(0, -1);
7774
qemuDriverLock(driver);
7775
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
7776
qemuDriverUnlock(driver);
7779
char uuidstr[VIR_UUID_STRING_BUFLEN];
7780
virUUIDFormat(dom->uuid, uuidstr);
7781
qemuReportError(VIR_ERR_NO_DOMAIN,
7782
_("no domain with matching uuid '%s'"), uuidstr);
7786
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
7789
if (virDomainObjIsActive(vm)) {
7790
qemuDomainObjPrivatePtr priv = vm->privateData;
7791
qemuDomainObjEnterMonitor(driver, vm);
7792
ret = qemuMonitorGetMemoryStats(priv->mon, stats, nr_stats);
7793
qemuDomainObjExitMonitor(driver, vm);
7795
qemuReportError(VIR_ERR_OPERATION_INVALID,
7796
"%s", _("domain is not running"));
7799
if (qemuDomainObjEndJob(driver, vm) == 0)
7804
virDomainObjUnlock(vm);
7809
qemudDomainBlockPeek (virDomainPtr dom,
7811
unsigned long long offset, size_t size,
7815
struct qemud_driver *driver = dom->conn->privateData;
7817
int fd = -1, ret = -1;
7820
virCheckFlags(0, -1);
7822
qemuDriverLock(driver);
7823
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
7824
qemuDriverUnlock(driver);
7827
char uuidstr[VIR_UUID_STRING_BUFLEN];
7828
virUUIDFormat(dom->uuid, uuidstr);
7829
qemuReportError(VIR_ERR_NO_DOMAIN,
7830
_("no domain with matching uuid '%s'"), uuidstr);
7834
if (!path || path[0] == '\0') {
7835
qemuReportError(VIR_ERR_INVALID_ARG,
7836
"%s", _("NULL or empty path"));
7840
/* Check the path belongs to this domain. */
7841
if (!(actual = virDomainDiskPathByName(vm->def, path))) {
7842
qemuReportError(VIR_ERR_INVALID_ARG,
7843
_("invalid path '%s'"), path);
7848
/* The path is correct, now try to open it and get its size. */
7849
fd = open(path, O_RDONLY);
7851
virReportSystemError(errno,
7852
_("%s: failed to open"), path);
7856
/* Seek and read. */
7857
/* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
7858
* be 64 bits on all platforms.
7860
if (lseek(fd, offset, SEEK_SET) == (off_t) -1 ||
7861
saferead(fd, buffer, size) == (ssize_t) -1) {
7862
virReportSystemError(errno,
7863
_("%s: failed to seek or read"), path);
7870
VIR_FORCE_CLOSE(fd);
7872
virDomainObjUnlock(vm);
7877
qemudDomainMemoryPeek (virDomainPtr dom,
7878
unsigned long long offset, size_t size,
7882
struct qemud_driver *driver = dom->conn->privateData;
7885
int fd = -1, ret = -1;
7886
qemuDomainObjPrivatePtr priv;
7888
virCheckFlags(VIR_MEMORY_VIRTUAL | VIR_MEMORY_PHYSICAL, -1);
7890
qemuDriverLock(driver);
7891
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
7892
qemuDriverUnlock(driver);
7895
char uuidstr[VIR_UUID_STRING_BUFLEN];
7896
virUUIDFormat(dom->uuid, uuidstr);
7897
qemuReportError(VIR_ERR_NO_DOMAIN,
7898
_("no domain with matching uuid '%s'"), uuidstr);
7902
if (flags != VIR_MEMORY_VIRTUAL && flags != VIR_MEMORY_PHYSICAL) {
7903
qemuReportError(VIR_ERR_INVALID_ARG,
7904
"%s", _("flags parameter must be VIR_MEMORY_VIRTUAL or VIR_MEMORY_PHYSICAL"));
7908
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
7911
if (!virDomainObjIsActive(vm)) {
7912
qemuReportError(VIR_ERR_OPERATION_INVALID,
7913
"%s", _("domain is not running"));
7917
if (virAsprintf(&tmp, "%s/qemu.mem.XXXXXX", driver->cacheDir) < 0) {
7918
virReportOOMError();
7922
/* Create a temporary filename. */
7923
if ((fd = mkstemp (tmp)) == -1) {
7924
virReportSystemError(errno,
7925
_("mkstemp(\"%s\") failed"), tmp);
7929
virSecurityManagerSetSavedStateLabel(qemu_driver->securityManager, vm, tmp);
7931
priv = vm->privateData;
7932
qemuDomainObjEnterMonitor(driver, vm);
7933
if (flags == VIR_MEMORY_VIRTUAL) {
7934
if (qemuMonitorSaveVirtualMemory(priv->mon, offset, size, tmp) < 0) {
7935
qemuDomainObjExitMonitor(driver, vm);
7939
if (qemuMonitorSavePhysicalMemory(priv->mon, offset, size, tmp) < 0) {
7940
qemuDomainObjExitMonitor(driver, vm);
7944
qemuDomainObjExitMonitor(driver, vm);
7946
/* Read the memory file into buffer. */
7947
if (saferead(fd, buffer, size) == (ssize_t) -1) {
7948
virReportSystemError(errno,
7949
_("failed to read temporary file "
7950
"created with template %s"), tmp);
7957
if (qemuDomainObjEndJob(driver, vm) == 0)
7961
VIR_FORCE_CLOSE(fd);
7966
virDomainObjUnlock(vm);
7971
static int qemuDomainGetBlockInfo(virDomainPtr dom,
7973
virDomainBlockInfoPtr info,
7974
unsigned int flags) {
7975
struct qemud_driver *driver = dom->conn->privateData;
7980
virStorageFileMetadata *meta = NULL;
7981
virDomainDiskDefPtr disk = NULL;
7986
virCheckFlags(0, -1);
7988
qemuDriverLock(driver);
7989
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
7990
qemuDriverUnlock(driver);
7992
char uuidstr[VIR_UUID_STRING_BUFLEN];
7993
virUUIDFormat(dom->uuid, uuidstr);
7994
qemuReportError(VIR_ERR_NO_DOMAIN,
7995
_("no domain with matching uuid '%s'"), uuidstr);
7999
if (!path || path[0] == '\0') {
8000
qemuReportError(VIR_ERR_INVALID_ARG,
8001
"%s", _("NULL or empty path"));
8005
/* Check the path belongs to this domain. */
8006
if ((i = virDomainDiskIndexByName(vm->def, path, false)) < 0) {
8007
qemuReportError(VIR_ERR_INVALID_ARG,
8008
_("invalid path %s not assigned to domain"), path);
8011
disk = vm->def->disks[i];
8013
qemuReportError(VIR_ERR_INVALID_ARG,
8014
_("disk %s does not currently have a source assigned"),
8020
/* The path is correct, now try to open it and get its size. */
8021
fd = open(path, O_RDONLY);
8023
virReportSystemError(errno,
8024
_("failed to open path '%s'"), path);
8028
/* Probe for magic formats */
8029
if (disk->driverType) {
8030
if ((format = virStorageFileFormatTypeFromString(disk->driverType)) < 0) {
8031
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8032
_("unknown disk format %s for %s"),
8033
disk->driverType, disk->src);
8037
if (driver->allowDiskFormatProbing) {
8038
if ((format = virStorageFileProbeFormat(disk->src)) < 0)
8041
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8042
_("no disk format for %s and probing is disabled"),
8048
if (VIR_ALLOC(meta) < 0) {
8049
virReportOOMError();
8053
if (virStorageFileGetMetadataFromFD(path, fd,
8058
/* Get info for normal formats */
8059
if (fstat(fd, &sb) < 0) {
8060
virReportSystemError(errno,
8061
_("cannot stat file '%s'"), path);
8065
if (S_ISREG(sb.st_mode)) {
8067
info->physical = (unsigned long long)sb.st_blocks *
8068
(unsigned long long)DEV_BSIZE;
8070
info->physical = sb.st_size;
8072
/* Regular files may be sparse, so logical size (capacity) is not same
8073
* as actual physical above
8075
info->capacity = sb.st_size;
8077
/* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
8078
* be 64 bits on all platforms.
8080
end = lseek(fd, 0, SEEK_END);
8081
if (end == (off_t)-1) {
8082
virReportSystemError(errno,
8083
_("failed to seek to end of %s"), path);
8086
info->physical = end;
8087
info->capacity = end;
8090
/* If the file we probed has a capacity set, then override
8091
* what we calculated from file/block extents */
8093
info->capacity = meta->capacity;
8095
/* Set default value .. */
8096
info->allocation = info->physical;
8098
/* ..but if guest is running & not using raw
8099
disk format and on a block device, then query
8100
highest allocated extent from QEMU */
8101
if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK &&
8102
format != VIR_STORAGE_FILE_RAW &&
8103
S_ISBLK(sb.st_mode) &&
8104
virDomainObjIsActive(vm)) {
8105
qemuDomainObjPrivatePtr priv = vm->privateData;
8107
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
8110
if (virDomainObjIsActive(vm)) {
8111
qemuDomainObjEnterMonitor(driver, vm);
8112
ret = qemuMonitorGetBlockExtent(priv->mon,
8115
qemuDomainObjExitMonitor(driver, vm);
8120
if (qemuDomainObjEndJob(driver, vm) == 0)
8127
virStorageFileFreeMetadata(meta);
8128
VIR_FORCE_CLOSE(fd);
8130
virDomainObjUnlock(vm);
8136
qemuDomainEventRegister(virConnectPtr conn,
8137
virConnectDomainEventCallback callback,
8139
virFreeCallback freecb)
8141
struct qemud_driver *driver = conn->privateData;
8144
qemuDriverLock(driver);
8145
ret = virDomainEventCallbackListAdd(conn,
8146
driver->domainEventState->callbacks,
8147
callback, opaque, freecb);
8148
qemuDriverUnlock(driver);
8155
qemuDomainEventDeregister(virConnectPtr conn,
8156
virConnectDomainEventCallback callback)
8158
struct qemud_driver *driver = conn->privateData;
8161
qemuDriverLock(driver);
8162
ret = virDomainEventStateDeregister(conn,
8163
driver->domainEventState,
8165
qemuDriverUnlock(driver);
8172
qemuDomainEventRegisterAny(virConnectPtr conn,
8175
virConnectDomainEventGenericCallback callback,
8177
virFreeCallback freecb)
8179
struct qemud_driver *driver = conn->privateData;
8182
qemuDriverLock(driver);
8183
ret = virDomainEventCallbackListAddID(conn,
8184
driver->domainEventState->callbacks,
8186
callback, opaque, freecb);
8187
qemuDriverUnlock(driver);
8194
qemuDomainEventDeregisterAny(virConnectPtr conn,
8197
struct qemud_driver *driver = conn->privateData;
8200
qemuDriverLock(driver);
8201
ret = virDomainEventStateDeregisterAny(conn,
8202
driver->domainEventState,
8204
qemuDriverUnlock(driver);
8210
/*******************************************************************
8211
* Migration Protocol Version 2
8212
*******************************************************************/
8214
/* Prepare is the first step, and it runs on the destination host.
8216
* This version starts an empty VM listening on a localhost TCP port, and
8217
* sets up the corresponding virStream to handle the incoming data.
8220
qemudDomainMigratePrepareTunnel(virConnectPtr dconn,
8222
unsigned long flags,
8224
unsigned long resource ATTRIBUTE_UNUSED,
8225
const char *dom_xml)
8227
struct qemud_driver *driver = dconn->privateData;
8230
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
8232
qemuDriverLock(driver);
8235
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8236
"%s", _("no domain XML passed"));
8239
if (!(flags & VIR_MIGRATE_TUNNELLED)) {
8240
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8241
"%s", _("PrepareTunnel called but no TUNNELLED flag set"));
8245
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8246
"%s", _("tunnelled migration requested but NULL stream passed"));
8250
if (virLockManagerPluginUsesState(driver->lockManager)) {
8251
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8252
_("Cannot use migrate v2 protocol with lock manager %s"),
8253
virLockManagerPluginGetName(driver->lockManager));
8257
ret = qemuMigrationPrepareTunnel(driver, dconn,
8258
NULL, 0, NULL, NULL, /* No cookies in v2 */
8259
st, dname, dom_xml);
8262
qemuDriverUnlock(driver);
8266
/* Prepare is the first step, and it runs on the destination host.
8268
* This starts an empty VM listening on a TCP port.
8270
static int ATTRIBUTE_NONNULL (5)
8271
qemudDomainMigratePrepare2 (virConnectPtr dconn,
8272
char **cookie ATTRIBUTE_UNUSED,
8273
int *cookielen ATTRIBUTE_UNUSED,
8276
unsigned long flags,
8278
unsigned long resource ATTRIBUTE_UNUSED,
8279
const char *dom_xml)
8281
struct qemud_driver *driver = dconn->privateData;
8284
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
8288
qemuDriverLock(driver);
8290
if (virLockManagerPluginUsesState(driver->lockManager)) {
8291
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8292
_("Cannot use migrate v2 protocol with lock manager %s"),
8293
virLockManagerPluginGetName(driver->lockManager));
8297
if (flags & VIR_MIGRATE_TUNNELLED) {
8298
/* this is a logical error; we never should have gotten here with
8299
* VIR_MIGRATE_TUNNELLED set
8301
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8302
"%s", _("Tunnelled migration requested but invalid RPC method called"));
8307
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8308
"%s", _("no domain XML passed"));
8312
/* Do not use cookies in v2 protocol, since the cookie
8313
* length was not sufficiently large, causing failures
8314
* migrating between old & new libvirtd
8316
ret = qemuMigrationPrepareDirect(driver, dconn,
8317
NULL, 0, NULL, NULL, /* No cookies */
8322
qemuDriverUnlock(driver);
8327
/* Perform is the second step, and it runs on the source host. */
8329
qemudDomainMigratePerform (virDomainPtr dom,
8333
unsigned long flags,
8335
unsigned long resource)
8337
struct qemud_driver *driver = dom->conn->privateData;
8340
const char *dconnuri = NULL;
8342
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
8344
qemuDriverLock(driver);
8345
if (virLockManagerPluginUsesState(driver->lockManager)) {
8346
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8347
_("Cannot use migrate v2 protocol with lock manager %s"),
8348
virLockManagerPluginGetName(driver->lockManager));
8352
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
8354
char uuidstr[VIR_UUID_STRING_BUFLEN];
8355
virUUIDFormat(dom->uuid, uuidstr);
8356
qemuReportError(VIR_ERR_NO_DOMAIN,
8357
_("no domain with matching uuid '%s'"), uuidstr);
8361
if (flags & VIR_MIGRATE_PEER2PEER) {
8366
/* Do not output cookies in v2 protocol, since the cookie
8367
* length was not sufficiently large, causing failures
8368
* migrating between old & new libvirtd.
8370
* Consume any cookie we were able to decode though
8372
ret = qemuMigrationPerform(driver, dom->conn, vm,
8373
NULL, dconnuri, uri, cookie, cookielen,
8374
NULL, NULL, /* No output cookies in v2 */
8375
flags, dname, resource, false);
8378
qemuDriverUnlock(driver);
8383
/* Finish is the third and final step, and it runs on the destination host. */
8385
qemudDomainMigrateFinish2 (virConnectPtr dconn,
8387
const char *cookie ATTRIBUTE_UNUSED,
8388
int cookielen ATTRIBUTE_UNUSED,
8389
const char *uri ATTRIBUTE_UNUSED,
8390
unsigned long flags,
8393
struct qemud_driver *driver = dconn->privateData;
8395
virDomainPtr dom = NULL;
8397
virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
8399
qemuDriverLock(driver);
8400
vm = virDomainFindByName(&driver->domains, dname);
8402
qemuReportError(VIR_ERR_NO_DOMAIN,
8403
_("no domain with matching name '%s'"), dname);
8407
/* Do not use cookies in v2 protocol, since the cookie
8408
* length was not sufficiently large, causing failures
8409
* migrating between old & new libvirtd
8411
dom = qemuMigrationFinish(driver, dconn, vm,
8412
NULL, 0, NULL, NULL, /* No cookies */
8413
flags, retcode, false);
8416
qemuDriverUnlock(driver);
8421
/*******************************************************************
8422
* Migration Protocol Version 3
8423
*******************************************************************/
8426
qemuDomainMigrateBegin3(virDomainPtr domain,
8430
unsigned long flags,
8432
unsigned long resource ATTRIBUTE_UNUSED)
8434
struct qemud_driver *driver = domain->conn->privateData;
8438
virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
8440
qemuDriverLock(driver);
8441
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
8443
char uuidstr[VIR_UUID_STRING_BUFLEN];
8444
virUUIDFormat(domain->uuid, uuidstr);
8445
qemuReportError(VIR_ERR_NO_DOMAIN,
8446
_("no domain with matching uuid '%s'"), uuidstr);
8450
if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
8451
if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
8454
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
8458
if (!virDomainObjIsActive(vm)) {
8459
qemuReportError(VIR_ERR_OPERATION_INVALID,
8460
"%s", _("domain is not running"));
8464
/* Check if there is any ejected media.
8465
* We don't want to require them on the destination.
8468
if (qemuDomainCheckEjectableMedia(driver, vm) < 0)
8471
if (!(xml = qemuMigrationBegin(driver, vm, xmlin, dname,
8472
cookieout, cookieoutlen)))
8475
if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
8476
/* We keep the job active across API calls until the confirm() call.
8477
* This prevents any other APIs being invoked while migration is taking
8480
if (qemuMigrationJobContinue(vm) == 0) {
8482
qemuReportError(VIR_ERR_OPERATION_FAILED,
8483
"%s", _("domain disappeared"));
8486
VIR_FREE(*cookieout);
8494
virDomainObjUnlock(vm);
8495
qemuDriverUnlock(driver);
8499
if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
8500
if (qemuMigrationJobFinish(driver, vm) == 0)
8503
if (qemuDomainObjEndJob(driver, vm) == 0)
8510
qemuDomainMigratePrepare3(virConnectPtr dconn,
8511
const char *cookiein,
8517
unsigned long flags,
8519
unsigned long resource ATTRIBUTE_UNUSED,
8520
const char *dom_xml)
8522
struct qemud_driver *driver = dconn->privateData;
8525
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
8529
qemuDriverLock(driver);
8530
if (flags & VIR_MIGRATE_TUNNELLED) {
8531
/* this is a logical error; we never should have gotten here with
8532
* VIR_MIGRATE_TUNNELLED set
8534
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8535
"%s", _("Tunnelled migration requested but invalid RPC method called"));
8540
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8541
"%s", _("no domain XML passed"));
8545
ret = qemuMigrationPrepareDirect(driver, dconn,
8546
cookiein, cookieinlen,
8547
cookieout, cookieoutlen,
8552
qemuDriverUnlock(driver);
8558
qemuDomainMigratePrepareTunnel3(virConnectPtr dconn,
8560
const char *cookiein,
8564
unsigned long flags,
8566
unsigned long resource ATTRIBUTE_UNUSED,
8567
const char *dom_xml)
8569
struct qemud_driver *driver = dconn->privateData;
8572
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
8575
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8576
"%s", _("no domain XML passed"));
8579
if (!(flags & VIR_MIGRATE_TUNNELLED)) {
8580
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8581
"%s", _("PrepareTunnel called but no TUNNELLED flag set"));
8585
qemuReportError(VIR_ERR_INTERNAL_ERROR,
8586
"%s", _("tunnelled migration requested but NULL stream passed"));
8590
qemuDriverLock(driver);
8591
ret = qemuMigrationPrepareTunnel(driver, dconn,
8592
cookiein, cookieinlen,
8593
cookieout, cookieoutlen,
8594
st, dname, dom_xml);
8595
qemuDriverUnlock(driver);
8603
qemuDomainMigratePerform3(virDomainPtr dom,
8605
const char *cookiein,
8609
const char *dconnuri,
8611
unsigned long flags,
8613
unsigned long resource)
8615
struct qemud_driver *driver = dom->conn->privateData;
8619
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
8621
qemuDriverLock(driver);
8622
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
8624
char uuidstr[VIR_UUID_STRING_BUFLEN];
8625
virUUIDFormat(dom->uuid, uuidstr);
8626
qemuReportError(VIR_ERR_NO_DOMAIN,
8627
_("no domain with matching uuid '%s'"), uuidstr);
8631
ret = qemuMigrationPerform(driver, dom->conn, vm, xmlin,
8632
dconnuri, uri, cookiein, cookieinlen,
8633
cookieout, cookieoutlen,
8634
flags, dname, resource, true);
8637
qemuDriverUnlock(driver);
8643
qemuDomainMigrateFinish3(virConnectPtr dconn,
8645
const char *cookiein,
8649
const char *dconnuri ATTRIBUTE_UNUSED,
8650
const char *uri ATTRIBUTE_UNUSED,
8651
unsigned long flags,
8654
struct qemud_driver *driver = dconn->privateData;
8656
virDomainPtr dom = NULL;
8658
virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
8660
qemuDriverLock(driver);
8661
vm = virDomainFindByName(&driver->domains, dname);
8663
qemuReportError(VIR_ERR_NO_DOMAIN,
8664
_("no domain with matching name '%s'"), dname);
8668
dom = qemuMigrationFinish(driver, dconn, vm,
8669
cookiein, cookieinlen,
8670
cookieout, cookieoutlen,
8671
flags, cancelled, true);
8674
qemuDriverUnlock(driver);
8679
qemuDomainMigrateConfirm3(virDomainPtr domain,
8680
const char *cookiein,
8682
unsigned long flags,
8685
struct qemud_driver *driver = domain->conn->privateData;
8688
enum qemuMigrationJobPhase phase;
8690
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
8692
qemuDriverLock(driver);
8693
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
8695
char uuidstr[VIR_UUID_STRING_BUFLEN];
8696
virUUIDFormat(domain->uuid, uuidstr);
8697
qemuReportError(VIR_ERR_NO_DOMAIN,
8698
_("no domain with matching uuid '%s'"), uuidstr);
8702
if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT))
8706
phase = QEMU_MIGRATION_PHASE_CONFIRM3_CANCELLED;
8708
phase = QEMU_MIGRATION_PHASE_CONFIRM3;
8710
qemuMigrationJobStartPhase(driver, vm, phase);
8712
ret = qemuMigrationConfirm(driver, domain->conn, vm,
8713
cookiein, cookieinlen,
8716
if (qemuMigrationJobFinish(driver, vm) == 0) {
8718
} else if (!virDomainObjIsActive(vm) &&
8719
(!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE))) {
8720
if (flags & VIR_MIGRATE_UNDEFINE_SOURCE)
8721
virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
8722
qemuDomainRemoveInactive(driver, vm);
8728
virDomainObjUnlock(vm);
8729
qemuDriverUnlock(driver);
8735
qemudNodeDeviceGetPciInfo (virNodeDevicePtr dev,
8741
virNodeDeviceDefPtr def = NULL;
8742
virNodeDevCapsDefPtr cap;
8746
xml = virNodeDeviceGetXMLDesc(dev, 0);
8750
def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE);
8756
if (cap->type == VIR_NODE_DEV_CAP_PCI_DEV) {
8757
*domain = cap->data.pci_dev.domain;
8758
*bus = cap->data.pci_dev.bus;
8759
*slot = cap->data.pci_dev.slot;
8760
*function = cap->data.pci_dev.function;
8768
qemuReportError(VIR_ERR_INVALID_ARG,
8769
_("device %s is not a PCI device"), dev->name);
8775
virNodeDeviceDefFree(def);
8781
qemudNodeDeviceDettach (virNodeDevicePtr dev)
8783
struct qemud_driver *driver = dev->conn->privateData;
8785
unsigned domain, bus, slot, function;
8788
if (qemudNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
8791
pci = pciGetDevice(domain, bus, slot, function);
8795
qemuDriverLock(driver);
8796
if (pciDettachDevice(pci, driver->activePciHostdevs) < 0)
8801
qemuDriverUnlock(driver);
8807
qemudNodeDeviceReAttach (virNodeDevicePtr dev)
8809
struct qemud_driver *driver = dev->conn->privateData;
8811
unsigned domain, bus, slot, function;
8814
if (qemudNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
8817
pci = pciGetDevice(domain, bus, slot, function);
8821
pciDeviceReAttachInit(pci);
8823
qemuDriverLock(driver);
8824
if (pciReAttachDevice(pci, driver->activePciHostdevs) < 0)
8829
qemuDriverUnlock(driver);
8835
qemudNodeDeviceReset (virNodeDevicePtr dev)
8837
struct qemud_driver *driver = dev->conn->privateData;
8839
unsigned domain, bus, slot, function;
8842
if (qemudNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
8845
pci = pciGetDevice(domain, bus, slot, function);
8849
qemuDriverLock(driver);
8851
if (pciResetDevice(pci, driver->activePciHostdevs, NULL) < 0)
8856
qemuDriverUnlock(driver);
8862
qemuCPUCompare(virConnectPtr conn,
8863
const char *xmlDesc,
8866
struct qemud_driver *driver = conn->privateData;
8867
int ret = VIR_CPU_COMPARE_ERROR;
8869
virCheckFlags(0, VIR_CPU_COMPARE_ERROR);
8871
qemuDriverLock(driver);
8873
if (!driver->caps || !driver->caps->host.cpu) {
8874
qemuReportError(VIR_ERR_OPERATION_INVALID,
8875
"%s", _("cannot get host CPU capabilities"));
8877
ret = cpuCompareXML(driver->caps->host.cpu, xmlDesc);
8880
qemuDriverUnlock(driver);
8887
qemuCPUBaseline(virConnectPtr conn ATTRIBUTE_UNUSED,
8888
const char **xmlCPUs,
8894
virCheckFlags(0, NULL);
8896
cpu = cpuBaselineXML(xmlCPUs, ncpus, NULL, 0);
8902
static int qemuDomainGetJobInfo(virDomainPtr dom,
8903
virDomainJobInfoPtr info) {
8904
struct qemud_driver *driver = dom->conn->privateData;
8907
qemuDomainObjPrivatePtr priv;
8909
qemuDriverLock(driver);
8910
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
8911
qemuDriverUnlock(driver);
8913
char uuidstr[VIR_UUID_STRING_BUFLEN];
8914
virUUIDFormat(dom->uuid, uuidstr);
8915
qemuReportError(VIR_ERR_NO_DOMAIN,
8916
_("no domain with matching uuid '%s'"), uuidstr);
8920
priv = vm->privateData;
8922
if (virDomainObjIsActive(vm)) {
8923
if (priv->job.asyncJob) {
8924
memcpy(info, &priv->job.info, sizeof(*info));
8926
/* Refresh elapsed time again just to ensure it
8927
* is fully updated. This is primarily for benefit
8928
* of incoming migration which we don't currently
8929
* monitor actively in the background thread
8931
if (virTimeMillisNow(&info->timeElapsed) < 0)
8933
info->timeElapsed -= priv->job.start;
8935
memset(info, 0, sizeof(*info));
8936
info->type = VIR_DOMAIN_JOB_NONE;
8939
qemuReportError(VIR_ERR_OPERATION_INVALID,
8940
"%s", _("domain is not running"));
8948
virDomainObjUnlock(vm);
8953
static int qemuDomainAbortJob(virDomainPtr dom) {
8954
struct qemud_driver *driver = dom->conn->privateData;
8957
qemuDomainObjPrivatePtr priv;
8959
qemuDriverLock(driver);
8960
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
8961
qemuDriverUnlock(driver);
8963
char uuidstr[VIR_UUID_STRING_BUFLEN];
8964
virUUIDFormat(dom->uuid, uuidstr);
8965
qemuReportError(VIR_ERR_NO_DOMAIN,
8966
_("no domain with matching uuid '%s'"), uuidstr);
8970
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_ABORT) < 0)
8973
if (!virDomainObjIsActive(vm)) {
8974
qemuReportError(VIR_ERR_OPERATION_INVALID,
8975
"%s", _("domain is not running"));
8979
priv = vm->privateData;
8981
if (!priv->job.asyncJob) {
8982
qemuReportError(VIR_ERR_OPERATION_INVALID,
8983
"%s", _("no job is active on the domain"));
8985
} else if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN) {
8986
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
8987
_("cannot abort incoming migration;"
8988
" use virDomainDestroy instead"));
8992
VIR_DEBUG("Cancelling job at client request");
8993
qemuDomainObjEnterMonitor(driver, vm);
8994
ret = qemuMonitorMigrateCancel(priv->mon);
8995
qemuDomainObjExitMonitor(driver, vm);
8998
if (qemuDomainObjEndJob(driver, vm) == 0)
9003
virDomainObjUnlock(vm);
9009
qemuDomainMigrateSetMaxDowntime(virDomainPtr dom,
9010
unsigned long long downtime,
9013
struct qemud_driver *driver = dom->conn->privateData;
9015
qemuDomainObjPrivatePtr priv;
9018
virCheckFlags(0, -1);
9020
qemuDriverLock(driver);
9021
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
9022
qemuDriverUnlock(driver);
9025
char uuidstr[VIR_UUID_STRING_BUFLEN];
9026
virUUIDFormat(dom->uuid, uuidstr);
9027
qemuReportError(VIR_ERR_NO_DOMAIN,
9028
_("no domain with matching uuid '%s'"), uuidstr);
9032
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) < 0)
9035
if (!virDomainObjIsActive(vm)) {
9036
qemuReportError(VIR_ERR_OPERATION_INVALID,
9037
"%s", _("domain is not running"));
9041
priv = vm->privateData;
9043
if (priv->job.asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT) {
9044
qemuReportError(VIR_ERR_OPERATION_INVALID,
9045
"%s", _("domain is not being migrated"));
9049
VIR_DEBUG("Setting migration downtime to %llums", downtime);
9050
qemuDomainObjEnterMonitor(driver, vm);
9051
ret = qemuMonitorSetMigrationDowntime(priv->mon, downtime);
9052
qemuDomainObjExitMonitor(driver, vm);
9055
if (qemuDomainObjEndJob(driver, vm) == 0)
9060
virDomainObjUnlock(vm);
9065
qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
9066
unsigned long bandwidth,
9069
struct qemud_driver *driver = dom->conn->privateData;
9071
qemuDomainObjPrivatePtr priv;
9074
virCheckFlags(0, -1);
9076
qemuDriverLock(driver);
9077
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
9078
qemuDriverUnlock(driver);
9081
char uuidstr[VIR_UUID_STRING_BUFLEN];
9082
virUUIDFormat(dom->uuid, uuidstr);
9083
qemuReportError(VIR_ERR_NO_DOMAIN,
9084
_("no domain with matching uuid '%s'"), uuidstr);
9088
priv = vm->privateData;
9089
if (virDomainObjIsActive(vm)) {
9090
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) < 0)
9093
if (!virDomainObjIsActive(vm)) {
9094
qemuReportError(VIR_ERR_OPERATION_INVALID,
9095
"%s", _("domain is not running"));
9099
VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth);
9100
qemuDomainObjEnterMonitor(driver, vm);
9101
ret = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
9102
qemuDomainObjExitMonitor(driver, vm);
9105
priv->migMaxBandwidth = bandwidth;
9108
if (qemuDomainObjEndJob(driver, vm) == 0)
9111
priv->migMaxBandwidth = bandwidth;
9117
virDomainObjUnlock(vm);
9122
qemuDomainMigrateGetMaxSpeed(virDomainPtr dom,
9123
unsigned long *bandwidth,
9126
struct qemud_driver *driver = dom->conn->privateData;
9128
qemuDomainObjPrivatePtr priv;
9131
virCheckFlags(0, -1);
9133
qemuDriverLock(driver);
9134
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
9135
qemuDriverUnlock(driver);
9138
char uuidstr[VIR_UUID_STRING_BUFLEN];
9139
virUUIDFormat(dom->uuid, uuidstr);
9140
qemuReportError(VIR_ERR_NO_DOMAIN,
9141
_("no domain with matching uuid '%s'"), uuidstr);
9145
priv = vm->privateData;
9146
*bandwidth = priv->migMaxBandwidth;
9151
virDomainObjUnlock(vm);
9155
static int qemuDomainSnapshotIsAllowed(virDomainObjPtr vm)
9159
/* FIXME: we need to figure out what else here might succeed; in
9160
* particular, if it's a raw device but on LVM, we could probably make
9161
* that succeed as well
9163
for (i = 0; i < vm->def->ndisks; i++) {
9164
if (vm->def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
9165
(!vm->def->disks[i]->driverType ||
9166
STRNEQ(vm->def->disks[i]->driverType, "qcow2"))) {
9167
qemuReportError(VIR_ERR_OPERATION_INVALID,
9168
_("Disk '%s' does not support snapshotting"),
9169
vm->def->disks[i]->src);
9177
/* The domain is expected to be locked and inactive. */
9179
qemuDomainSnapshotCreateInactive(struct qemud_driver *driver,
9181
virDomainSnapshotObjPtr snap)
9183
return qemuDomainSnapshotForEachQcow2(driver, vm, snap, "-c", false);
9186
/* The domain is expected to be locked and active. */
9188
qemuDomainSnapshotCreateActive(virConnectPtr conn,
9189
struct qemud_driver *driver,
9190
virDomainObjPtr *vmptr,
9191
virDomainSnapshotObjPtr snap,
9194
virDomainObjPtr vm = *vmptr;
9195
qemuDomainObjPrivatePtr priv = vm->privateData;
9196
bool resume = false;
9199
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
9202
if (!virDomainObjIsActive(vm)) {
9203
qemuReportError(VIR_ERR_OPERATION_INVALID,
9204
"%s", _("domain is not running"));
9208
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
9209
/* savevm monitor command pauses the domain emitting an event which
9210
* confuses libvirt since it's not notified when qemu resumes the
9211
* domain. Thus we stop and start CPUs ourselves.
9213
if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_SAVE,
9214
QEMU_ASYNC_JOB_NONE) < 0)
9218
if (!virDomainObjIsActive(vm)) {
9219
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
9220
_("guest unexpectedly quit"));
9225
qemuDomainObjEnterMonitorWithDriver(driver, vm);
9226
ret = qemuMonitorCreateSnapshot(priv->mon, snap->def->name);
9227
qemuDomainObjExitMonitorWithDriver(driver, vm);
9231
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT) {
9232
virDomainEventPtr event;
9234
event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED,
9235
VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT);
9236
qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT);
9237
virDomainAuditStop(vm, "from-snapshot");
9238
/* We already filtered the _HALT flag for persistent domains
9239
* only, so this end job never drops the last reference. */
9240
ignore_value(qemuDomainObjEndJob(driver, vm));
9244
qemuDomainEventQueue(driver, event);
9248
if (resume && virDomainObjIsActive(vm) &&
9249
qemuProcessStartCPUs(driver, vm, conn,
9250
VIR_DOMAIN_RUNNING_UNPAUSED,
9251
QEMU_ASYNC_JOB_NONE) < 0 &&
9252
virGetLastError() == NULL) {
9253
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
9254
_("resuming after snapshot failed"));
9258
if (vm && qemuDomainObjEndJob(driver, vm) == 0) {
9259
/* Only possible if a transient vm quit while our locks were down,
9260
* in which case we don't want to save snapshot metadata. */
9269
qemuDomainSnapshotDiskPrepare(virDomainObjPtr vm, virDomainSnapshotDefPtr def)
9274
bool active = virDomainObjIsActive(vm);
9277
for (i = 0; i < def->ndisks; i++) {
9278
virDomainSnapshotDiskDefPtr disk = &def->disks[i];
9280
switch (disk->snapshot) {
9281
case VIR_DOMAIN_DISK_SNAPSHOT_INTERNAL:
9283
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
9284
_("active qemu domains require external disk "
9285
"snapshots; disk %s requested internal"),
9289
if (!vm->def->disks[i]->driverType ||
9290
STRNEQ(vm->def->disks[i]->driverType, "qcow2")) {
9291
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
9292
_("internal snapshot for disk %s unsupported "
9293
"for storage type %s"),
9295
NULLSTR(vm->def->disks[i]->driverType));
9301
case VIR_DOMAIN_DISK_SNAPSHOT_EXTERNAL:
9302
if (!disk->driverType) {
9303
if (!(disk->driverType = strdup("qcow2"))) {
9304
virReportOOMError();
9307
} else if (STRNEQ(disk->driverType, "qcow2")) {
9308
/* XXX We should also support QED */
9309
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
9310
_("external snapshot format for disk %s "
9311
"is unsupported: %s"),
9312
disk->name, disk->driverType);
9315
if (stat(disk->file, &st) < 0) {
9316
if (errno != ENOENT) {
9317
virReportSystemError(errno,
9318
_("unable to stat for disk %s: %s"),
9319
disk->name, disk->file);
9322
} else if (!S_ISBLK(st.st_mode)) {
9323
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
9324
_("external snapshot file for disk %s already "
9325
"exists and is not a block device: %s"),
9326
disk->name, disk->file);
9332
case VIR_DOMAIN_DISK_SNAPSHOT_NO:
9335
case VIR_DOMAIN_DISK_SNAPSHOT_DEFAULT:
9337
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
9338
_("unexpected code path"));
9344
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
9345
_("disk snapshots require at least one disk to be "
9346
"selected for snapshot"));
9356
/* The domain is expected to hold monitor lock. */
9358
qemuDomainSnapshotCreateSingleDiskActive(struct qemud_driver *driver,
9360
virDomainSnapshotDiskDefPtr snap,
9361
virDomainDiskDefPtr disk,
9362
virDomainDiskDefPtr persistDisk)
9364
qemuDomainObjPrivatePtr priv = vm->privateData;
9365
char *device = NULL;
9366
char *source = NULL;
9367
char *driverType = NULL;
9368
char *persistSource = NULL;
9369
char *persistDriverType = NULL;
9372
char *origsrc = NULL;
9373
char *origdriver = NULL;
9374
bool need_unlink = false;
9376
if (snap->snapshot != VIR_DOMAIN_DISK_SNAPSHOT_EXTERNAL) {
9377
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
9378
_("unexpected code path"));
9382
if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0 ||
9383
!(source = strdup(snap->file)) ||
9384
(STRNEQ_NULLABLE(disk->driverType, "qcow2") &&
9385
!(driverType = strdup("qcow2"))) ||
9387
(!(persistSource = strdup(source)) ||
9388
(STRNEQ_NULLABLE(persistDisk->driverType, "qcow2") &&
9389
!(persistDriverType = strdup("qcow2")))))) {
9390
virReportOOMError();
9394
/* create the stub file and set selinux labels; manipulate disk in
9395
* place, in a way that can be reverted on failure. */
9396
fd = qemuOpenFile(driver, source, O_WRONLY | O_TRUNC | O_CREAT,
9397
&need_unlink, NULL);
9400
VIR_FORCE_CLOSE(fd);
9402
origsrc = disk->src;
9404
origdriver = disk->driverType;
9405
disk->driverType = (char *) "raw"; /* Don't want to probe backing files */
9407
if (virDomainLockDiskAttach(driver->lockManager, vm, disk) < 0)
9409
if (virSecurityManagerSetImageLabel(driver->securityManager, vm,
9411
if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
9412
VIR_WARN("Unable to release lock on %s", source);
9416
disk->src = origsrc;
9418
disk->driverType = origdriver;
9421
/* create the actual snapshot */
9422
ret = qemuMonitorDiskSnapshot(priv->mon, device, source);
9423
virDomainAuditDisk(vm, disk->src, source, "snapshot", ret >= 0);
9427
/* Update vm in place to match changes. */
9428
need_unlink = false;
9429
VIR_FREE(disk->src);
9433
VIR_FREE(disk->driverType);
9434
disk->driverType = driverType;
9438
VIR_FREE(persistDisk->src);
9439
persistDisk->src = persistSource;
9440
persistSource = NULL;
9441
if (persistDriverType) {
9442
VIR_FREE(persistDisk->driverType);
9443
persistDisk->driverType = persistDriverType;
9444
persistDriverType = NULL;
9450
disk->src = origsrc;
9451
disk->driverType = origdriver;
9453
if (need_unlink && unlink(source))
9454
VIR_WARN("unable to unlink just-created %s", source);
9457
VIR_FREE(driverType);
9458
VIR_FREE(persistSource);
9459
VIR_FREE(persistDriverType);
9463
/* The domain is expected to be locked and active. */
9465
qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
9466
struct qemud_driver *driver,
9467
virDomainObjPtr *vmptr,
9468
virDomainSnapshotObjPtr snap,
9471
virDomainObjPtr vm = *vmptr;
9472
bool resume = false;
9475
bool persist = false;
9477
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
9480
if (!virDomainObjIsActive(vm)) {
9481
qemuReportError(VIR_ERR_OPERATION_INVALID,
9482
"%s", _("domain is not running"));
9487
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
9488
/* In qemu, snapshot_blkdev on a single disk will pause cpus,
9489
* but this confuses libvirt since notifications are not given
9490
* when qemu resumes. And for multiple disks, libvirt must
9491
* pause externally to get all snapshots to be at the same
9492
* point in time. For simplicitly, we always pause ourselves
9493
* rather than relying on qemu doing pause.
9495
if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_SAVE,
9496
QEMU_ASYNC_JOB_NONE) < 0)
9500
if (!virDomainObjIsActive(vm)) {
9501
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
9502
_("guest unexpectedly quit"));
9507
/* No way to roll back if first disk succeeds but later disks
9508
* fail. Based on earlier qemuDomainSnapshotDiskPrepare, all
9509
* disks in this list are now either SNAPSHOT_NO, or
9510
* SNAPSHOT_EXTERNAL with a valid file name and qcow2 format. */
9511
qemuDomainObjEnterMonitorWithDriver(driver, vm);
9512
for (i = 0; i < snap->def->ndisks; i++) {
9513
virDomainDiskDefPtr persistDisk = NULL;
9515
if (snap->def->disks[i].snapshot == VIR_DOMAIN_DISK_SNAPSHOT_NO)
9518
int indx = virDomainDiskIndexByName(vm->newDef,
9519
vm->def->disks[i]->dst,
9522
persistDisk = vm->newDef->disks[indx];
9527
ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm,
9528
&snap->def->disks[i],
9534
qemuDomainObjExitMonitorWithDriver(driver, vm);
9538
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT) {
9539
virDomainEventPtr event;
9541
event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED,
9542
VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT);
9543
qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT);
9544
virDomainAuditStop(vm, "from-snapshot");
9545
/* We already filtered the _HALT flag for persistent domains
9546
* only, so this end job never drops the last reference. */
9547
ignore_value(qemuDomainObjEndJob(driver, vm));
9551
qemuDomainEventQueue(driver, event);
9555
if (resume && virDomainObjIsActive(vm) &&
9556
qemuProcessStartCPUs(driver, vm, conn,
9557
VIR_DOMAIN_RUNNING_UNPAUSED,
9558
QEMU_ASYNC_JOB_NONE) < 0 &&
9559
virGetLastError() == NULL) {
9560
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
9561
_("resuming after snapshot failed"));
9565
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0 ||
9567
virDomainSaveConfig(driver->configDir, vm->newDef) < 0))
9572
if (vm && (qemuDomainObjEndJob(driver, vm) == 0)) {
9573
/* Only possible if a transient vm quit while our locks were down,
9574
* in which case we don't want to save snapshot metadata. */
9582
static virDomainSnapshotPtr
9583
qemuDomainSnapshotCreateXML(virDomainPtr domain,
9584
const char *xmlDesc,
9587
struct qemud_driver *driver = domain->conn->privateData;
9588
virDomainObjPtr vm = NULL;
9590
virDomainSnapshotObjPtr snap = NULL;
9591
virDomainSnapshotPtr snapshot = NULL;
9592
char uuidstr[VIR_UUID_STRING_BUFLEN];
9593
virDomainSnapshotDefPtr def = NULL;
9594
bool update_current = true;
9595
unsigned int parse_flags = 0;
9596
virDomainSnapshotObjPtr other = NULL;
9598
virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
9599
VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT |
9600
VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA |
9601
VIR_DOMAIN_SNAPSHOT_CREATE_HALT |
9602
VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY, NULL);
9604
if (((flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) &&
9605
!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT)) ||
9606
(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA))
9607
update_current = false;
9608
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE)
9609
parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE;
9610
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY)
9611
parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_DISKS;
9613
qemuDriverLock(driver);
9614
virUUIDFormat(domain->uuid, uuidstr);
9615
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
9617
qemuReportError(VIR_ERR_NO_DOMAIN,
9618
_("no domain with matching uuid '%s'"), uuidstr);
9622
if (qemuProcessAutoDestroyActive(driver, vm)) {
9623
qemuReportError(VIR_ERR_OPERATION_INVALID,
9624
"%s", _("domain is marked for auto destroy"));
9627
if (!vm->persistent && (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT)) {
9628
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
9629
_("cannot halt after transient domain snapshot"));
9633
if (!(def = virDomainSnapshotDefParseString(xmlDesc, driver->caps,
9634
QEMU_EXPECTED_VIRT_TYPES,
9638
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) {
9639
/* Prevent circular chains */
9641
if (STREQ(def->name, def->parent)) {
9642
qemuReportError(VIR_ERR_INVALID_ARG,
9643
_("cannot set snapshot %s as its own parent"),
9647
other = virDomainSnapshotFindByName(&vm->snapshots, def->parent);
9649
qemuReportError(VIR_ERR_INVALID_ARG,
9650
_("parent %s for snapshot %s not found"),
9651
def->parent, def->name);
9654
while (other->def->parent) {
9655
if (STREQ(other->def->parent, def->name)) {
9656
qemuReportError(VIR_ERR_INVALID_ARG,
9657
_("parent %s would create cycle to %s"),
9658
other->def->name, def->name);
9661
other = virDomainSnapshotFindByName(&vm->snapshots,
9662
other->def->parent);
9664
VIR_WARN("snapshots are inconsistent for %s",
9671
/* Check that any replacement is compatible */
9673
memcmp(def->dom->uuid, domain->uuid, VIR_UUID_BUFLEN)) {
9674
qemuReportError(VIR_ERR_INVALID_ARG,
9675
_("definition for snapshot %s must use uuid %s"),
9676
def->name, uuidstr);
9679
other = virDomainSnapshotFindByName(&vm->snapshots, def->name);
9681
if ((other->def->state == VIR_DOMAIN_RUNNING ||
9682
other->def->state == VIR_DOMAIN_PAUSED) !=
9683
(def->state == VIR_DOMAIN_RUNNING ||
9684
def->state == VIR_DOMAIN_PAUSED)) {
9685
qemuReportError(VIR_ERR_INVALID_ARG,
9686
_("cannot change between online and offline "
9687
"snapshot state in snapshot %s"),
9691
if ((other->def->state == VIR_DOMAIN_DISK_SNAPSHOT) !=
9692
(def->state == VIR_DOMAIN_DISK_SNAPSHOT)) {
9693
qemuReportError(VIR_ERR_INVALID_ARG,
9694
_("cannot change between disk snapshot and "
9695
"system checkpoint in snapshot %s"),
9699
if (other->def->dom) {
9701
if (!virDomainDefCheckABIStability(other->def->dom,
9705
/* Transfer the domain def */
9706
def->dom = other->def->dom;
9707
other->def->dom = NULL;
9710
if (other == vm->current_snapshot) {
9711
update_current = true;
9712
vm->current_snapshot = NULL;
9714
/* Drop and rebuild the parent relationship, but keep all
9715
* child relations by reusing snap. */
9716
virDomainSnapshotDropParent(&vm->snapshots, other);
9717
virDomainSnapshotDefFree(other->def);
9721
if (def->state == VIR_DOMAIN_DISK_SNAPSHOT && def->dom) {
9722
if (virDomainSnapshotAlignDisks(def,
9723
VIR_DOMAIN_DISK_SNAPSHOT_EXTERNAL,
9728
/* Easiest way to clone inactive portion of vm->def is via
9729
* conversion in and back out of xml. */
9730
if (!(xml = virDomainDefFormat(vm->def, (VIR_DOMAIN_XML_INACTIVE |
9731
VIR_DOMAIN_XML_SECURE))) ||
9732
!(def->dom = virDomainDefParseString(driver->caps, xml,
9733
QEMU_EXPECTED_VIRT_TYPES,
9734
VIR_DOMAIN_XML_INACTIVE)))
9737
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) {
9738
if (virDomainSnapshotAlignDisks(def,
9739
VIR_DOMAIN_DISK_SNAPSHOT_EXTERNAL,
9742
if (qemuDomainSnapshotDiskPrepare(vm, def) < 0)
9744
def->state = VIR_DOMAIN_DISK_SNAPSHOT;
9746
/* In a perfect world, we would allow qemu to tell us this.
9747
* The problem is that qemu only does this check
9748
* device-by-device; so if you had a domain that booted from a
9749
* large qcow2 device, but had a secondary raw device
9750
* attached, you wouldn't find out that you can't snapshot
9751
* your guest until *after* it had spent the time to snapshot
9752
* the boot device. This is probably a bug in qemu, but we'll
9753
* work around it here for now.
9755
if (!qemuDomainSnapshotIsAllowed(vm))
9757
def->state = virDomainObjGetState(vm, NULL);
9763
else if (!(snap = virDomainSnapshotAssignDef(&vm->snapshots, def)))
9768
snap->def->current = true;
9769
if (vm->current_snapshot) {
9770
if (!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE)) {
9771
snap->def->parent = strdup(vm->current_snapshot->def->name);
9772
if (snap->def->parent == NULL) {
9773
virReportOOMError();
9777
if (update_current) {
9778
vm->current_snapshot->def->current = false;
9779
if (qemuDomainSnapshotWriteMetadata(vm, vm->current_snapshot,
9780
driver->snapshotDir) < 0)
9782
vm->current_snapshot = NULL;
9786
/* actually do the snapshot */
9787
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) {
9788
/* XXX Should we validate that the redefined snapshot even
9789
* makes sense, such as checking that qemu-img recognizes the
9790
* snapshot name in at least one of the domain's disks? */
9791
} else if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) {
9792
if (!virDomainObjIsActive(vm)) {
9793
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
9794
_("disk snapshots of inactive domains not "
9795
"implemented yet"));
9798
if (qemuDomainSnapshotCreateDiskActive(domain->conn, driver,
9799
&vm, snap, flags) < 0)
9801
} else if (!virDomainObjIsActive(vm)) {
9802
if (qemuDomainSnapshotCreateInactive(driver, vm, snap) < 0)
9805
if (qemuDomainSnapshotCreateActive(domain->conn, driver,
9806
&vm, snap, flags) < 0)
9810
/* If we fail after this point, there's not a whole lot we can
9811
* do; we've successfully taken the snapshot, and we are now running
9812
* on it, so we have to go forward the best we can
9814
snapshot = virGetDomainSnapshot(domain, snap->def->name);
9818
if (snapshot && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
9819
if (qemuDomainSnapshotWriteMetadata(vm, snap,
9820
driver->snapshotDir) < 0) {
9821
VIR_WARN("unable to save metadata for snapshot %s",
9825
vm->current_snapshot = snap;
9826
if (snap->def->parent) {
9827
other = virDomainSnapshotFindByName(&vm->snapshots,
9829
snap->parent = other;
9831
snap->sibling = other->first_child;
9832
other->first_child = snap;
9834
vm->snapshots.nroots++;
9835
snap->sibling = vm->snapshots.first_root;
9836
vm->snapshots.first_root = snap;
9840
virDomainSnapshotObjListRemove(&vm->snapshots, snap);
9842
virDomainObjUnlock(vm);
9844
virDomainSnapshotDefFree(def);
9846
qemuDriverUnlock(driver);
9850
static int qemuDomainSnapshotListNames(virDomainPtr domain, char **names,
9854
struct qemud_driver *driver = domain->conn->privateData;
9855
virDomainObjPtr vm = NULL;
9858
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
9859
VIR_DOMAIN_SNAPSHOT_LIST_METADATA |
9860
VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
9862
qemuDriverLock(driver);
9863
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
9865
char uuidstr[VIR_UUID_STRING_BUFLEN];
9866
virUUIDFormat(domain->uuid, uuidstr);
9867
qemuReportError(VIR_ERR_NO_DOMAIN,
9868
_("no domain with matching uuid '%s'"), uuidstr);
9872
n = virDomainSnapshotObjListGetNames(&vm->snapshots, names, nameslen,
9877
virDomainObjUnlock(vm);
9878
qemuDriverUnlock(driver);
9882
static int qemuDomainSnapshotNum(virDomainPtr domain,
9885
struct qemud_driver *driver = domain->conn->privateData;
9886
virDomainObjPtr vm = NULL;
9889
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
9890
VIR_DOMAIN_SNAPSHOT_LIST_METADATA |
9891
VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
9893
qemuDriverLock(driver);
9894
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
9896
char uuidstr[VIR_UUID_STRING_BUFLEN];
9897
virUUIDFormat(domain->uuid, uuidstr);
9898
qemuReportError(VIR_ERR_NO_DOMAIN,
9899
_("no domain with matching uuid '%s'"), uuidstr);
9903
/* All qemu snapshots have libvirt metadata, so
9904
* VIR_DOMAIN_SNAPSHOT_LIST_METADATA makes no difference to our
9907
n = virDomainSnapshotObjListNum(&vm->snapshots, flags);
9911
virDomainObjUnlock(vm);
9912
qemuDriverUnlock(driver);
9917
qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
9922
struct qemud_driver *driver = snapshot->domain->conn->privateData;
9923
virDomainObjPtr vm = NULL;
9924
virDomainSnapshotObjPtr snap = NULL;
9927
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
9928
VIR_DOMAIN_SNAPSHOT_LIST_METADATA |
9929
VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
9931
qemuDriverLock(driver);
9932
vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
9934
char uuidstr[VIR_UUID_STRING_BUFLEN];
9935
virUUIDFormat(snapshot->domain->uuid, uuidstr);
9936
qemuReportError(VIR_ERR_NO_DOMAIN,
9937
_("no domain with matching uuid '%s'"), uuidstr);
9941
snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
9943
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
9944
_("no domain snapshot with matching name '%s'"),
9949
n = virDomainSnapshotObjListGetNamesFrom(snap, names, nameslen, flags);
9953
virDomainObjUnlock(vm);
9954
qemuDriverUnlock(driver);
9959
qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot,
9962
struct qemud_driver *driver = snapshot->domain->conn->privateData;
9963
virDomainObjPtr vm = NULL;
9964
virDomainSnapshotObjPtr snap = NULL;
9967
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
9968
VIR_DOMAIN_SNAPSHOT_LIST_METADATA |
9969
VIR_DOMAIN_SNAPSHOT_LIST_LEAVES, -1);
9971
qemuDriverLock(driver);
9972
vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
9974
char uuidstr[VIR_UUID_STRING_BUFLEN];
9975
virUUIDFormat(snapshot->domain->uuid, uuidstr);
9976
qemuReportError(VIR_ERR_NO_DOMAIN,
9977
_("no domain with matching uuid '%s'"), uuidstr);
9981
snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
9983
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
9984
_("no domain snapshot with matching name '%s'"),
9989
/* All qemu snapshots have libvirt metadata, so
9990
* VIR_DOMAIN_SNAPSHOT_LIST_METADATA makes no difference to our
9993
n = virDomainSnapshotObjListNumFrom(snap, flags);
9997
virDomainObjUnlock(vm);
9998
qemuDriverUnlock(driver);
10002
static virDomainSnapshotPtr qemuDomainSnapshotLookupByName(virDomainPtr domain,
10004
unsigned int flags)
10006
struct qemud_driver *driver = domain->conn->privateData;
10007
virDomainObjPtr vm;
10008
virDomainSnapshotObjPtr snap = NULL;
10009
virDomainSnapshotPtr snapshot = NULL;
10011
virCheckFlags(0, NULL);
10013
qemuDriverLock(driver);
10014
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
10016
char uuidstr[VIR_UUID_STRING_BUFLEN];
10017
virUUIDFormat(domain->uuid, uuidstr);
10018
qemuReportError(VIR_ERR_NO_DOMAIN,
10019
_("no domain with matching uuid '%s'"), uuidstr);
10023
snap = virDomainSnapshotFindByName(&vm->snapshots, name);
10025
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
10026
_("no snapshot with matching name '%s'"), name);
10030
snapshot = virGetDomainSnapshot(domain, snap->def->name);
10034
virDomainObjUnlock(vm);
10035
qemuDriverUnlock(driver);
10039
static int qemuDomainHasCurrentSnapshot(virDomainPtr domain,
10040
unsigned int flags)
10042
struct qemud_driver *driver = domain->conn->privateData;
10043
virDomainObjPtr vm;
10046
virCheckFlags(0, -1);
10048
qemuDriverLock(driver);
10049
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
10051
char uuidstr[VIR_UUID_STRING_BUFLEN];
10052
virUUIDFormat(domain->uuid, uuidstr);
10053
qemuReportError(VIR_ERR_NO_DOMAIN,
10054
_("no domain with matching uuid '%s'"), uuidstr);
10058
ret = (vm->current_snapshot != NULL);
10062
virDomainObjUnlock(vm);
10063
qemuDriverUnlock(driver);
10067
static virDomainSnapshotPtr
10068
qemuDomainSnapshotGetParent(virDomainSnapshotPtr snapshot,
10069
unsigned int flags)
10071
struct qemud_driver *driver = snapshot->domain->conn->privateData;
10072
virDomainObjPtr vm;
10073
virDomainSnapshotObjPtr snap = NULL;
10074
virDomainSnapshotPtr parent = NULL;
10076
virCheckFlags(0, NULL);
10078
qemuDriverLock(driver);
10079
vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
10081
char uuidstr[VIR_UUID_STRING_BUFLEN];
10082
virUUIDFormat(snapshot->domain->uuid, uuidstr);
10083
qemuReportError(VIR_ERR_NO_DOMAIN,
10084
_("no domain with matching uuid '%s'"), uuidstr);
10088
snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
10090
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
10091
_("no domain snapshot with matching name '%s'"),
10096
if (!snap->def->parent) {
10097
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
10098
_("snapshot '%s' does not have a parent"),
10103
parent = virGetDomainSnapshot(snapshot->domain, snap->def->parent);
10107
virDomainObjUnlock(vm);
10108
qemuDriverUnlock(driver);
10112
static virDomainSnapshotPtr qemuDomainSnapshotCurrent(virDomainPtr domain,
10113
unsigned int flags)
10115
struct qemud_driver *driver = domain->conn->privateData;
10116
virDomainObjPtr vm;
10117
virDomainSnapshotPtr snapshot = NULL;
10119
virCheckFlags(0, NULL);
10121
qemuDriverLock(driver);
10122
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
10124
char uuidstr[VIR_UUID_STRING_BUFLEN];
10125
virUUIDFormat(domain->uuid, uuidstr);
10126
qemuReportError(VIR_ERR_NO_DOMAIN,
10127
_("no domain with matching uuid '%s'"), uuidstr);
10131
if (!vm->current_snapshot) {
10132
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s",
10133
_("the domain does not have a current snapshot"));
10137
snapshot = virGetDomainSnapshot(domain, vm->current_snapshot->def->name);
10141
virDomainObjUnlock(vm);
10142
qemuDriverUnlock(driver);
10146
static char *qemuDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
10147
unsigned int flags)
10149
struct qemud_driver *driver = snapshot->domain->conn->privateData;
10150
virDomainObjPtr vm = NULL;
10152
virDomainSnapshotObjPtr snap = NULL;
10153
char uuidstr[VIR_UUID_STRING_BUFLEN];
10155
virCheckFlags(VIR_DOMAIN_XML_SECURE, NULL);
10157
qemuDriverLock(driver);
10158
virUUIDFormat(snapshot->domain->uuid, uuidstr);
10159
vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
10161
qemuReportError(VIR_ERR_NO_DOMAIN,
10162
_("no domain with matching uuid '%s'"), uuidstr);
10166
snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
10168
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
10169
_("no domain snapshot with matching name '%s'"),
10174
xml = virDomainSnapshotDefFormat(uuidstr, snap->def, flags, 0);
10178
virDomainObjUnlock(vm);
10179
qemuDriverUnlock(driver);
10183
/* The domain is expected to be locked and inactive. */
10185
qemuDomainSnapshotRevertInactive(struct qemud_driver *driver,
10186
virDomainObjPtr vm,
10187
virDomainSnapshotObjPtr snap)
10189
/* Try all disks, but report failure if we skipped any. */
10190
int ret = qemuDomainSnapshotForEachQcow2(driver, vm, snap, "-a", true);
10191
return ret > 0 ? -1 : ret;
10194
static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
10195
unsigned int flags)
10197
struct qemud_driver *driver = snapshot->domain->conn->privateData;
10198
virDomainObjPtr vm = NULL;
10200
virDomainSnapshotObjPtr snap = NULL;
10201
char uuidstr[VIR_UUID_STRING_BUFLEN];
10202
virDomainEventPtr event = NULL;
10203
virDomainEventPtr event2 = NULL;
10205
qemuDomainObjPrivatePtr priv;
10207
virDomainDefPtr config = NULL;
10209
virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
10210
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED |
10211
VIR_DOMAIN_SNAPSHOT_REVERT_FORCE, -1);
10213
/* We have the following transitions, which create the following events:
10214
* 1. inactive -> inactive: none
10215
* 2. inactive -> running: EVENT_STARTED
10216
* 3. inactive -> paused: EVENT_STARTED, EVENT_PAUSED
10217
* 4. running -> inactive: EVENT_STOPPED
10218
* 5. running -> running: none
10219
* 6. running -> paused: EVENT_PAUSED
10220
* 7. paused -> inactive: EVENT_STOPPED
10221
* 8. paused -> running: EVENT_RESUMED
10222
* 9. paused -> paused: none
10223
* Also, several transitions occur even if we fail partway through,
10224
* and use of FORCE can cause multiple transitions.
10227
qemuDriverLock(driver);
10228
virUUIDFormat(snapshot->domain->uuid, uuidstr);
10229
vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
10231
qemuReportError(VIR_ERR_NO_DOMAIN,
10232
_("no domain with matching uuid '%s'"), uuidstr);
10236
snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
10238
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
10239
_("no domain snapshot with matching name '%s'"),
10244
if (!vm->persistent &&
10245
snap->def->state != VIR_DOMAIN_RUNNING &&
10246
snap->def->state != VIR_DOMAIN_PAUSED &&
10247
(flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
10248
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) == 0) {
10249
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
10250
_("transient domain needs to request run or pause "
10251
"to revert to inactive snapshot"));
10254
if (snap->def->state == VIR_DOMAIN_DISK_SNAPSHOT) {
10255
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
10256
_("revert to external disk snapshot not supported "
10260
if (!(flags & VIR_DOMAIN_SNAPSHOT_REVERT_FORCE)) {
10261
if (!snap->def->dom) {
10262
qemuReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY,
10263
_("snapshot '%s' lacks domain '%s' rollback info"),
10264
snap->def->name, vm->def->name);
10267
if (virDomainObjIsActive(vm) &&
10268
!(snap->def->state == VIR_DOMAIN_RUNNING
10269
|| snap->def->state == VIR_DOMAIN_PAUSED) &&
10270
(flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
10271
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED))) {
10272
qemuReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY,
10273
_("must respawn qemu to start inactive snapshot"));
10279
if (vm->current_snapshot) {
10280
vm->current_snapshot->def->current = false;
10281
if (qemuDomainSnapshotWriteMetadata(vm, vm->current_snapshot,
10282
driver->snapshotDir) < 0)
10284
vm->current_snapshot = NULL;
10285
/* XXX Should we restore vm->current_snapshot after this point
10286
* in the failure cases where we know there was no change? */
10289
/* Prepare to copy the snapshot inactive xml as the config of this
10290
* domain. Easiest way is by a round trip through xml.
10292
* XXX Should domain snapshots track live xml rather
10293
* than inactive xml? */
10294
snap->def->current = true;
10295
if (snap->def->dom) {
10297
if (!(xml = virDomainDefFormat(snap->def->dom,
10298
(VIR_DOMAIN_XML_INACTIVE |
10299
VIR_DOMAIN_XML_SECURE))))
10301
config = virDomainDefParseString(driver->caps, xml,
10302
QEMU_EXPECTED_VIRT_TYPES,
10303
VIR_DOMAIN_XML_INACTIVE);
10309
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
10312
if (snap->def->state == VIR_DOMAIN_RUNNING
10313
|| snap->def->state == VIR_DOMAIN_PAUSED) {
10314
/* Transitions 2, 3, 5, 6, 8, 9 */
10315
bool was_running = false;
10316
bool was_stopped = false;
10318
/* When using the loadvm monitor command, qemu does not know
10319
* whether to pause or run the reverted domain, and just stays
10320
* in the same state as before the monitor command, whether
10321
* that is paused or running. We always pause before loadvm,
10322
* to have finer control. */
10323
if (virDomainObjIsActive(vm)) {
10324
/* Transitions 5, 6, 8, 9 */
10325
/* Check for ABI compatibility. */
10326
if (config && !virDomainDefCheckABIStability(vm->def, config)) {
10327
virErrorPtr err = virGetLastError();
10329
if (!(flags & VIR_DOMAIN_SNAPSHOT_REVERT_FORCE)) {
10330
/* Re-spawn error using correct category. */
10331
if (err->code == VIR_ERR_CONFIG_UNSUPPORTED)
10332
qemuReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY, "%s",
10336
virResetError(err);
10337
qemuProcessStop(driver, vm, 0,
10338
VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT);
10339
virDomainAuditStop(vm, "from-snapshot");
10340
detail = VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT;
10341
event = virDomainEventNewFromObj(vm,
10342
VIR_DOMAIN_EVENT_STOPPED,
10345
qemuDomainEventQueue(driver, event);
10349
priv = vm->privateData;
10350
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
10351
/* Transitions 5, 6 */
10352
was_running = true;
10353
if (qemuProcessStopCPUs(driver, vm,
10354
VIR_DOMAIN_PAUSED_FROM_SNAPSHOT,
10355
QEMU_ASYNC_JOB_NONE) < 0)
10357
/* Create an event now in case the restore fails, so
10358
* that user will be alerted that they are now paused.
10359
* If restore later succeeds, we might replace this. */
10360
detail = VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT;
10361
event = virDomainEventNewFromObj(vm,
10362
VIR_DOMAIN_EVENT_SUSPENDED,
10364
if (!virDomainObjIsActive(vm)) {
10365
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
10366
_("guest unexpectedly quit"));
10370
qemuDomainObjEnterMonitorWithDriver(driver, vm);
10371
rc = qemuMonitorLoadSnapshot(priv->mon, snap->def->name);
10372
qemuDomainObjExitMonitorWithDriver(driver, vm);
10374
/* XXX resume domain if it was running before the
10375
* failed loadvm attempt? */
10379
virDomainObjAssignDef(vm, config, false);
10381
/* Transitions 2, 3 */
10383
was_stopped = true;
10385
virDomainObjAssignDef(vm, config, false);
10387
rc = qemuProcessStart(snapshot->domain->conn, driver, vm, NULL,
10388
true, false, -1, NULL, snap,
10389
VIR_NETDEV_VPORT_PROFILE_OP_CREATE);
10390
virDomainAuditStart(vm, "from-snapshot", rc >= 0);
10391
detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;
10392
event = virDomainEventNewFromObj(vm,
10393
VIR_DOMAIN_EVENT_STARTED,
10399
/* Touch up domain state. */
10400
if (!(flags & VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING) &&
10401
(snap->def->state == VIR_DOMAIN_PAUSED ||
10402
(flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED))) {
10403
/* Transitions 3, 6, 9 */
10404
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
10405
VIR_DOMAIN_PAUSED_FROM_SNAPSHOT);
10407
/* Transition 3, use event as-is and add event2 */
10408
detail = VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT;
10409
event2 = virDomainEventNewFromObj(vm,
10410
VIR_DOMAIN_EVENT_SUSPENDED,
10412
} /* else transition 6 and 9 use event as-is */
10414
/* Transitions 2, 5, 8 */
10415
if (!virDomainObjIsActive(vm)) {
10416
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
10417
_("guest unexpectedly quit"));
10420
rc = qemuProcessStartCPUs(driver, vm, snapshot->domain->conn,
10421
VIR_DOMAIN_RUNNING_FROM_SNAPSHOT,
10422
QEMU_ASYNC_JOB_NONE);
10425
virDomainEventFree(event);
10429
detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;
10430
event = virDomainEventNewFromObj(vm,
10431
VIR_DOMAIN_EVENT_STARTED,
10433
} else if (was_running) {
10435
detail = VIR_DOMAIN_EVENT_RESUMED;
10436
event = virDomainEventNewFromObj(vm,
10437
VIR_DOMAIN_EVENT_RESUMED,
10442
/* Transitions 1, 4, 7 */
10443
/* Newer qemu -loadvm refuses to revert to the state of a snapshot
10444
* created by qemu-img snapshot -c. If the domain is running, we
10445
* must take it offline; then do the revert using qemu-img.
10448
if (virDomainObjIsActive(vm)) {
10449
/* Transitions 4, 7 */
10450
qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT);
10451
virDomainAuditStop(vm, "from-snapshot");
10452
detail = VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT;
10453
event = virDomainEventNewFromObj(vm,
10454
VIR_DOMAIN_EVENT_STOPPED,
10458
if (qemuDomainSnapshotRevertInactive(driver, vm, snap) < 0) {
10459
if (!vm->persistent) {
10460
if (qemuDomainObjEndJob(driver, vm) > 0)
10461
qemuDomainRemoveInactive(driver, vm);
10468
virDomainObjAssignDef(vm, config, false);
10470
if (flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
10471
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
10472
/* Flush first event, now do transition 2 or 3 */
10473
bool paused = (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED) != 0;
10476
qemuDomainEventQueue(driver, event);
10477
rc = qemuProcessStart(snapshot->domain->conn, driver, vm, NULL,
10478
paused, false, -1, NULL, NULL,
10479
VIR_NETDEV_VPORT_PROFILE_OP_CREATE);
10480
virDomainAuditStart(vm, "from-snapshot", rc >= 0);
10482
if (!vm->persistent) {
10483
if (qemuDomainObjEndJob(driver, vm) > 0)
10484
qemuDomainRemoveInactive(driver, vm);
10490
detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;
10491
event = virDomainEventNewFromObj(vm,
10492
VIR_DOMAIN_EVENT_STARTED,
10495
detail = VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT;
10496
event2 = virDomainEventNewFromObj(vm,
10497
VIR_DOMAIN_EVENT_SUSPENDED,
10506
if (vm && qemuDomainObjEndJob(driver, vm) == 0)
10510
if (vm && ret == 0) {
10511
if (qemuDomainSnapshotWriteMetadata(vm, snap,
10512
driver->snapshotDir) < 0)
10515
vm->current_snapshot = snap;
10517
snap->def->current = false;
10520
qemuDomainEventQueue(driver, event);
10522
qemuDomainEventQueue(driver, event2);
10525
virDomainObjUnlock(vm);
10526
qemuDriverUnlock(driver);
10531
struct snap_reparent {
10532
struct qemud_driver *driver;
10533
virDomainSnapshotObjPtr parent;
10534
virDomainObjPtr vm;
10536
virDomainSnapshotObjPtr last;
10540
qemuDomainSnapshotReparentChildren(void *payload,
10541
const void *name ATTRIBUTE_UNUSED,
10544
virDomainSnapshotObjPtr snap = payload;
10545
struct snap_reparent *rep = data;
10547
if (rep->err < 0) {
10551
VIR_FREE(snap->def->parent);
10552
snap->parent = rep->parent;
10555
snap->def->parent = strdup(rep->parent->def->name);
10557
if (snap->def->parent == NULL) {
10558
virReportOOMError();
10564
if (!snap->sibling)
10567
rep->err = qemuDomainSnapshotWriteMetadata(rep->vm, snap,
10568
rep->driver->snapshotDir);
10571
static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
10572
unsigned int flags)
10574
struct qemud_driver *driver = snapshot->domain->conn->privateData;
10575
virDomainObjPtr vm = NULL;
10577
virDomainSnapshotObjPtr snap = NULL;
10578
char uuidstr[VIR_UUID_STRING_BUFLEN];
10579
struct qemu_snap_remove rem;
10580
struct snap_reparent rep;
10581
bool metadata_only = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY);
10584
virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
10585
VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY |
10586
VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY, -1);
10588
qemuDriverLock(driver);
10589
virUUIDFormat(snapshot->domain->uuid, uuidstr);
10590
vm = virDomainFindByUUID(&driver->domains, snapshot->domain->uuid);
10592
qemuReportError(VIR_ERR_NO_DOMAIN,
10593
_("no domain with matching uuid '%s'"), uuidstr);
10597
snap = virDomainSnapshotFindByName(&vm->snapshots, snapshot->name);
10599
qemuReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
10600
_("no domain snapshot with matching name '%s'"),
10605
if (!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY)) {
10606
if (!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) &&
10607
snap->def->state == VIR_DOMAIN_DISK_SNAPSHOT)
10609
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN)
10610
virDomainSnapshotForEachDescendant(snap,
10611
qemuDomainSnapshotCountExternal,
10614
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
10615
_("deletion of %d external disk snapshots not "
10616
"supported yet"), external);
10621
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
10624
if (flags & (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
10625
VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) {
10626
rem.driver = driver;
10628
rem.metadata_only = metadata_only;
10630
rem.current = false;
10631
virDomainSnapshotForEachDescendant(snap,
10632
qemuDomainSnapshotDiscardAll,
10637
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
10638
snap->def->current = true;
10639
if (qemuDomainSnapshotWriteMetadata(vm, snap,
10640
driver->snapshotDir) < 0) {
10641
qemuReportError(VIR_ERR_INTERNAL_ERROR,
10642
_("failed to set snapshot '%s' as current"),
10644
snap->def->current = false;
10648
vm->current_snapshot = snap;
10650
} else if (snap->nchildren) {
10651
rep.driver = driver;
10652
rep.parent = snap->parent;
10656
virDomainSnapshotForEachChild(snap,
10657
qemuDomainSnapshotReparentChildren,
10661
/* Can't modify siblings during ForEachChild, so do it now. */
10662
if (snap->parent) {
10663
snap->parent->nchildren += snap->nchildren;
10664
rep.last->sibling = snap->parent->first_child;
10665
snap->parent->first_child = snap->first_child;
10667
vm->snapshots.nroots += snap->nchildren;
10668
rep.last->sibling = vm->snapshots.first_root;
10669
vm->snapshots.first_root = snap->first_child;
10673
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
10674
snap->nchildren = 0;
10675
snap->first_child = NULL;
10678
virDomainSnapshotDropParent(&vm->snapshots, snap);
10679
ret = qemuDomainSnapshotDiscard(driver, vm, snap, true, metadata_only);
10683
if (qemuDomainObjEndJob(driver, vm) == 0)
10688
virDomainObjUnlock(vm);
10689
qemuDriverUnlock(driver);
10693
static int qemuDomainMonitorCommand(virDomainPtr domain, const char *cmd,
10694
char **result, unsigned int flags)
10696
struct qemud_driver *driver = domain->conn->privateData;
10697
virDomainObjPtr vm = NULL;
10699
qemuDomainObjPrivatePtr priv;
10702
virCheckFlags(VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP, -1);
10704
qemuDriverLock(driver);
10705
vm = virDomainFindByUUID(&driver->domains, domain->uuid);
10707
char uuidstr[VIR_UUID_STRING_BUFLEN];
10708
virUUIDFormat(domain->uuid, uuidstr);
10709
qemuReportError(VIR_ERR_NO_DOMAIN,
10710
_("no domain with matching uuid '%s'"), uuidstr);
10714
if (!virDomainObjIsActive(vm)) {
10715
qemuReportError(VIR_ERR_OPERATION_INVALID,
10716
"%s", _("domain is not running"));
10720
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
10723
if (!virDomainObjIsActive(vm)) {
10724
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
10725
_("domain is not running"));
10729
priv = vm->privateData;
10731
qemuDomainObjTaint(driver, vm, VIR_DOMAIN_TAINT_CUSTOM_MONITOR, -1);
10733
hmp = !!(flags & VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP);
10735
qemuDomainObjEnterMonitorWithDriver(driver, vm);
10736
ret = qemuMonitorArbitraryCommand(priv->mon, cmd, result, hmp);
10737
qemuDomainObjExitMonitorWithDriver(driver, vm);
10740
if (qemuDomainObjEndJob(driver, vm) == 0) {
10746
virDomainObjUnlock(vm);
10747
qemuDriverUnlock(driver);
10752
static virDomainPtr qemuDomainAttach(virConnectPtr conn,
10754
unsigned int flags)
10756
struct qemud_driver *driver = conn->privateData;
10757
virDomainObjPtr vm = NULL;
10758
virDomainDefPtr def = NULL;
10759
virDomainPtr dom = NULL;
10760
virDomainChrSourceDefPtr monConfig = NULL;
10761
bool monJSON = false;
10762
char *pidfile = NULL;
10764
virCheckFlags(0, NULL);
10766
qemuDriverLock(driver);
10768
if (!(def = qemuParseCommandLinePid(driver->caps, pid,
10769
&pidfile, &monConfig, &monJSON)))
10773
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
10774
_("No monitor connection for pid %u"),
10778
if (monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) {
10779
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
10780
_("Cannot connect to monitor connection of type '%s' for pid %u"),
10781
virDomainChrTypeToString(monConfig->type), pid);
10785
if (!(def->name) &&
10786
virAsprintf(&def->name, "attach-pid-%u", pid) < 0) {
10787
virReportOOMError();
10791
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
10794
if (qemudCanonicalizeMachine(driver, def) < 0)
10797
if (qemuDomainAssignPCIAddresses(def) < 0)
10800
if (!(vm = virDomainAssignDef(driver->caps,
10807
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
10810
if (qemuProcessAttach(conn, driver, vm, pid,
10811
pidfile, monConfig, monJSON) < 0) {
10818
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
10819
if (dom) dom->id = vm->def->id;
10822
if (qemuDomainObjEndJob(driver, vm) == 0) {
10828
virDomainDefFree(def);
10829
virDomainChrSourceDefFree(monConfig);
10831
virDomainObjUnlock(vm);
10832
qemuDriverUnlock(driver);
10839
qemuDomainOpenConsole(virDomainPtr dom,
10840
const char *dev_name,
10842
unsigned int flags)
10844
struct qemud_driver *driver = dom->conn->privateData;
10845
virDomainObjPtr vm = NULL;
10846
char uuidstr[VIR_UUID_STRING_BUFLEN];
10849
virDomainChrDefPtr chr = NULL;
10851
virCheckFlags(0, -1);
10853
qemuDriverLock(driver);
10854
virUUIDFormat(dom->uuid, uuidstr);
10855
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
10857
qemuReportError(VIR_ERR_NO_DOMAIN,
10858
_("no domain with matching uuid '%s'"), uuidstr);
10862
if (!virDomainObjIsActive(vm)) {
10863
qemuReportError(VIR_ERR_OPERATION_INVALID,
10864
"%s", _("domain is not running"));
10869
for (i = 0 ; !chr && i < vm->def->nconsoles ; i++) {
10870
if (vm->def->consoles[i]->info.alias &&
10871
STREQ(dev_name, vm->def->consoles[i]->info.alias))
10872
chr = vm->def->consoles[i];
10874
for (i = 0 ; !chr && i < vm->def->nserials ; i++) {
10875
if (STREQ(dev_name, vm->def->serials[i]->info.alias))
10876
chr = vm->def->serials[i];
10878
for (i = 0 ; !chr && i < vm->def->nparallels ; i++) {
10879
if (STREQ(dev_name, vm->def->parallels[i]->info.alias))
10880
chr = vm->def->parallels[i];
10883
if (vm->def->nconsoles)
10884
chr = vm->def->consoles[0];
10885
else if (vm->def->nserials)
10886
chr = vm->def->serials[0];
10890
qemuReportError(VIR_ERR_INTERNAL_ERROR,
10891
_("cannot find character device %s"),
10892
NULLSTR(dev_name));
10896
if (chr->source.type != VIR_DOMAIN_CHR_TYPE_PTY) {
10897
qemuReportError(VIR_ERR_INTERNAL_ERROR,
10898
_("character device %s is not using a PTY"),
10899
NULLSTR(dev_name));
10903
if (virFDStreamOpenFile(st, chr->source.data.file.path,
10910
virDomainObjUnlock(vm);
10911
qemuDriverUnlock(driver);
10916
qemuDiskPathToAlias(virDomainObjPtr vm, const char *path)
10920
virDomainDiskDefPtr disk;
10922
i = virDomainDiskIndexByName(vm->def, path, true);
10926
disk = vm->def->disks[i];
10928
if (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK &&
10929
disk->type != VIR_DOMAIN_DISK_TYPE_FILE)
10933
if (virAsprintf(&ret, "drive-%s", disk->info.alias) < 0) {
10934
virReportOOMError();
10941
qemuReportError(VIR_ERR_INVALID_ARG,
10942
"%s", _("No device found for specified path"));
10948
qemuDomainBlockJobImpl(virDomainPtr dom, const char *path,
10949
unsigned long bandwidth, virDomainBlockJobInfoPtr info,
10952
struct qemud_driver *driver = dom->conn->privateData;
10953
virDomainObjPtr vm = NULL;
10954
qemuDomainObjPrivatePtr priv;
10955
char uuidstr[VIR_UUID_STRING_BUFLEN];
10956
char *device = NULL;
10959
qemuDriverLock(driver);
10960
virUUIDFormat(dom->uuid, uuidstr);
10961
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
10963
qemuReportError(VIR_ERR_NO_DOMAIN,
10964
_("no domain with matching uuid '%s'"), uuidstr);
10968
if (!virDomainObjIsActive(vm)) {
10969
qemuReportError(VIR_ERR_OPERATION_INVALID,
10970
"%s", _("domain is not running"));
10974
device = qemuDiskPathToAlias(vm, path);
10979
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
10982
if (!virDomainObjIsActive(vm)) {
10983
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
10984
_("domain is not running"));
10988
qemuDomainObjEnterMonitorWithDriver(driver, vm);
10989
priv = vm->privateData;
10990
ret = qemuMonitorBlockJob(priv->mon, device, bandwidth, info, mode);
10991
qemuDomainObjExitMonitorWithDriver(driver, vm);
10994
if (qemuDomainObjEndJob(driver, vm) == 0) {
11002
virDomainObjUnlock(vm);
11003
qemuDriverUnlock(driver);
11008
qemuDomainBlockJobAbort(virDomainPtr dom, const char *path, unsigned int flags)
11010
virCheckFlags(0, -1);
11011
return qemuDomainBlockJobImpl(dom, path, 0, NULL, BLOCK_JOB_ABORT);
11015
qemuDomainGetBlockJobInfo(virDomainPtr dom, const char *path,
11016
virDomainBlockJobInfoPtr info, unsigned int flags)
11018
virCheckFlags(0, -1);
11019
return qemuDomainBlockJobImpl(dom, path, 0, info, BLOCK_JOB_INFO);
11023
qemuDomainBlockJobSetSpeed(virDomainPtr dom, const char *path,
11024
unsigned long bandwidth, unsigned int flags)
11026
virCheckFlags(0, -1);
11027
return qemuDomainBlockJobImpl(dom, path, bandwidth, NULL, BLOCK_JOB_SPEED);
11031
qemuDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth,
11032
unsigned int flags)
11036
virCheckFlags(0, -1);
11037
ret = qemuDomainBlockJobImpl(dom, path, bandwidth, NULL, BLOCK_JOB_PULL);
11038
if (ret == 0 && bandwidth != 0)
11039
ret = qemuDomainBlockJobImpl(dom, path, bandwidth, NULL,
11045
qemuDomainOpenGraphics(virDomainPtr dom,
11048
unsigned int flags)
11050
struct qemud_driver *driver = dom->conn->privateData;
11051
virDomainObjPtr vm = NULL;
11052
char uuidstr[VIR_UUID_STRING_BUFLEN];
11054
qemuDomainObjPrivatePtr priv;
11055
const char *protocol;
11057
virCheckFlags(VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH, -1);
11059
qemuDriverLock(driver);
11060
virUUIDFormat(dom->uuid, uuidstr);
11061
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
11063
qemuReportError(VIR_ERR_NO_DOMAIN,
11064
_("no domain with matching uuid '%s'"), uuidstr);
11068
if (!virDomainObjIsActive(vm)) {
11069
qemuReportError(VIR_ERR_OPERATION_INVALID,
11070
"%s", _("domain is not running"));
11074
priv = vm->privateData;
11076
if (idx >= vm->def->ngraphics) {
11077
qemuReportError(VIR_ERR_INTERNAL_ERROR,
11078
_("No graphics backend with index %d"), idx);
11081
switch (vm->def->graphics[idx]->type) {
11082
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
11085
case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
11086
protocol = "spice";
11089
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
11090
_("Can only open VNC or SPICE graphics backends, not %s"),
11091
virDomainGraphicsTypeToString(vm->def->graphics[idx]->type));
11095
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
11097
qemuDomainObjEnterMonitorWithDriver(driver, vm);
11098
ret = qemuMonitorOpenGraphics(priv->mon, protocol, fd, "graphicsfd",
11099
(flags & VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH) != 0);
11100
qemuDomainObjExitMonitorWithDriver(driver, vm);
11101
if (qemuDomainObjEndJob(driver, vm) == 0) {
11108
virDomainObjUnlock(vm);
11109
qemuDriverUnlock(driver);
11114
qemuDomainSetBlockIoTune(virDomainPtr dom,
11116
virTypedParameterPtr params,
11118
unsigned int flags)
11120
struct qemud_driver *driver = dom->conn->privateData;
11121
virDomainObjPtr vm = NULL;
11122
qemuDomainObjPrivatePtr priv;
11123
virDomainDefPtr persistentDef = NULL;
11124
virDomainBlockIoTuneInfo info;
11125
char uuidstr[VIR_UUID_STRING_BUFLEN];
11126
const char *device = NULL;
11132
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
11133
VIR_DOMAIN_AFFECT_CONFIG, -1);
11135
memset(&info, 0, sizeof(info));
11137
qemuDriverLock(driver);
11138
virUUIDFormat(dom->uuid, uuidstr);
11139
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
11141
qemuReportError(VIR_ERR_NO_DOMAIN,
11142
_("no domain with matching uuid '%s'"), uuidstr);
11146
device = qemuDiskPathToAlias(vm, disk);
11151
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
11154
isActive = virDomainObjIsActive(vm);
11156
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
11158
flags = VIR_DOMAIN_AFFECT_LIVE;
11160
flags = VIR_DOMAIN_AFFECT_CONFIG;
11163
if (!isActive && (flags & VIR_DOMAIN_AFFECT_LIVE)) {
11164
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
11165
_("domain is not running"));
11169
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
11170
if (!vm->persistent) {
11171
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
11172
_("cannot change persistent config of a transient domain"));
11175
if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
11177
idx = virDomainDiskIndexByName(persistentDef, disk, true);
11182
for (i = 0; i < nparams; i++) {
11183
virTypedParameterPtr param = ¶ms[i];
11185
if (param->type != VIR_TYPED_PARAM_ULLONG) {
11186
qemuReportError(VIR_ERR_INVALID_ARG,
11187
_("expected unsigned long long for parameter %s"),
11192
if (STREQ(param->field, VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC)) {
11193
info.total_bytes_sec = param->value.ul;
11194
} else if (STREQ(param->field,
11195
VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC)) {
11196
info.read_bytes_sec = param->value.ul;
11197
} else if (STREQ(param->field,
11198
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC)) {
11199
info.write_bytes_sec = param->value.ul;
11200
} else if (STREQ(param->field,
11201
VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC)) {
11202
info.total_iops_sec = param->value.ul;
11203
} else if (STREQ(param->field,
11204
VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC)) {
11205
info.read_iops_sec = param->value.ul;
11206
} else if (STREQ(param->field,
11207
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC)) {
11208
info.write_iops_sec = param->value.ul;
11210
qemuReportError(VIR_ERR_INVALID_ARG,
11211
_("Unrecognized parameter %s"),
11217
if ((info.total_bytes_sec && info.read_bytes_sec) ||
11218
(info.total_bytes_sec && info.write_bytes_sec)) {
11219
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
11220
_("total and read/write of bytes_sec cannot be set at the same time"));
11224
if ((info.total_iops_sec && info.read_iops_sec) ||
11225
(info.total_iops_sec && info.write_iops_sec)) {
11226
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
11227
_("total and read/write of iops_sec cannot be set at the same time"));
11231
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
11232
priv = vm->privateData;
11233
qemuDomainObjEnterMonitorWithDriver(driver, vm);
11234
ret = qemuMonitorSetBlockIoThrottle(priv->mon, device, &info);
11235
qemuDomainObjExitMonitorWithDriver(driver, vm);
11240
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
11241
sa_assert(persistentDef && idx >= 0);
11242
persistentDef->disks[idx]->blkdeviotune = info;
11243
ret = virDomainSaveConfig(driver->configDir, persistentDef);
11245
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
11246
_("Write to config file failed"));
11252
if (qemuDomainObjEndJob(driver, vm) == 0)
11258
virDomainObjUnlock(vm);
11259
qemuDriverUnlock(driver);
11264
qemuDomainGetBlockIoTune(virDomainPtr dom,
11266
virTypedParameterPtr params,
11268
unsigned int flags)
11270
struct qemud_driver *driver = dom->conn->privateData;
11271
virDomainObjPtr vm = NULL;
11272
qemuDomainObjPrivatePtr priv;
11273
virDomainDefPtr persistentDef = NULL;
11274
virDomainBlockIoTuneInfo reply;
11275
char uuidstr[VIR_UUID_STRING_BUFLEN];
11276
const char *device = NULL;
11281
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
11282
VIR_DOMAIN_AFFECT_CONFIG |
11283
VIR_TYPED_PARAM_STRING_OKAY, -1);
11285
/* We don't return strings, and thus trivially support this flag. */
11286
flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
11288
qemuDriverLock(driver);
11289
virUUIDFormat(dom->uuid, uuidstr);
11290
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
11292
qemuReportError(VIR_ERR_NO_DOMAIN,
11293
_("no domain with matching uuid '%s'"), uuidstr);
11297
if ((*nparams) == 0) {
11298
/* Current number of parameters supported by QEMU Block I/O Throttling */
11299
*nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM;
11304
device = qemuDiskPathToAlias(vm, disk);
11310
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
11313
isActive = virDomainObjIsActive(vm);
11315
if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
11317
flags = VIR_DOMAIN_AFFECT_LIVE;
11319
flags = VIR_DOMAIN_AFFECT_CONFIG;
11322
if (!isActive && (flags & VIR_DOMAIN_AFFECT_LIVE)) {
11323
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
11324
_("domain is not running"));
11328
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
11329
priv = vm->privateData;
11330
qemuDomainObjEnterMonitorWithDriver(driver, vm);
11331
ret = qemuMonitorGetBlockIoThrottle(priv->mon, device, &reply);
11332
qemuDomainObjExitMonitorWithDriver(driver, vm);
11337
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
11338
if (!vm->persistent) {
11339
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
11340
_("domain is transient"));
11343
if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
11346
int idx = virDomainDiskIndexByName(vm->def, disk, true);
11349
reply = persistentDef->disks[idx]->blkdeviotune;
11352
for (i = 0; i < QEMU_NB_BLOCK_IO_TUNE_PARAM && i < *nparams; i++) {
11353
virTypedParameterPtr param = ¶ms[i];
11354
param->value.ul = 0;
11355
param->type = VIR_TYPED_PARAM_ULLONG;
11359
if (virStrcpyStatic(param->field,
11360
VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC) == NULL) {
11361
qemuReportError(VIR_ERR_INTERNAL_ERROR,
11362
_("Field name '%s' too long"),
11363
VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC);
11366
param->value.ul = reply.total_bytes_sec;
11370
if (virStrcpyStatic(param->field,
11371
VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC) == NULL) {
11372
qemuReportError(VIR_ERR_INTERNAL_ERROR,
11373
_("Field name '%s' too long"),
11374
VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC);
11377
param->value.ul = reply.read_bytes_sec;
11381
if (virStrcpyStatic(param->field,
11382
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC) == NULL) {
11383
qemuReportError(VIR_ERR_INTERNAL_ERROR,
11384
_("Field name '%s' too long"),
11385
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC);
11388
param->value.ul = reply.write_bytes_sec;
11392
if (virStrcpyStatic(param->field,
11393
VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC) == NULL) {
11394
qemuReportError(VIR_ERR_INTERNAL_ERROR,
11395
_("Field name '%s' too long"),
11396
VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC);
11399
param->value.ul = reply.total_iops_sec;
11403
if (virStrcpyStatic(param->field,
11404
VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC) == NULL) {
11405
qemuReportError(VIR_ERR_INTERNAL_ERROR,
11406
_("Field name '%s' too long"),
11407
VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC);
11410
param->value.ul = reply.read_iops_sec;
11414
if (virStrcpyStatic(param->field,
11415
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC) == NULL) {
11416
qemuReportError(VIR_ERR_INTERNAL_ERROR,
11417
_("Field name '%s' too long"),
11418
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC);
11421
param->value.ul = reply.write_iops_sec;
11428
if (*nparams > QEMU_NB_BLOCK_IO_TUNE_PARAM)
11429
*nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM;
11433
if (qemuDomainObjEndJob(driver, vm) == 0)
11439
virDomainObjUnlock(vm);
11440
qemuDriverUnlock(driver);
11444
static virDriver qemuDriver = {
11445
.no = VIR_DRV_QEMU,
11447
.open = qemudOpen, /* 0.2.0 */
11448
.close = qemudClose, /* 0.2.0 */
11449
.supports_feature = qemudSupportsFeature, /* 0.5.0 */
11450
.type = qemudGetType, /* 0.2.0 */
11451
.version = qemudGetVersion, /* 0.2.0 */
11452
.getHostname = virGetHostname, /* 0.3.3 */
11453
.getSysinfo = qemuGetSysinfo, /* 0.8.8 */
11454
.getMaxVcpus = qemudGetMaxVCPUs, /* 0.2.1 */
11455
.nodeGetInfo = nodeGetInfo, /* 0.2.0 */
11456
.getCapabilities = qemudGetCapabilities, /* 0.2.1 */
11457
.listDomains = qemudListDomains, /* 0.2.0 */
11458
.numOfDomains = qemudNumDomains, /* 0.2.0 */
11459
.domainCreateXML = qemudDomainCreate, /* 0.2.0 */
11460
.domainLookupByID = qemudDomainLookupByID, /* 0.2.0 */
11461
.domainLookupByUUID = qemudDomainLookupByUUID, /* 0.2.0 */
11462
.domainLookupByName = qemudDomainLookupByName, /* 0.2.0 */
11463
.domainSuspend = qemudDomainSuspend, /* 0.2.0 */
11464
.domainResume = qemudDomainResume, /* 0.2.0 */
11465
.domainShutdown = qemuDomainShutdown, /* 0.2.0 */
11466
.domainReboot = qemuDomainReboot, /* 0.9.3 */
11467
.domainReset = qemuDomainReset, /* 0.9.7 */
11468
.domainDestroy = qemuDomainDestroy, /* 0.2.0 */
11469
.domainDestroyFlags = qemuDomainDestroyFlags, /* 0.9.4 */
11470
.domainGetOSType = qemudDomainGetOSType, /* 0.2.2 */
11471
.domainGetMaxMemory = qemudDomainGetMaxMemory, /* 0.4.2 */
11472
.domainSetMaxMemory = qemudDomainSetMaxMemory, /* 0.4.2 */
11473
.domainSetMemory = qemudDomainSetMemory, /* 0.4.2 */
11474
.domainSetMemoryFlags = qemudDomainSetMemoryFlags, /* 0.9.0 */
11475
.domainSetMemoryParameters = qemuDomainSetMemoryParameters, /* 0.8.5 */
11476
.domainGetMemoryParameters = qemuDomainGetMemoryParameters, /* 0.8.5 */
11477
.domainSetBlkioParameters = qemuDomainSetBlkioParameters, /* 0.9.0 */
11478
.domainGetBlkioParameters = qemuDomainGetBlkioParameters, /* 0.9.0 */
11479
.domainGetInfo = qemudDomainGetInfo, /* 0.2.0 */
11480
.domainGetState = qemuDomainGetState, /* 0.9.2 */
11481
.domainGetControlInfo = qemuDomainGetControlInfo, /* 0.9.3 */
11482
.domainSave = qemuDomainSave, /* 0.2.0 */
11483
.domainSaveFlags = qemuDomainSaveFlags, /* 0.9.4 */
11484
.domainRestore = qemuDomainRestore, /* 0.2.0 */
11485
.domainRestoreFlags = qemuDomainRestoreFlags, /* 0.9.4 */
11486
.domainSaveImageGetXMLDesc = qemuDomainSaveImageGetXMLDesc, /* 0.9.4 */
11487
.domainSaveImageDefineXML = qemuDomainSaveImageDefineXML, /* 0.9.4 */
11488
.domainCoreDump = qemudDomainCoreDump, /* 0.7.0 */
11489
.domainScreenshot = qemuDomainScreenshot, /* 0.9.2 */
11490
.domainSetVcpus = qemuDomainSetVcpus, /* 0.4.4 */
11491
.domainSetVcpusFlags = qemuDomainSetVcpusFlags, /* 0.8.5 */
11492
.domainGetVcpusFlags = qemudDomainGetVcpusFlags, /* 0.8.5 */
11493
.domainPinVcpu = qemudDomainPinVcpu, /* 0.4.4 */
11494
.domainPinVcpuFlags = qemudDomainPinVcpuFlags, /* 0.9.3 */
11495
.domainGetVcpuPinInfo = qemudDomainGetVcpuPinInfo, /* 0.9.3 */
11496
.domainGetVcpus = qemudDomainGetVcpus, /* 0.4.4 */
11497
.domainGetMaxVcpus = qemudDomainGetMaxVcpus, /* 0.4.4 */
11498
.domainGetSecurityLabel = qemudDomainGetSecurityLabel, /* 0.6.1 */
11499
.nodeGetSecurityModel = qemudNodeGetSecurityModel, /* 0.6.1 */
11500
.domainGetXMLDesc = qemuDomainGetXMLDesc, /* 0.2.0 */
11501
.domainXMLFromNative = qemuDomainXMLFromNative, /* 0.6.4 */
11502
.domainXMLToNative = qemuDomainXMLToNative, /* 0.6.4 */
11503
.listDefinedDomains = qemudListDefinedDomains, /* 0.2.0 */
11504
.numOfDefinedDomains = qemudNumDefinedDomains, /* 0.2.0 */
11505
.domainCreate = qemuDomainStart, /* 0.2.0 */
11506
.domainCreateWithFlags = qemuDomainStartWithFlags, /* 0.8.2 */
11507
.domainDefineXML = qemudDomainDefine, /* 0.2.0 */
11508
.domainUndefine = qemudDomainUndefine, /* 0.2.0 */
11509
.domainUndefineFlags = qemuDomainUndefineFlags, /* 0.9.4 */
11510
.domainAttachDevice = qemuDomainAttachDevice, /* 0.4.1 */
11511
.domainAttachDeviceFlags = qemuDomainAttachDeviceFlags, /* 0.7.7 */
11512
.domainDetachDevice = qemuDomainDetachDevice, /* 0.5.0 */
11513
.domainDetachDeviceFlags = qemuDomainDetachDeviceFlags, /* 0.7.7 */
11514
.domainUpdateDeviceFlags = qemuDomainUpdateDeviceFlags, /* 0.8.0 */
11515
.domainGetAutostart = qemudDomainGetAutostart, /* 0.2.1 */
11516
.domainSetAutostart = qemudDomainSetAutostart, /* 0.2.1 */
11517
.domainGetSchedulerType = qemuGetSchedulerType, /* 0.7.0 */
11518
.domainGetSchedulerParameters = qemuGetSchedulerParameters, /* 0.7.0 */
11519
.domainGetSchedulerParametersFlags = qemuGetSchedulerParametersFlags, /* 0.9.2 */
11520
.domainSetSchedulerParameters = qemuSetSchedulerParameters, /* 0.7.0 */
11521
.domainSetSchedulerParametersFlags = qemuSetSchedulerParametersFlags, /* 0.9.2 */
11522
.domainMigratePerform = qemudDomainMigratePerform, /* 0.5.0 */
11523
.domainBlockResize = qemuDomainBlockResize, /* 0.9.8 */
11524
.domainBlockStats = qemuDomainBlockStats, /* 0.4.1 */
11525
.domainBlockStatsFlags = qemuDomainBlockStatsFlags, /* 0.9.5 */
11526
.domainInterfaceStats = qemudDomainInterfaceStats, /* 0.4.1 */
11527
.domainMemoryStats = qemudDomainMemoryStats, /* 0.7.5 */
11528
.domainBlockPeek = qemudDomainBlockPeek, /* 0.4.4 */
11529
.domainMemoryPeek = qemudDomainMemoryPeek, /* 0.4.4 */
11530
.domainGetBlockInfo = qemuDomainGetBlockInfo, /* 0.8.1 */
11531
.nodeGetCPUStats = nodeGetCPUStats, /* 0.9.3 */
11532
.nodeGetMemoryStats = nodeGetMemoryStats, /* 0.9.3 */
11533
.nodeGetCellsFreeMemory = nodeGetCellsFreeMemory, /* 0.4.4 */
11534
.nodeGetFreeMemory = nodeGetFreeMemory, /* 0.4.4 */
11535
.domainEventRegister = qemuDomainEventRegister, /* 0.5.0 */
11536
.domainEventDeregister = qemuDomainEventDeregister, /* 0.5.0 */
11537
.domainMigratePrepare2 = qemudDomainMigratePrepare2, /* 0.5.0 */
11538
.domainMigrateFinish2 = qemudDomainMigrateFinish2, /* 0.5.0 */
11539
.nodeDeviceDettach = qemudNodeDeviceDettach, /* 0.6.1 */
11540
.nodeDeviceReAttach = qemudNodeDeviceReAttach, /* 0.6.1 */
11541
.nodeDeviceReset = qemudNodeDeviceReset, /* 0.6.1 */
11542
.domainMigratePrepareTunnel = qemudDomainMigratePrepareTunnel, /* 0.7.2 */
11543
.isEncrypted = qemuIsEncrypted, /* 0.7.3 */
11544
.isSecure = qemuIsSecure, /* 0.7.3 */
11545
.domainIsActive = qemuDomainIsActive, /* 0.7.3 */
11546
.domainIsPersistent = qemuDomainIsPersistent, /* 0.7.3 */
11547
.domainIsUpdated = qemuDomainIsUpdated, /* 0.8.6 */
11548
.cpuCompare = qemuCPUCompare, /* 0.7.5 */
11549
.cpuBaseline = qemuCPUBaseline, /* 0.7.7 */
11550
.domainGetJobInfo = qemuDomainGetJobInfo, /* 0.7.7 */
11551
.domainAbortJob = qemuDomainAbortJob, /* 0.7.7 */
11552
.domainMigrateSetMaxDowntime = qemuDomainMigrateSetMaxDowntime, /* 0.8.0 */
11553
.domainMigrateSetMaxSpeed = qemuDomainMigrateSetMaxSpeed, /* 0.9.0 */
11554
.domainMigrateGetMaxSpeed = qemuDomainMigrateGetMaxSpeed, /* 0.9.5 */
11555
.domainEventRegisterAny = qemuDomainEventRegisterAny, /* 0.8.0 */
11556
.domainEventDeregisterAny = qemuDomainEventDeregisterAny, /* 0.8.0 */
11557
.domainManagedSave = qemuDomainManagedSave, /* 0.8.0 */
11558
.domainHasManagedSaveImage = qemuDomainHasManagedSaveImage, /* 0.8.0 */
11559
.domainManagedSaveRemove = qemuDomainManagedSaveRemove, /* 0.8.0 */
11560
.domainSnapshotCreateXML = qemuDomainSnapshotCreateXML, /* 0.8.0 */
11561
.domainSnapshotGetXMLDesc = qemuDomainSnapshotGetXMLDesc, /* 0.8.0 */
11562
.domainSnapshotNum = qemuDomainSnapshotNum, /* 0.8.0 */
11563
.domainSnapshotListNames = qemuDomainSnapshotListNames, /* 0.8.0 */
11564
.domainSnapshotNumChildren = qemuDomainSnapshotNumChildren, /* 0.9.7 */
11565
.domainSnapshotListChildrenNames = qemuDomainSnapshotListChildrenNames, /* 0.9.7 */
11566
.domainSnapshotLookupByName = qemuDomainSnapshotLookupByName, /* 0.8.0 */
11567
.domainHasCurrentSnapshot = qemuDomainHasCurrentSnapshot, /* 0.8.0 */
11568
.domainSnapshotGetParent = qemuDomainSnapshotGetParent, /* 0.9.7 */
11569
.domainSnapshotCurrent = qemuDomainSnapshotCurrent, /* 0.8.0 */
11570
.domainRevertToSnapshot = qemuDomainRevertToSnapshot, /* 0.8.0 */
11571
.domainSnapshotDelete = qemuDomainSnapshotDelete, /* 0.8.0 */
11572
.qemuDomainMonitorCommand = qemuDomainMonitorCommand, /* 0.8.3 */
11573
.qemuDomainAttach = qemuDomainAttach, /* 0.9.4 */
11574
.domainOpenConsole = qemuDomainOpenConsole, /* 0.8.6 */
11575
.domainOpenGraphics = qemuDomainOpenGraphics, /* 0.9.7 */
11576
.domainInjectNMI = qemuDomainInjectNMI, /* 0.9.2 */
11577
.domainMigrateBegin3 = qemuDomainMigrateBegin3, /* 0.9.2 */
11578
.domainMigratePrepare3 = qemuDomainMigratePrepare3, /* 0.9.2 */
11579
.domainMigratePrepareTunnel3 = qemuDomainMigratePrepareTunnel3, /* 0.9.2 */
11580
.domainMigratePerform3 = qemuDomainMigratePerform3, /* 0.9.2 */
11581
.domainMigrateFinish3 = qemuDomainMigrateFinish3, /* 0.9.2 */
11582
.domainMigrateConfirm3 = qemuDomainMigrateConfirm3, /* 0.9.2 */
11583
.domainSendKey = qemuDomainSendKey, /* 0.9.4 */
11584
.domainBlockJobAbort = qemuDomainBlockJobAbort, /* 0.9.4 */
11585
.domainGetBlockJobInfo = qemuDomainGetBlockJobInfo, /* 0.9.4 */
11586
.domainBlockJobSetSpeed = qemuDomainBlockJobSetSpeed, /* 0.9.4 */
11587
.domainBlockPull = qemuDomainBlockPull, /* 0.9.4 */
11588
.isAlive = qemuIsAlive, /* 0.9.8 */
11589
.nodeSuspendForDuration = nodeSuspendForDuration, /* 0.9.8 */
11590
.domainSetBlockIoTune = qemuDomainSetBlockIoTune, /* 0.9.8 */
11591
.domainGetBlockIoTune = qemuDomainGetBlockIoTune, /* 0.9.8 */
11595
static virStateDriver qemuStateDriver = {
11597
.initialize = qemudStartup,
11598
.cleanup = qemudShutdown,
11599
.reload = qemudReload,
11600
.active = qemudActive,
11604
qemuVMDriverLock(void) {
11605
qemuDriverLock(qemu_driver);
11610
qemuVMDriverUnlock(void) {
11611
qemuDriverUnlock(qemu_driver);
11616
qemuVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED,
11617
virHashIterator iter, void *data)
11619
virHashForEach(qemu_driver->domains.objs, iter, data);
11624
static virNWFilterCallbackDriver qemuCallbackDriver = {
11626
.vmFilterRebuild = qemuVMFilterRebuild,
11627
.vmDriverLock = qemuVMDriverLock,
11628
.vmDriverUnlock = qemuVMDriverUnlock,
11631
int qemuRegister(void) {
11632
virRegisterDriver(&qemuDriver);
11633
virRegisterStateDriver(&qemuStateDriver);
11634
virNWFilterRegisterCallbackDriver(&qemuCallbackDriver);