2 * qemu_driver.c: core driver methods for managing qemu guests
4 * Copyright (C) 2006-2019 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, see
19 * <http://www.gnu.org/licenses/>.
24 #include <sys/types.h>
34 #include <sys/ioctl.h>
39 #include "qemu_driver.h"
40 #include "qemu_agent.h"
41 #include "qemu_alias.h"
42 #include "qemu_block.h"
43 #include "qemu_conf.h"
44 #include "qemu_capabilities.h"
45 #include "qemu_command.h"
46 #include "qemu_parse_command.h"
47 #include "qemu_cgroup.h"
48 #include "qemu_hostdev.h"
49 #include "qemu_hotplug.h"
50 #include "qemu_monitor.h"
51 #include "qemu_monitor_json.h"
52 #include "qemu_process.h"
53 #include "qemu_migration.h"
54 #include "qemu_migration_params.h"
55 #include "qemu_blockjob.h"
56 #include "qemu_security.h"
60 #include "datatypes.h"
61 #include "virbuffer.h"
62 #include "virhostcpu.h"
63 #include "virhostmem.h"
64 #include "virnetdevtap.h"
65 #include "virnetdevopenvswitch.h"
66 #include "capabilities.h"
68 #include "virarptable.h"
70 #include "domain_conf.h"
71 #include "domain_audit.h"
72 #include "node_device_conf.h"
75 #include "virprocess.h"
76 #include "libvirt_internal.h"
79 #include "virsysinfo.h"
80 #include "domain_nwfilter.h"
82 #include "virstoragefile.h"
84 #include "virfdstream.h"
85 #include "configmake.h"
86 #include "virthreadpool.h"
87 #include "locking/lock_manager.h"
88 #include "locking/domain_lock.h"
89 #include "virkeycode.h"
90 #include "virnodesuspend.h"
92 #include "virtypedparam.h"
93 #include "virbitmap.h"
94 #include "virstring.h"
95 #include "viraccessapicheck.h"
96 #include "viraccessapicheckqemu.h"
97 #include "virhostdev.h"
98 #include "domain_capabilities.h"
99 #include "vircgroup.h"
103 #include "netdev_bandwidth_conf.h"
105 #include "virdomainsnapshotobjlist.h"
106 #include "virdomaincheckpointobjlist.h"
107 #include "backup_conf.h"
109 #define VIR_FROM_THIS VIR_FROM_QEMU
111 VIR_LOG_INIT("qemu.qemu_driver");
113 #define QEMU_NB_MEM_PARAM 3
115 #define QEMU_NB_BLOCK_IO_TUNE_BASE_PARAMS 6
116 #define QEMU_NB_BLOCK_IO_TUNE_MAX_PARAMS 7
117 #define QEMU_NB_BLOCK_IO_TUNE_LENGTH_PARAMS 6
118 #define QEMU_NB_BLOCK_IO_TUNE_GROUP_PARAMS 1
119 #define QEMU_NB_BLOCK_IO_TUNE_ALL_PARAMS (QEMU_NB_BLOCK_IO_TUNE_BASE_PARAMS + \
120 QEMU_NB_BLOCK_IO_TUNE_MAX_PARAMS + \
121 QEMU_NB_BLOCK_IO_TUNE_GROUP_PARAMS + \
122 QEMU_NB_BLOCK_IO_TUNE_LENGTH_PARAMS)
124 #define QEMU_NB_NUMA_PARAM 2
126 #define QEMU_SCHED_MIN_PERIOD 1000LL
127 #define QEMU_SCHED_MAX_PERIOD 1000000LL
128 #define QEMU_SCHED_MIN_QUOTA 1000LL
129 #define QEMU_SCHED_MAX_QUOTA 18446744073709551LL
131 #define QEMU_GUEST_VCPU_MAX_ID 4096
133 #define QEMU_NB_BLKIO_PARAM 6
135 #define QEMU_NB_BANDWIDTH_PARAM 7
137 static void qemuProcessEventHandler(void *data
, void *opaque
);
139 static int qemuStateCleanup(void);
141 static int qemuDomainObjStart(virConnectPtr conn
,
142 virQEMUDriverPtr driver
,
145 qemuDomainAsyncJob asyncJob
);
147 static int qemuDomainManagedSaveLoad(virDomainObjPtr vm
,
150 static int qemuOpenFileAs(uid_t fallback_uid
, gid_t fallback_gid
,
151 bool dynamicOwnership
,
152 const char *path
, int oflags
,
155 static int qemuGetDHCPInterfaces(virDomainPtr dom
,
157 virDomainInterfacePtr
**ifaces
);
159 static int qemuARPGetInterfaces(virDomainObjPtr vm
,
160 virDomainInterfacePtr
**ifaces
);
162 static virQEMUDriverPtr qemu_driver
;
165 * qemuDomObjFromDomain:
166 * @domain: Domain pointer that has to be looked up
168 * This function looks up @domain and returns the appropriate virDomainObjPtr
169 * that has to be released by calling virDomainObjEndAPI().
171 * Returns the domain object with incremented reference counter which is locked
172 * on success, NULL otherwise.
174 static virDomainObjPtr
175 qemuDomObjFromDomain(virDomainPtr domain
)
178 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
179 char uuidstr
[VIR_UUID_STRING_BUFLEN
];
181 vm
= virDomainObjListFindByUUID(driver
->domains
, domain
->uuid
);
183 virUUIDFormat(domain
->uuid
, uuidstr
);
184 virReportError(VIR_ERR_NO_DOMAIN
,
185 _("no domain with matching uuid '%s' (%s)"),
186 uuidstr
, domain
->name
);
193 /* Looks up the domain object from snapshot and unlocks the
194 * driver. The returned domain object is locked and ref'd and the
195 * caller must call virDomainObjEndAPI() on it. */
196 static virDomainObjPtr
197 qemuDomObjFromSnapshot(virDomainSnapshotPtr snapshot
)
199 return qemuDomObjFromDomain(snapshot
->domain
);
203 /* Looks up snapshot object from VM and name */
204 static virDomainMomentObjPtr
205 qemuSnapObjFromName(virDomainObjPtr vm
,
208 virDomainMomentObjPtr snap
= NULL
;
209 snap
= virDomainSnapshotFindByName(vm
->snapshots
, name
);
211 virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT
,
212 _("no domain snapshot with matching name '%s'"),
219 /* Looks up snapshot object from VM and snapshotPtr */
220 static virDomainMomentObjPtr
221 qemuSnapObjFromSnapshot(virDomainObjPtr vm
,
222 virDomainSnapshotPtr snapshot
)
224 return qemuSnapObjFromName(vm
, snapshot
->name
);
227 /* Looks up the domain object from checkpoint and unlocks the
228 * driver. The returned domain object is locked and ref'd and the
229 * caller must call virDomainObjEndAPI() on it. */
230 static virDomainObjPtr
231 qemuDomObjFromCheckpoint(virDomainCheckpointPtr checkpoint
)
233 return qemuDomObjFromDomain(checkpoint
->domain
);
237 /* Looks up checkpoint object from VM and name */
238 static virDomainMomentObjPtr
239 qemuCheckObjFromName(virDomainObjPtr vm
,
242 virDomainMomentObjPtr chk
= NULL
;
243 chk
= virDomainCheckpointFindByName(vm
->checkpoints
, name
);
245 virReportError(VIR_ERR_NO_DOMAIN_CHECKPOINT
,
246 _("no domain checkpoint with matching name '%s'"),
253 /* Looks up checkpoint object from VM and checkpointPtr */
254 static virDomainMomentObjPtr
255 qemuCheckObjFromCheckpoint(virDomainObjPtr vm
,
256 virDomainCheckpointPtr checkpoint
)
258 return qemuCheckObjFromName(vm
, checkpoint
->name
);
262 qemuAutostartDomain(virDomainObjPtr vm
,
265 virQEMUDriverPtr driver
= opaque
;
267 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
270 if (cfg
->autoStartBypassCache
)
271 flags
|= VIR_DOMAIN_START_BYPASS_CACHE
;
277 !virDomainObjIsActive(vm
)) {
278 if (qemuProcessBeginJob(driver
, vm
,
279 VIR_DOMAIN_JOB_OPERATION_START
, flags
) < 0) {
280 virReportError(VIR_ERR_INTERNAL_ERROR
,
281 _("Failed to start job on VM '%s': %s"),
282 vm
->def
->name
, virGetLastErrorMessage());
286 if (qemuDomainObjStart(NULL
, driver
, vm
, flags
,
287 QEMU_ASYNC_JOB_START
) < 0) {
288 virReportError(VIR_ERR_INTERNAL_ERROR
,
289 _("Failed to autostart VM '%s': %s"),
290 vm
->def
->name
, virGetLastErrorMessage());
293 qemuProcessEndJob(driver
, vm
);
298 virDomainObjEndAPI(&vm
);
305 qemuAutostartDomains(virQEMUDriverPtr driver
)
307 virDomainObjListForEach(driver
->domains
, qemuAutostartDomain
, driver
);
312 qemuSecurityChownCallback(const virStorageSource
*src
,
320 VIR_AUTOUNREF(virStorageSourcePtr
) cpy
= NULL
;
322 rv
= virStorageFileSupportsSecurityDriver(src
);
326 if (virStorageSourceIsLocalStorage(src
)) {
327 /* use direct chown for local files so that the file doesn't
328 * need to be initialized */
332 if (stat(src
->path
, &sb
) >= 0) {
333 if (sb
.st_uid
== uid
&&
335 /* It's alright, there's nothing to change anyway. */
340 if (chown(src
->path
, uid
, gid
) < 0)
343 if (!(cpy
= virStorageSourceCopy(src
, false)))
346 /* src file init reports errors, return -2 on failure */
347 if (virStorageFileInit(cpy
) < 0) {
352 if (virStorageFileChown(cpy
, uid
, gid
) < 0)
360 virStorageFileDeinit(cpy
);
368 qemuSecurityInit(virQEMUDriverPtr driver
)
371 virSecurityManagerPtr mgr
= NULL
;
372 virSecurityManagerPtr stack
= NULL
;
373 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
374 unsigned int flags
= 0;
376 if (cfg
->securityDefaultConfined
)
377 flags
|= VIR_SECURITY_MANAGER_DEFAULT_CONFINED
;
378 if (cfg
->securityRequireConfined
)
379 flags
|= VIR_SECURITY_MANAGER_REQUIRE_CONFINED
;
380 if (virQEMUDriverIsPrivileged(driver
))
381 flags
|= VIR_SECURITY_MANAGER_PRIVILEGED
;
383 if (cfg
->securityDriverNames
&&
384 cfg
->securityDriverNames
[0]) {
385 names
= cfg
->securityDriverNames
;
386 while (names
&& *names
) {
387 if (!(mgr
= qemuSecurityNew(*names
,
392 if (!(stack
= qemuSecurityNewStack(mgr
)))
395 if (qemuSecurityStackAddNested(stack
, mgr
) < 0)
402 if (!(mgr
= qemuSecurityNew(NULL
,
406 if (!(stack
= qemuSecurityNewStack(mgr
)))
411 if (virQEMUDriverIsPrivileged(driver
)) {
412 if (cfg
->dynamicOwnership
)
413 flags
|= VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP
;
414 if (virBitmapIsBitSet(cfg
->namespaces
, QEMU_DOMAIN_NS_MOUNT
))
415 flags
|= VIR_SECURITY_MANAGER_MOUNT_NAMESPACE
;
416 if (!(mgr
= qemuSecurityNewDAC(QEMU_DRIVER_NAME
,
420 qemuSecurityChownCallback
)))
423 if (!(stack
= qemuSecurityNewStack(mgr
)))
426 if (qemuSecurityStackAddNested(stack
, mgr
) < 0)
432 driver
->securityManager
= stack
;
437 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
438 _("Failed to initialize security drivers"));
439 virObjectUnref(stack
);
447 qemuDomainSnapshotLoad(virDomainObjPtr vm
,
450 char *baseDir
= (char *)data
;
451 char *snapDir
= NULL
;
453 struct dirent
*entry
;
456 virDomainSnapshotDefPtr def
= NULL
;
457 virDomainMomentObjPtr snap
= NULL
;
458 virDomainMomentObjPtr current
= NULL
;
460 unsigned int flags
= (VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE
|
461 VIR_DOMAIN_SNAPSHOT_PARSE_DISKS
|
462 VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL
);
464 virCapsPtr caps
= NULL
;
468 if (virAsprintf(&snapDir
, "%s/%s", baseDir
, vm
->def
->name
) < 0) {
469 virReportError(VIR_ERR_INTERNAL_ERROR
,
470 _("Failed to allocate memory for "
471 "snapshot directory for domain %s"),
476 if (!(caps
= virQEMUDriverGetCapabilities(qemu_driver
, false)))
479 VIR_INFO("Scanning for snapshots for domain %s in %s", vm
->def
->name
,
482 if (virDirOpenIfExists(&dir
, snapDir
) <= 0)
485 while ((direrr
= virDirRead(dir
, &entry
, NULL
)) > 0) {
486 /* NB: ignoring errors, so one malformed config doesn't
487 kill the whole process */
488 VIR_INFO("Loading snapshot file '%s'", entry
->d_name
);
490 if (virAsprintf(&fullpath
, "%s/%s", snapDir
, entry
->d_name
) < 0) {
491 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
492 _("Failed to allocate memory for path"));
496 if (virFileReadAll(fullpath
, 1024*1024*1, &xmlStr
) < 0) {
497 /* Nothing we can do here, skip this one */
498 virReportSystemError(errno
,
499 _("Failed to read snapshot file %s"),
505 def
= virDomainSnapshotDefParseString(xmlStr
, caps
,
506 qemu_driver
->xmlopt
, &cur
,
509 /* Nothing we can do here, skip this one */
510 virReportError(VIR_ERR_INTERNAL_ERROR
,
511 _("Failed to parse snapshot XML from file '%s'"),
518 snap
= virDomainSnapshotAssignDef(vm
->snapshots
, def
);
520 virDomainSnapshotDefFree(def
);
523 virReportError(VIR_ERR_INTERNAL_ERROR
,
524 _("Too many snapshots claiming to be current for domain %s"),
533 virReportError(VIR_ERR_INTERNAL_ERROR
,
534 _("Failed to fully read directory %s"),
537 virDomainSnapshotSetCurrent(vm
->snapshots
, current
);
538 if (virDomainSnapshotUpdateRelations(vm
->snapshots
) < 0)
539 virReportError(VIR_ERR_INTERNAL_ERROR
,
540 _("Snapshots have inconsistent relations for domain %s"),
543 /* FIXME: qemu keeps internal track of snapshots. We can get access
544 * to this info via the "info snapshots" monitor command for running
545 * domains, or via "qemu-img snapshot -l" for shutoff domains. It would
546 * be nice to update our internal state based on that, but there is a
547 * a problem. qemu doesn't track all of the same metadata that we do.
548 * In particular we wouldn't be able to fill in the <parent>, which is
549 * pretty important in our metadata.
558 virObjectUnref(caps
);
565 qemuDomainCheckpointLoad(virDomainObjPtr vm
,
568 char *baseDir
= (char *)data
;
571 struct dirent
*entry
;
574 virDomainCheckpointDefPtr def
= NULL
;
575 virDomainMomentObjPtr chk
= NULL
;
576 virDomainMomentObjPtr current
= NULL
;
578 unsigned int flags
= (VIR_DOMAIN_CHECKPOINT_PARSE_REDEFINE
|
579 VIR_DOMAIN_CHECKPOINT_PARSE_INTERNAL
);
581 virCapsPtr caps
= NULL
;
585 if (virAsprintf(&chkDir
, "%s/%s", baseDir
, vm
->def
->name
) < 0) {
586 virReportError(VIR_ERR_INTERNAL_ERROR
,
587 _("Failed to allocate memory for "
588 "checkpoint directory for domain %s"),
593 if (!(caps
= virQEMUDriverGetCapabilities(qemu_driver
, false)))
596 VIR_INFO("Scanning for checkpoints for domain %s in %s", vm
->def
->name
,
599 if (virDirOpenIfExists(&dir
, chkDir
) <= 0)
602 while ((direrr
= virDirRead(dir
, &entry
, NULL
)) > 0) {
603 /* NB: ignoring errors, so one malformed config doesn't
604 kill the whole process */
605 VIR_INFO("Loading checkpoint file '%s'", entry
->d_name
);
607 if (virAsprintf(&fullpath
, "%s/%s", chkDir
, entry
->d_name
) < 0) {
608 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
609 _("Failed to allocate memory for path"));
613 if (virFileReadAll(fullpath
, 1024*1024*1, &xmlStr
) < 0) {
614 /* Nothing we can do here, skip this one */
615 virReportSystemError(errno
,
616 _("Failed to read checkpoint file %s"),
622 def
= virDomainCheckpointDefParseString(xmlStr
, caps
,
623 qemu_driver
->xmlopt
, &cur
,
625 if (!def
|| virDomainCheckpointAlignDisks(def
) < 0) {
626 /* Nothing we can do here, skip this one */
627 virReportError(VIR_ERR_INTERNAL_ERROR
,
628 _("Failed to parse checkpoint XML from file '%s'"),
635 chk
= virDomainCheckpointAssignDef(vm
->checkpoints
, def
);
637 virDomainCheckpointDefFree(def
);
640 virReportError(VIR_ERR_INTERNAL_ERROR
,
641 _("Too many snapshots claiming to be current for domain %s"),
650 virReportError(VIR_ERR_INTERNAL_ERROR
,
651 _("Failed to fully read directory %s"),
654 virDomainCheckpointSetCurrent(vm
->checkpoints
, current
);
656 if (virDomainCheckpointUpdateRelations(vm
->checkpoints
) < 0)
657 virReportError(VIR_ERR_INTERNAL_ERROR
,
658 _("Checkpoints have inconsistent relations for domain %s"),
661 /* FIXME: qemu keeps internal track of bitmaps, which form the
662 * basis for checkpoints; it would be nice if we could update our
663 * internal state to reflect that information automatically. But
664 * qemu 3.0 did not have access to this via qemu-img for offline
665 * images (you have to use QMP commands on a running guest), and
666 * it also does not track <parent> relations which we find
667 * important in our metadata.
676 virObjectUnref(caps
);
683 qemuDomainNetsRestart(virDomainObjPtr vm
,
684 void *data ATTRIBUTE_UNUSED
)
687 virDomainDefPtr def
= vm
->def
;
691 for (i
= 0; i
< def
->nnets
; i
++) {
692 virDomainNetDefPtr net
= def
->nets
[i
];
693 if (virDomainNetGetActualType(net
) == VIR_DOMAIN_NET_TYPE_DIRECT
&&
694 virDomainNetGetActualDirectMode(net
) == VIR_NETDEV_MACVLAN_MODE_VEPA
) {
695 VIR_DEBUG("VEPA mode device %s active in domain %s. Reassociating.",
696 net
->ifname
, def
->name
);
697 ignore_value(virNetDevMacVLanRestartWithVPortProfile(net
->ifname
,
699 virDomainNetGetActualDirectDev(net
),
701 virDomainNetGetActualVirtPortProfile(net
),
702 VIR_NETDEV_VPORT_PROFILE_OP_CREATE
));
712 qemuDomainFindMaxID(virDomainObjPtr vm
,
715 int *driver_maxid
= data
;
717 if (vm
->def
->id
> *driver_maxid
)
718 *driver_maxid
= vm
->def
->id
;
725 * qemuStateInitialize:
727 * Initialization function for the QEMU daemon
730 qemuStateInitialize(bool privileged
,
731 virStateInhibitCallback callback
,
734 char *driverConf
= NULL
;
735 virQEMUDriverConfigPtr cfg
;
738 char *hugepagePath
= NULL
;
739 char *memoryBackingPath
= NULL
;
741 virCPUDefPtr hostCPU
= NULL
;
742 unsigned int microcodeVersion
= 0;
744 if (VIR_ALLOC(qemu_driver
) < 0)
747 if (virMutexInit(&qemu_driver
->lock
) < 0) {
748 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
749 _("cannot initialize mutex"));
750 VIR_FREE(qemu_driver
);
754 qemu_driver
->inhibitCallback
= callback
;
755 qemu_driver
->inhibitOpaque
= opaque
;
757 qemu_driver
->privileged
= privileged
;
759 if (!(qemu_driver
->domains
= virDomainObjListNew()))
762 /* Init domain events */
763 qemu_driver
->domainEventState
= virObjectEventStateNew();
764 if (!qemu_driver
->domainEventState
)
767 /* read the host sysinfo */
769 qemu_driver
->hostsysinfo
= virSysinfoRead();
771 if (!(qemu_driver
->config
= cfg
= virQEMUDriverConfigNew(privileged
)))
774 if (virAsprintf(&driverConf
, "%s/qemu.conf", cfg
->configBaseDir
) < 0)
777 if (virQEMUDriverConfigLoadFile(cfg
, driverConf
, privileged
) < 0)
779 VIR_FREE(driverConf
);
781 if (virQEMUDriverConfigValidate(cfg
) < 0)
784 if (virQEMUDriverConfigSetDefaults(cfg
) < 0)
787 if (virFileMakePath(cfg
->stateDir
) < 0) {
788 virReportSystemError(errno
, _("Failed to create state dir %s"),
792 if (virFileMakePath(cfg
->libDir
) < 0) {
793 virReportSystemError(errno
, _("Failed to create lib dir %s"),
797 if (virFileMakePath(cfg
->cacheDir
) < 0) {
798 virReportSystemError(errno
, _("Failed to create cache dir %s"),
802 if (virFileMakePath(cfg
->saveDir
) < 0) {
803 virReportSystemError(errno
, _("Failed to create save dir %s"),
807 if (virFileMakePath(cfg
->snapshotDir
) < 0) {
808 virReportSystemError(errno
, _("Failed to create snapshot dir %s"),
812 if (virFileMakePath(cfg
->checkpointDir
) < 0) {
813 virReportSystemError(errno
, _("Failed to create checkpoint dir %s"),
817 if (virFileMakePath(cfg
->autoDumpPath
) < 0) {
818 virReportSystemError(errno
, _("Failed to create dump dir %s"),
822 if (virFileMakePath(cfg
->channelTargetDir
) < 0) {
823 virReportSystemError(errno
, _("Failed to create channel target dir %s"),
824 cfg
->channelTargetDir
);
827 if (virFileMakePath(cfg
->nvramDir
) < 0) {
828 virReportSystemError(errno
, _("Failed to create nvram dir %s"),
832 if (virFileMakePath(cfg
->memoryBackingDir
) < 0) {
833 virReportSystemError(errno
, _("Failed to create memory backing dir %s"),
834 cfg
->memoryBackingDir
);
838 qemu_driver
->qemuImgBinary
= virFindFileInPath("qemu-img");
840 if (!(qemu_driver
->lockManager
=
841 virLockManagerPluginNew(cfg
->lockManagerName
?
842 cfg
->lockManagerName
: "nop",
848 if (cfg
->macFilter
) {
849 if (!(qemu_driver
->ebtables
= ebtablesContextNew("qemu"))) {
850 virReportSystemError(errno
,
851 _("failed to enable mac filter in '%s'"),
856 if (ebtablesAddForwardPolicyReject(qemu_driver
->ebtables
) < 0)
860 /* Allocate bitmap for remote display port reservations. We cannot
861 * do this before the config is loaded properly, since the port
862 * numbers are configurable now */
863 if ((qemu_driver
->remotePorts
=
864 virPortAllocatorRangeNew(_("display"),
866 cfg
->remotePortMax
)) == NULL
)
869 if ((qemu_driver
->webSocketPorts
=
870 virPortAllocatorRangeNew(_("webSocket"),
871 cfg
->webSocketPortMin
,
872 cfg
->webSocketPortMax
)) == NULL
)
875 if ((qemu_driver
->migrationPorts
=
876 virPortAllocatorRangeNew(_("migration"),
877 cfg
->migrationPortMin
,
878 cfg
->migrationPortMax
)) == NULL
)
881 if (qemuSecurityInit(qemu_driver
) < 0)
884 if (!(qemu_driver
->hostdevMgr
= virHostdevManagerGetDefault()))
887 if (!(qemu_driver
->sharedDevices
= virHashCreate(30, qemuSharedDeviceEntryFree
)))
890 if (qemuMigrationDstErrorInit(qemu_driver
) < 0)
896 if (chown(cfg
->libDir
, cfg
->user
, cfg
->group
) < 0) {
897 virReportSystemError(errno
,
898 _("unable to set ownership of '%s' to user %d:%d"),
899 cfg
->libDir
, (int)cfg
->user
,
903 if (chown(cfg
->cacheDir
, cfg
->user
, cfg
->group
) < 0) {
904 virReportSystemError(errno
,
905 _("unable to set ownership of '%s' to %d:%d"),
906 cfg
->cacheDir
, (int)cfg
->user
,
910 if (chown(cfg
->saveDir
, cfg
->user
, cfg
->group
) < 0) {
911 virReportSystemError(errno
,
912 _("unable to set ownership of '%s' to %d:%d"),
913 cfg
->saveDir
, (int)cfg
->user
,
917 if (chown(cfg
->snapshotDir
, cfg
->user
, cfg
->group
) < 0) {
918 virReportSystemError(errno
,
919 _("unable to set ownership of '%s' to %d:%d"),
920 cfg
->snapshotDir
, (int)cfg
->user
,
924 if (chown(cfg
->checkpointDir
, cfg
->user
, cfg
->group
) < 0) {
925 virReportSystemError(errno
,
926 _("unable to set ownership of '%s' to %d:%d"),
927 cfg
->checkpointDir
, (int)cfg
->user
,
931 if (chown(cfg
->autoDumpPath
, cfg
->user
, cfg
->group
) < 0) {
932 virReportSystemError(errno
,
933 _("unable to set ownership of '%s' to %d:%d"),
934 cfg
->autoDumpPath
, (int)cfg
->user
,
938 if (!(channeldir
= mdir_name(cfg
->channelTargetDir
))) {
942 if (chown(channeldir
, cfg
->user
, cfg
->group
) < 0) {
943 virReportSystemError(errno
,
944 _("unable to set ownership of '%s' to %d:%d"),
945 channeldir
, (int)cfg
->user
,
947 VIR_FREE(channeldir
);
950 VIR_FREE(channeldir
);
951 if (chown(cfg
->channelTargetDir
, cfg
->user
, cfg
->group
) < 0) {
952 virReportSystemError(errno
,
953 _("unable to set ownership of '%s' to %d:%d"),
954 cfg
->channelTargetDir
, (int)cfg
->user
,
958 if (chown(cfg
->nvramDir
, cfg
->user
, cfg
->group
) < 0) {
959 virReportSystemError(errno
,
960 _("unable to set ownership of '%s' to %d:%d"),
961 cfg
->nvramDir
, (int)cfg
->user
,
965 if (chown(cfg
->memoryBackingDir
, cfg
->user
, cfg
->group
) < 0) {
966 virReportSystemError(errno
,
967 _("unable to set ownership of '%s' to %d:%d"),
968 cfg
->memoryBackingDir
, (int)cfg
->user
,
974 run_gid
= cfg
->group
;
977 if ((hostCPU
= virCPUProbeHost(virArchFromHost())))
978 microcodeVersion
= hostCPU
->microcodeVersion
;
979 virCPUDefFree(hostCPU
);
981 qemu_driver
->qemuCapsCache
= virQEMUCapsCacheNew(cfg
->libDir
,
986 if (!qemu_driver
->qemuCapsCache
)
989 if ((qemu_driver
->caps
= virQEMUDriverCreateCapabilities(qemu_driver
)) == NULL
)
992 if (!(qemu_driver
->xmlopt
= virQEMUDriverCreateXMLConf(qemu_driver
)))
995 /* If hugetlbfs is present, then we need to create a sub-directory within
996 * it, since we can't assume the root mount point has permissions that
997 * will let our spawned QEMU instances use it. */
998 for (i
= 0; i
< cfg
->nhugetlbfs
; i
++) {
999 hugepagePath
= qemuGetBaseHugepagePath(&cfg
->hugetlbfs
[i
]);
1004 if (virFileMakePath(hugepagePath
) < 0) {
1005 virReportSystemError(errno
,
1006 _("unable to create hugepage path %s"),
1011 virFileUpdatePerm(cfg
->hugetlbfs
[i
].mnt_dir
,
1012 0, S_IXGRP
| S_IXOTH
) < 0)
1014 VIR_FREE(hugepagePath
);
1017 if (qemuGetMemoryBackingBasePath(cfg
, &memoryBackingPath
) < 0)
1020 if (virFileMakePath(memoryBackingPath
) < 0) {
1021 virReportSystemError(errno
,
1022 _("unable to create memory backing path %s"),
1028 virFileUpdatePerm(memoryBackingPath
,
1029 0, S_IXGRP
| S_IXOTH
) < 0)
1031 VIR_FREE(memoryBackingPath
);
1033 if (!(qemu_driver
->closeCallbacks
= virCloseCallbacksNew()))
1036 /* Get all the running persistent or transient configs first */
1037 if (virDomainObjListLoadAllConfigs(qemu_driver
->domains
,
1041 qemu_driver
->xmlopt
,
1045 /* find the maximum ID from active and transient configs to initialize
1046 * the driver with. This is to avoid race between autostart and reconnect
1048 virDomainObjListForEach(qemu_driver
->domains
,
1049 qemuDomainFindMaxID
,
1050 &qemu_driver
->lastvmid
);
1052 virDomainObjListForEach(qemu_driver
->domains
,
1053 qemuDomainNetsRestart
,
1056 /* Then inactive persistent configs */
1057 if (virDomainObjListLoadAllConfigs(qemu_driver
->domains
,
1059 cfg
->autostartDir
, false,
1061 qemu_driver
->xmlopt
,
1065 virDomainObjListForEach(qemu_driver
->domains
,
1066 qemuDomainSnapshotLoad
,
1069 virDomainObjListForEach(qemu_driver
->domains
,
1070 qemuDomainCheckpointLoad
,
1071 cfg
->checkpointDir
);
1073 virDomainObjListForEach(qemu_driver
->domains
,
1074 qemuDomainManagedSaveLoad
,
1077 /* must be initialized before trying to reconnect to all the
1078 * running domains since there might occur some QEMU monitor
1079 * events that will be dispatched to the worker pool */
1080 qemu_driver
->workerPool
= virThreadPoolNew(0, 1, 0, qemuProcessEventHandler
, qemu_driver
);
1081 if (!qemu_driver
->workerPool
)
1084 qemuProcessReconnectAll(qemu_driver
);
1086 qemuAutostartDomains(qemu_driver
);
1091 VIR_FREE(driverConf
);
1092 VIR_FREE(hugepagePath
);
1093 VIR_FREE(memoryBackingPath
);
1098 static void qemuNotifyLoadDomain(virDomainObjPtr vm
, int newVM
, void *opaque
)
1100 virQEMUDriverPtr driver
= opaque
;
1103 virObjectEventPtr event
=
1104 virDomainEventLifecycleNewFromObj(vm
,
1105 VIR_DOMAIN_EVENT_DEFINED
,
1106 VIR_DOMAIN_EVENT_DEFINED_ADDED
);
1107 virObjectEventStateQueue(driver
->domainEventState
, event
);
1114 * Function to restart the QEMU daemon, it will recheck the configuration
1115 * files and update its state and the networking
1118 qemuStateReload(void)
1120 virQEMUDriverConfigPtr cfg
= NULL
;
1121 virCapsPtr caps
= NULL
;
1126 if (!(caps
= virQEMUDriverGetCapabilities(qemu_driver
, false)))
1129 cfg
= virQEMUDriverGetConfig(qemu_driver
);
1130 virDomainObjListLoadAllConfigs(qemu_driver
->domains
,
1132 cfg
->autostartDir
, false,
1133 caps
, qemu_driver
->xmlopt
,
1134 qemuNotifyLoadDomain
, qemu_driver
);
1136 virObjectUnref(cfg
);
1137 virObjectUnref(caps
);
1145 * Save any VMs in preparation for shutdown
1156 virDomainPtr
*domains
= NULL
;
1157 unsigned int *flags
= NULL
;
1158 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(qemu_driver
);
1160 if (!(conn
= virConnectOpen(cfg
->uri
)))
1163 if ((numDomains
= virConnectListAllDomains(conn
,
1165 VIR_CONNECT_LIST_DOMAINS_ACTIVE
)) < 0)
1168 if (VIR_ALLOC_N(flags
, numDomains
) < 0)
1171 /* First we pause all VMs to make them stop dirtying
1172 pages, etc. We remember if any VMs were paused so
1173 we can restore that on resume. */
1174 for (i
= 0; i
< numDomains
; i
++) {
1175 flags
[i
] = VIR_DOMAIN_SAVE_RUNNING
;
1176 if (virDomainGetState(domains
[i
], &state
, NULL
, 0) == 0) {
1177 if (state
== VIR_DOMAIN_PAUSED
)
1178 flags
[i
] = VIR_DOMAIN_SAVE_PAUSED
;
1180 virDomainSuspend(domains
[i
]);
1184 /* Then we save the VMs to disk */
1185 for (i
= 0; i
< numDomains
; i
++)
1186 if (virDomainManagedSave(domains
[i
], flags
[i
]) < 0)
1191 for (i
= 0; i
< numDomains
; i
++)
1192 virObjectUnref(domains
[i
]);
1196 virObjectUnref(conn
);
1197 virObjectUnref(cfg
);
1205 * Shutdown the QEMU daemon, it will stop all active domains and networks
1208 qemuStateCleanup(void)
1213 virThreadPoolFree(qemu_driver
->workerPool
);
1214 virObjectUnref(qemu_driver
->config
);
1215 virObjectUnref(qemu_driver
->hostdevMgr
);
1216 virHashFree(qemu_driver
->sharedDevices
);
1217 virObjectUnref(qemu_driver
->caps
);
1218 virObjectUnref(qemu_driver
->qemuCapsCache
);
1220 virObjectUnref(qemu_driver
->domains
);
1221 virPortAllocatorRangeFree(qemu_driver
->remotePorts
);
1222 virPortAllocatorRangeFree(qemu_driver
->webSocketPorts
);
1223 virPortAllocatorRangeFree(qemu_driver
->migrationPorts
);
1224 virObjectUnref(qemu_driver
->migrationErrors
);
1226 virObjectUnref(qemu_driver
->xmlopt
);
1228 virSysinfoDefFree(qemu_driver
->hostsysinfo
);
1230 virObjectUnref(qemu_driver
->closeCallbacks
);
1232 VIR_FREE(qemu_driver
->qemuImgBinary
);
1234 virObjectUnref(qemu_driver
->securityManager
);
1236 ebtablesContextFree(qemu_driver
->ebtables
);
1238 /* Free domain callback list */
1239 virObjectUnref(qemu_driver
->domainEventState
);
1241 virLockManagerPluginUnref(qemu_driver
->lockManager
);
1243 virMutexDestroy(&qemu_driver
->lock
);
1244 VIR_FREE(qemu_driver
);
1251 qemuConnectURIProbe(char **uri
)
1253 virQEMUDriverConfigPtr cfg
= NULL
;
1256 if (qemu_driver
== NULL
)
1259 cfg
= virQEMUDriverGetConfig(qemu_driver
);
1260 if (VIR_STRDUP(*uri
, cfg
->uri
) < 0)
1265 virObjectUnref(cfg
);
1269 static virDrvOpenStatus
qemuConnectOpen(virConnectPtr conn
,
1270 virConnectAuthPtr auth ATTRIBUTE_UNUSED
,
1271 virConfPtr conf ATTRIBUTE_UNUSED
,
1274 virQEMUDriverConfigPtr cfg
= NULL
;
1275 virDrvOpenStatus ret
= VIR_DRV_OPEN_ERROR
;
1276 virCheckFlags(VIR_CONNECT_RO
, VIR_DRV_OPEN_ERROR
);
1278 if (qemu_driver
== NULL
) {
1279 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
1280 _("qemu state driver is not active"));
1284 cfg
= virQEMUDriverGetConfig(qemu_driver
);
1286 if (virQEMUDriverIsPrivileged(qemu_driver
)) {
1287 if (STRNEQ(conn
->uri
->path
, "/system") &&
1288 STRNEQ(conn
->uri
->path
, "/session")) {
1289 virReportError(VIR_ERR_INTERNAL_ERROR
,
1290 _("unexpected QEMU URI path '%s', try qemu:///system"),
1295 if (STRNEQ(conn
->uri
->path
, "/session")) {
1296 virReportError(VIR_ERR_INTERNAL_ERROR
,
1297 _("unexpected QEMU URI path '%s', try qemu:///session"),
1303 if (virConnectOpenEnsureACL(conn
) < 0)
1306 conn
->privateData
= qemu_driver
;
1308 ret
= VIR_DRV_OPEN_SUCCESS
;
1310 virObjectUnref(cfg
);
1314 static int qemuConnectClose(virConnectPtr conn
)
1316 virQEMUDriverPtr driver
= conn
->privateData
;
1318 /* Get rid of callbacks registered for this conn */
1319 virCloseCallbacksRun(driver
->closeCallbacks
, conn
, driver
->domains
, driver
);
1321 conn
->privateData
= NULL
;
1326 /* Which features are supported by this driver? */
1328 qemuConnectSupportsFeature(virConnectPtr conn
, int feature
)
1330 if (virConnectSupportsFeatureEnsureACL(conn
) < 0)
1333 switch ((virDrvFeature
) feature
) {
1334 case VIR_DRV_FEATURE_MIGRATION_V2
:
1335 case VIR_DRV_FEATURE_MIGRATION_V3
:
1336 case VIR_DRV_FEATURE_MIGRATION_P2P
:
1337 case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION
:
1338 case VIR_DRV_FEATURE_FD_PASSING
:
1339 case VIR_DRV_FEATURE_TYPED_PARAM_STRING
:
1340 case VIR_DRV_FEATURE_XML_MIGRATABLE
:
1341 case VIR_DRV_FEATURE_MIGRATION_OFFLINE
:
1342 case VIR_DRV_FEATURE_MIGRATION_PARAMS
:
1344 case VIR_DRV_FEATURE_MIGRATION_DIRECT
:
1345 case VIR_DRV_FEATURE_MIGRATION_V1
:
1346 case VIR_DRV_FEATURE_PROGRAM_KEEPALIVE
:
1347 case VIR_DRV_FEATURE_REMOTE
:
1348 case VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK
:
1349 case VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK
:
1355 static const char *qemuConnectGetType(virConnectPtr conn
) {
1356 if (virConnectGetTypeEnsureACL(conn
) < 0)
1363 static int qemuConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED
)
1365 /* Trivially secure, since always inside the daemon */
1369 static int qemuConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED
)
1371 /* Not encrypted, but remote driver takes care of that */
1375 static int qemuConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED
)
1382 qemuConnectGetSysinfo(virConnectPtr conn
, unsigned int flags
)
1384 virQEMUDriverPtr driver
= conn
->privateData
;
1385 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
1387 virCheckFlags(0, NULL
);
1389 if (virConnectGetSysinfoEnsureACL(conn
) < 0)
1392 if (!driver
->hostsysinfo
) {
1393 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
1394 _("Host SMBIOS information is not available"));
1398 if (virSysinfoFormat(&buf
, driver
->hostsysinfo
) < 0)
1400 if (virBufferCheckError(&buf
) < 0)
1402 return virBufferContentAndReset(&buf
);
1406 qemuConnectGetMaxVcpus(virConnectPtr conn ATTRIBUTE_UNUSED
, const char *type
)
1408 if (virConnectGetMaxVcpusEnsureACL(conn
) < 0)
1414 if (STRCASEEQ(type
, "qemu"))
1417 if (STRCASEEQ(type
, "kvm"))
1418 return virHostCPUGetKVMMaxVCPUs();
1420 virReportError(VIR_ERR_INVALID_ARG
,
1421 _("unknown type '%s'"), type
);
1426 static char *qemuConnectGetCapabilities(virConnectPtr conn
) {
1427 virQEMUDriverPtr driver
= conn
->privateData
;
1428 virCapsPtr caps
= NULL
;
1431 if (virConnectGetCapabilitiesEnsureACL(conn
) < 0)
1434 if (!(caps
= virQEMUDriverGetCapabilities(driver
, true)))
1437 xml
= virCapabilitiesFormatXML(caps
);
1438 virObjectUnref(caps
);
1447 qemuGetSchedInfo(unsigned long long *cpuWait
,
1448 pid_t pid
, pid_t tid
)
1452 char **lines
= NULL
;
1459 /* In general, we cannot assume pid_t fits in int; but /proc parsing
1460 * is specific to Linux where int works fine. */
1462 ret
= virAsprintf(&proc
, "/proc/%d/task/%d/sched", (int)pid
, (int)tid
);
1464 ret
= virAsprintf(&proc
, "/proc/%d/sched", (int)pid
);
1469 /* The file is not guaranteed to exist (needs CONFIG_SCHED_DEBUG) */
1470 if (access(proc
, R_OK
) < 0) {
1475 if (virFileReadAll(proc
, (1<<16), &data
) < 0)
1478 lines
= virStringSplit(data
, "\n", 0);
1482 for (i
= 0; lines
[i
] != NULL
; i
++) {
1483 const char *line
= lines
[i
];
1485 /* Needs CONFIG_SCHEDSTATS. The second check
1486 * is the old name the kernel used in past */
1487 if (STRPREFIX(line
, "se.statistics.wait_sum") ||
1488 STRPREFIX(line
, "se.wait_sum")) {
1489 line
= strchr(line
, ':');
1491 virReportError(VIR_ERR_INTERNAL_ERROR
,
1492 _("Missing separator in sched info '%s'"),
1497 while (*line
== ' ')
1500 if (virStrToDouble(line
, NULL
, &val
) < 0) {
1501 virReportError(VIR_ERR_INTERNAL_ERROR
,
1502 _("Unable to parse sched info value '%s'"),
1507 *cpuWait
= (unsigned long long)(val
* 1000000);
1517 virStringListFree(lines
);
1523 qemuGetProcessInfo(unsigned long long *cpuTime
, int *lastCpu
, long *vm_rss
,
1528 unsigned long long usertime
= 0, systime
= 0;
1533 /* In general, we cannot assume pid_t fits in int; but /proc parsing
1534 * is specific to Linux where int works fine. */
1536 ret
= virAsprintf(&proc
, "/proc/%d/task/%d/stat", (int)pid
, tid
);
1538 ret
= virAsprintf(&proc
, "/proc/%d/stat", (int)pid
);
1542 pidinfo
= fopen(proc
, "r");
1545 /* See 'man proc' for information about what all these fields are. We're
1546 * only interested in a very few of them */
1550 "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %llu %llu"
1551 /* cutime -> endcode */
1552 "%*d %*d %*d %*d %*d %*d %*u %*u %ld %*u %*u %*u"
1553 /* startstack -> processor */
1554 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %d",
1555 &usertime
, &systime
, &rss
, &cpu
) != 4) {
1556 VIR_WARN("cannot parse process status data");
1560 * We want nanoseconds
1561 * _SC_CLK_TCK is jiffies per second
1562 * So calculate thus....
1565 *cpuTime
= 1000ull * 1000ull * 1000ull * (usertime
+ systime
)
1566 / (unsigned long long)sysconf(_SC_CLK_TCK
);
1571 *vm_rss
= rss
* virGetSystemPageSizeKB();
1574 VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d rss=%ld",
1575 (int)pid
, tid
, usertime
, systime
, cpu
, rss
);
1577 VIR_FORCE_FCLOSE(pidinfo
);
1584 qemuDomainHelperGetVcpus(virDomainObjPtr vm
,
1585 virVcpuInfoPtr info
,
1586 unsigned long long *cpuwait
,
1588 unsigned char *cpumaps
,
1591 size_t ncpuinfo
= 0;
1597 if (!qemuDomainHasVcpuPids(vm
)) {
1598 virReportError(VIR_ERR_OPERATION_INVALID
,
1599 "%s", _("cpu affinity is not supported"));
1604 memset(info
, 0, sizeof(*info
) * maxinfo
);
1607 memset(cpumaps
, 0, sizeof(*cpumaps
) * maxinfo
);
1609 for (i
= 0; i
< virDomainDefGetVcpusMax(vm
->def
) && ncpuinfo
< maxinfo
; i
++) {
1610 virDomainVcpuDefPtr vcpu
= virDomainDefGetVcpu(vm
->def
, i
);
1611 pid_t vcpupid
= qemuDomainGetVcpuPid(vm
, i
);
1612 virVcpuInfoPtr vcpuinfo
= info
+ ncpuinfo
;
1618 vcpuinfo
->number
= i
;
1619 vcpuinfo
->state
= VIR_VCPU_RUNNING
;
1621 if (qemuGetProcessInfo(&vcpuinfo
->cpuTime
,
1622 &vcpuinfo
->cpu
, NULL
,
1623 vm
->pid
, vcpupid
) < 0) {
1624 virReportSystemError(errno
, "%s",
1625 _("cannot get vCPU placement & pCPU time"));
1631 unsigned char *cpumap
= VIR_GET_CPUMAP(cpumaps
, maplen
, ncpuinfo
);
1632 virBitmapPtr map
= NULL
;
1634 if (!(map
= virProcessGetAffinity(vcpupid
)))
1637 virBitmapToDataBuf(map
, cpumap
, maplen
);
1642 if (qemuGetSchedInfo(&(cpuwait
[ncpuinfo
]), vm
->pid
, vcpupid
) < 0)
1653 static virDomainPtr
qemuDomainLookupByID(virConnectPtr conn
,
1656 virQEMUDriverPtr driver
= conn
->privateData
;
1658 virDomainPtr dom
= NULL
;
1660 vm
= virDomainObjListFindByID(driver
->domains
, id
);
1663 virReportError(VIR_ERR_NO_DOMAIN
,
1664 _("no domain with matching id %d"), id
);
1668 if (virDomainLookupByIDEnsureACL(conn
, vm
->def
) < 0)
1671 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
1674 virDomainObjEndAPI(&vm
);
1678 static virDomainPtr
qemuDomainLookupByUUID(virConnectPtr conn
,
1679 const unsigned char *uuid
)
1681 virQEMUDriverPtr driver
= conn
->privateData
;
1683 virDomainPtr dom
= NULL
;
1685 vm
= virDomainObjListFindByUUID(driver
->domains
, uuid
);
1688 char uuidstr
[VIR_UUID_STRING_BUFLEN
];
1689 virUUIDFormat(uuid
, uuidstr
);
1690 virReportError(VIR_ERR_NO_DOMAIN
,
1691 _("no domain with matching uuid '%s'"), uuidstr
);
1695 if (virDomainLookupByUUIDEnsureACL(conn
, vm
->def
) < 0)
1698 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
1701 virDomainObjEndAPI(&vm
);
1705 static virDomainPtr
qemuDomainLookupByName(virConnectPtr conn
,
1708 virQEMUDriverPtr driver
= conn
->privateData
;
1710 virDomainPtr dom
= NULL
;
1712 vm
= virDomainObjListFindByName(driver
->domains
, name
);
1715 virReportError(VIR_ERR_NO_DOMAIN
,
1716 _("no domain with matching name '%s'"), name
);
1720 if (virDomainLookupByNameEnsureACL(conn
, vm
->def
) < 0)
1723 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
1726 virDomainObjEndAPI(&vm
);
1731 static int qemuDomainIsActive(virDomainPtr dom
)
1733 virDomainObjPtr obj
;
1736 if (!(obj
= qemuDomObjFromDomain(dom
)))
1739 if (virDomainIsActiveEnsureACL(dom
->conn
, obj
->def
) < 0)
1742 ret
= virDomainObjIsActive(obj
);
1745 virDomainObjEndAPI(&obj
);
1749 static int qemuDomainIsPersistent(virDomainPtr dom
)
1751 virDomainObjPtr obj
;
1754 if (!(obj
= qemuDomObjFromDomain(dom
)))
1757 if (virDomainIsPersistentEnsureACL(dom
->conn
, obj
->def
) < 0)
1760 ret
= obj
->persistent
;
1763 virDomainObjEndAPI(&obj
);
1767 static int qemuDomainIsUpdated(virDomainPtr dom
)
1769 virDomainObjPtr obj
;
1772 if (!(obj
= qemuDomObjFromDomain(dom
)))
1775 if (virDomainIsUpdatedEnsureACL(dom
->conn
, obj
->def
) < 0)
1781 virDomainObjEndAPI(&obj
);
1785 static int qemuConnectGetVersion(virConnectPtr conn
, unsigned long *version
)
1787 virQEMUDriverPtr driver
= conn
->privateData
;
1789 unsigned int qemuVersion
= 0;
1790 virCapsPtr caps
= NULL
;
1792 if (virConnectGetVersionEnsureACL(conn
) < 0)
1795 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
1798 if (virQEMUCapsGetDefaultVersion(caps
,
1799 driver
->qemuCapsCache
,
1803 *version
= qemuVersion
;
1807 virObjectUnref(caps
);
1812 static char *qemuConnectGetHostname(virConnectPtr conn
)
1814 if (virConnectGetHostnameEnsureACL(conn
) < 0)
1817 return virGetHostname();
1821 static int qemuConnectListDomains(virConnectPtr conn
, int *ids
, int nids
)
1823 virQEMUDriverPtr driver
= conn
->privateData
;
1826 if (virConnectListDomainsEnsureACL(conn
) < 0)
1829 n
= virDomainObjListGetActiveIDs(driver
->domains
, ids
, nids
,
1830 virConnectListDomainsCheckACL
, conn
);
1835 static int qemuConnectNumOfDomains(virConnectPtr conn
)
1837 virQEMUDriverPtr driver
= conn
->privateData
;
1840 if (virConnectNumOfDomainsEnsureACL(conn
) < 0)
1843 n
= virDomainObjListNumOfDomains(driver
->domains
, true,
1844 virConnectNumOfDomainsCheckACL
, conn
);
1850 static virDomainPtr
qemuDomainCreateXML(virConnectPtr conn
,
1854 virQEMUDriverPtr driver
= conn
->privateData
;
1855 virDomainDefPtr def
= NULL
;
1856 virDomainObjPtr vm
= NULL
;
1857 virDomainPtr dom
= NULL
;
1858 virObjectEventPtr event
= NULL
;
1859 virObjectEventPtr event2
= NULL
;
1860 unsigned int start_flags
= VIR_QEMU_PROCESS_START_COLD
;
1861 virCapsPtr caps
= NULL
;
1862 unsigned int parse_flags
= VIR_DOMAIN_DEF_PARSE_INACTIVE
|
1863 VIR_DOMAIN_DEF_PARSE_ABI_UPDATE
;
1865 virCheckFlags(VIR_DOMAIN_START_PAUSED
|
1866 VIR_DOMAIN_START_AUTODESTROY
|
1867 VIR_DOMAIN_START_VALIDATE
, NULL
);
1869 if (flags
& VIR_DOMAIN_START_VALIDATE
)
1870 parse_flags
|= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA
;
1871 if (flags
& VIR_DOMAIN_START_PAUSED
)
1872 start_flags
|= VIR_QEMU_PROCESS_START_PAUSED
;
1873 if (flags
& VIR_DOMAIN_START_AUTODESTROY
)
1874 start_flags
|= VIR_QEMU_PROCESS_START_AUTODESTROY
;
1876 virNWFilterReadLockFilterUpdates();
1878 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
1881 if (!(def
= virDomainDefParseString(xml
, caps
, driver
->xmlopt
,
1882 NULL
, parse_flags
)))
1885 if (virDomainCreateXMLEnsureACL(conn
, def
) < 0)
1888 if (!(vm
= virDomainObjListAdd(driver
->domains
, def
,
1890 VIR_DOMAIN_OBJ_LIST_ADD_LIVE
|
1891 VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE
,
1896 if (qemuProcessBeginJob(driver
, vm
, VIR_DOMAIN_JOB_OPERATION_START
,
1898 qemuDomainRemoveInactiveJob(driver
, vm
);
1902 if (qemuProcessStart(conn
, driver
, vm
, NULL
, QEMU_ASYNC_JOB_START
,
1903 NULL
, -1, NULL
, NULL
,
1904 VIR_NETDEV_VPORT_PROFILE_OP_CREATE
,
1906 virDomainAuditStart(vm
, "booted", false);
1907 qemuDomainRemoveInactive(driver
, vm
);
1908 qemuProcessEndJob(driver
, vm
);
1912 event
= virDomainEventLifecycleNewFromObj(vm
,
1913 VIR_DOMAIN_EVENT_STARTED
,
1914 VIR_DOMAIN_EVENT_STARTED_BOOTED
);
1915 if (event
&& (flags
& VIR_DOMAIN_START_PAUSED
)) {
1916 /* There are two classes of event-watching clients - those
1917 * that only care about on/off (and must see a started event
1918 * no matter what, but don't care about suspend events), and
1919 * those that also care about running/paused. To satisfy both
1920 * client types, we have to send two events. */
1921 event2
= virDomainEventLifecycleNewFromObj(vm
,
1922 VIR_DOMAIN_EVENT_SUSPENDED
,
1923 VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
);
1925 virDomainAuditStart(vm
, "booted", true);
1927 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
1929 qemuProcessEndJob(driver
, vm
);
1932 virDomainDefFree(def
);
1933 virDomainObjEndAPI(&vm
);
1934 virObjectEventStateQueue(driver
->domainEventState
, event
);
1935 virObjectEventStateQueue(driver
->domainEventState
, event2
);
1936 virObjectUnref(caps
);
1937 virNWFilterUnlockFilterUpdates();
1942 static int qemuDomainSuspend(virDomainPtr dom
)
1944 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
1947 virObjectEventPtr event
= NULL
;
1948 qemuDomainObjPrivatePtr priv
;
1949 virDomainPausedReason reason
;
1952 virQEMUDriverConfigPtr cfg
= NULL
;
1954 if (!(vm
= qemuDomObjFromDomain(dom
)))
1957 if (virDomainSuspendEnsureACL(dom
->conn
, vm
->def
) < 0)
1960 cfg
= virQEMUDriverGetConfig(driver
);
1961 priv
= vm
->privateData
;
1963 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_SUSPEND
) < 0)
1966 if (virDomainObjCheckActive(vm
) < 0)
1969 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_OUT
) {
1970 reason
= VIR_DOMAIN_PAUSED_MIGRATION
;
1971 eventDetail
= VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED
;
1972 } else if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_SNAPSHOT
) {
1973 reason
= VIR_DOMAIN_PAUSED_SNAPSHOT
;
1974 eventDetail
= -1; /* don't create lifecycle events when doing snapshot */
1976 reason
= VIR_DOMAIN_PAUSED_USER
;
1977 eventDetail
= VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
;
1980 state
= virDomainObjGetState(vm
, NULL
);
1981 if (state
== VIR_DOMAIN_PMSUSPENDED
) {
1982 virReportError(VIR_ERR_OPERATION_INVALID
,
1983 "%s", _("domain is pmsuspended"));
1985 } else if (state
!= VIR_DOMAIN_PAUSED
) {
1986 if (qemuProcessStopCPUs(driver
, vm
, reason
, QEMU_ASYNC_JOB_NONE
) < 0)
1989 if (eventDetail
>= 0) {
1990 event
= virDomainEventLifecycleNewFromObj(vm
,
1991 VIR_DOMAIN_EVENT_SUSPENDED
,
1995 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
2000 qemuDomainObjEndJob(driver
, vm
);
2003 virDomainObjEndAPI(&vm
);
2005 virObjectEventStateQueue(driver
->domainEventState
, event
);
2006 virObjectUnref(cfg
);
2011 static int qemuDomainResume(virDomainPtr dom
)
2013 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2018 virQEMUDriverConfigPtr cfg
= NULL
;
2020 if (!(vm
= qemuDomObjFromDomain(dom
)))
2023 cfg
= virQEMUDriverGetConfig(driver
);
2025 if (virDomainResumeEnsureACL(dom
->conn
, vm
->def
) < 0)
2028 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2031 if (virDomainObjCheckActive(vm
) < 0)
2034 state
= virDomainObjGetState(vm
, &reason
);
2035 if (state
== VIR_DOMAIN_PMSUSPENDED
) {
2036 virReportError(VIR_ERR_OPERATION_INVALID
,
2037 "%s", _("domain is pmsuspended"));
2039 } else if (state
== VIR_DOMAIN_RUNNING
) {
2040 virReportError(VIR_ERR_OPERATION_INVALID
,
2041 "%s", _("domain is already running"));
2043 } else if ((state
== VIR_DOMAIN_CRASHED
&&
2044 reason
== VIR_DOMAIN_CRASHED_PANICKED
) ||
2045 state
== VIR_DOMAIN_PAUSED
) {
2046 if (qemuProcessStartCPUs(driver
, vm
,
2047 VIR_DOMAIN_RUNNING_UNPAUSED
,
2048 QEMU_ASYNC_JOB_NONE
) < 0) {
2049 if (virGetLastErrorCode() == VIR_ERR_OK
)
2050 virReportError(VIR_ERR_OPERATION_FAILED
,
2051 "%s", _("resume operation failed"));
2055 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
2060 qemuDomainObjEndJob(driver
, vm
);
2063 virDomainObjEndAPI(&vm
);
2064 virObjectUnref(cfg
);
2068 static int qemuDomainShutdownFlags(virDomainPtr dom
, unsigned int flags
)
2070 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2073 qemuDomainObjPrivatePtr priv
;
2074 bool useAgent
= false, agentRequested
, acpiRequested
;
2075 bool isReboot
= false;
2077 qemuDomainAgentJob agentJob
= QEMU_AGENT_JOB_NONE
;
2078 int agentFlag
= QEMU_AGENT_SHUTDOWN_POWERDOWN
;
2080 virCheckFlags(VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN
|
2081 VIR_DOMAIN_SHUTDOWN_GUEST_AGENT
, -1);
2083 if (!(vm
= qemuDomObjFromDomain(dom
)))
2086 if (vm
->def
->onPoweroff
== VIR_DOMAIN_LIFECYCLE_ACTION_RESTART
||
2087 vm
->def
->onPoweroff
== VIR_DOMAIN_LIFECYCLE_ACTION_RESTART_RENAME
) {
2089 agentFlag
= QEMU_AGENT_SHUTDOWN_REBOOT
;
2090 VIR_INFO("Domain on_poweroff setting overridden, attempting reboot");
2093 priv
= vm
->privateData
;
2094 agentRequested
= flags
& VIR_DOMAIN_SHUTDOWN_GUEST_AGENT
;
2095 acpiRequested
= flags
& VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN
;
2097 /* Prefer agent unless we were requested to not to. */
2098 if (agentRequested
|| (!flags
&& priv
->agent
))
2101 if (virDomainShutdownFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
2105 agentJob
= QEMU_AGENT_JOB_MODIFY
;
2107 if (qemuDomainObjBeginJobWithAgent(driver
, vm
,
2112 if (virDomainObjGetState(vm
, NULL
) != VIR_DOMAIN_RUNNING
) {
2113 virReportError(VIR_ERR_OPERATION_INVALID
,
2114 "%s", _("domain is not running"));
2118 agentForced
= agentRequested
&& !acpiRequested
;
2119 if (!qemuDomainAgentAvailable(vm
, agentForced
)) {
2128 qemuDomainSetFakeReboot(driver
, vm
, false);
2129 agent
= qemuDomainObjEnterAgent(vm
);
2130 ret
= qemuAgentShutdown(agent
, agentFlag
);
2131 qemuDomainObjExitAgent(vm
, agent
);
2134 /* If we are not enforced to use just an agent, try ACPI
2135 * shutdown as well in case agent did not succeed.
2138 (ret
< 0 && (acpiRequested
|| !flags
))) {
2140 /* Even if agent failed, we have to check if guest went away
2141 * by itself while our locks were down. */
2142 if (useAgent
&& !virDomainObjIsActive(vm
)) {
2147 qemuDomainSetFakeReboot(driver
, vm
, isReboot
);
2148 qemuDomainObjEnterMonitor(driver
, vm
);
2149 ret
= qemuMonitorSystemPowerdown(priv
->mon
);
2150 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2156 qemuDomainObjEndJobWithAgent(driver
, vm
);
2158 qemuDomainObjEndJob(driver
, vm
);
2161 virDomainObjEndAPI(&vm
);
2165 static int qemuDomainShutdown(virDomainPtr dom
)
2167 return qemuDomainShutdownFlags(dom
, 0);
2172 qemuDomainReboot(virDomainPtr dom
, unsigned int flags
)
2174 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2177 qemuDomainObjPrivatePtr priv
;
2178 bool useAgent
= false, agentRequested
, acpiRequested
;
2179 bool isReboot
= true;
2181 qemuDomainAgentJob agentJob
= QEMU_AGENT_JOB_NONE
;
2182 int agentFlag
= QEMU_AGENT_SHUTDOWN_REBOOT
;
2184 virCheckFlags(VIR_DOMAIN_REBOOT_ACPI_POWER_BTN
|
2185 VIR_DOMAIN_REBOOT_GUEST_AGENT
, -1);
2187 if (!(vm
= qemuDomObjFromDomain(dom
)))
2190 if (vm
->def
->onReboot
== VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY
||
2191 vm
->def
->onReboot
== VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE
) {
2192 agentFlag
= QEMU_AGENT_SHUTDOWN_POWERDOWN
;
2194 VIR_INFO("Domain on_reboot setting overridden, shutting down");
2197 priv
= vm
->privateData
;
2198 agentRequested
= flags
& VIR_DOMAIN_REBOOT_GUEST_AGENT
;
2199 acpiRequested
= flags
& VIR_DOMAIN_REBOOT_ACPI_POWER_BTN
;
2201 /* Prefer agent unless we were requested to not to. */
2202 if (agentRequested
|| (!flags
&& priv
->agent
))
2205 if (virDomainRebootEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
2209 agentJob
= QEMU_AGENT_JOB_MODIFY
;
2211 if (qemuDomainObjBeginJobWithAgent(driver
, vm
,
2216 agentForced
= agentRequested
&& !acpiRequested
;
2217 if (!qemuDomainAgentAvailable(vm
, agentForced
)) {
2223 if (virDomainObjCheckActive(vm
) < 0)
2229 qemuDomainSetFakeReboot(driver
, vm
, false);
2230 agent
= qemuDomainObjEnterAgent(vm
);
2231 ret
= qemuAgentShutdown(agent
, agentFlag
);
2232 qemuDomainObjExitAgent(vm
, agent
);
2235 /* If we are not enforced to use just an agent, try ACPI
2236 * shutdown as well in case agent did not succeed.
2239 (ret
< 0 && (acpiRequested
|| !flags
))) {
2241 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2242 _("ACPI reboot is not supported without the JSON monitor"));
2245 qemuDomainSetFakeReboot(driver
, vm
, isReboot
);
2246 qemuDomainObjEnterMonitor(driver
, vm
);
2247 ret
= qemuMonitorSystemPowerdown(priv
->mon
);
2248 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2254 qemuDomainObjEndJobWithAgent(driver
, vm
);
2256 qemuDomainObjEndJob(driver
, vm
);
2259 virDomainObjEndAPI(&vm
);
2265 qemuDomainReset(virDomainPtr dom
, unsigned int flags
)
2267 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2270 qemuDomainObjPrivatePtr priv
;
2271 virDomainState state
;
2273 virCheckFlags(0, -1);
2275 if (!(vm
= qemuDomObjFromDomain(dom
)))
2278 if (virDomainResetEnsureACL(dom
->conn
, vm
->def
) < 0)
2281 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2284 if (virDomainObjCheckActive(vm
) < 0)
2287 priv
= vm
->privateData
;
2288 qemuDomainObjEnterMonitor(driver
, vm
);
2289 ret
= qemuMonitorSystemReset(priv
->mon
);
2290 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2293 priv
->fakeReboot
= false;
2295 state
= virDomainObjGetState(vm
, NULL
);
2296 if (state
== VIR_DOMAIN_CRASHED
)
2297 virDomainObjSetState(vm
, VIR_DOMAIN_PAUSED
, VIR_DOMAIN_PAUSED_CRASHED
);
2300 qemuDomainObjEndJob(driver
, vm
);
2303 virDomainObjEndAPI(&vm
);
2308 /* Count how many snapshots in a set are external snapshots. */
2310 qemuDomainSnapshotCountExternal(void *payload
,
2311 const void *name ATTRIBUTE_UNUSED
,
2314 virDomainMomentObjPtr snap
= payload
;
2317 if (virDomainSnapshotIsExternal(snap
))
2323 qemuDomainDestroyFlags(virDomainPtr dom
,
2326 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2329 virObjectEventPtr event
= NULL
;
2330 qemuDomainObjPrivatePtr priv
;
2331 unsigned int stopFlags
= 0;
2336 virCheckFlags(VIR_DOMAIN_DESTROY_GRACEFUL
, -1);
2338 if (!(vm
= qemuDomObjFromDomain(dom
)))
2341 priv
= vm
->privateData
;
2343 if (virDomainDestroyFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
2346 if (virDomainObjCheckActive(vm
) < 0)
2349 state
= virDomainObjGetState(vm
, &reason
);
2350 starting
= (state
== VIR_DOMAIN_PAUSED
&&
2351 reason
== VIR_DOMAIN_PAUSED_STARTING_UP
&&
2352 !priv
->beingDestroyed
);
2354 if (qemuProcessBeginStopJob(driver
, vm
, QEMU_JOB_DESTROY
,
2355 !(flags
& VIR_DOMAIN_DESTROY_GRACEFUL
)) < 0)
2358 if (!virDomainObjIsActive(vm
)) {
2360 VIR_DEBUG("Domain %s is not running anymore", vm
->def
->name
);
2363 virReportError(VIR_ERR_OPERATION_INVALID
,
2364 "%s", _("domain is not running"));
2369 qemuDomainSetFakeReboot(driver
, vm
, false);
2371 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_IN
)
2372 stopFlags
|= VIR_QEMU_PROCESS_STOP_MIGRATED
;
2374 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_DESTROYED
,
2375 QEMU_ASYNC_JOB_NONE
, stopFlags
);
2376 event
= virDomainEventLifecycleNewFromObj(vm
,
2377 VIR_DOMAIN_EVENT_STOPPED
,
2378 VIR_DOMAIN_EVENT_STOPPED_DESTROYED
);
2379 virDomainAuditStop(vm
, "destroyed");
2384 qemuDomainRemoveInactive(driver
, vm
);
2385 qemuDomainObjEndJob(driver
, vm
);
2388 virDomainObjEndAPI(&vm
);
2389 virObjectEventStateQueue(driver
->domainEventState
, event
);
2394 qemuDomainDestroy(virDomainPtr dom
)
2396 return qemuDomainDestroyFlags(dom
, 0);
2399 static char *qemuDomainGetOSType(virDomainPtr dom
) {
2403 if (!(vm
= qemuDomObjFromDomain(dom
)))
2406 if (virDomainGetOSTypeEnsureACL(dom
->conn
, vm
->def
) < 0)
2409 ignore_value(VIR_STRDUP(type
, virDomainOSTypeToString(vm
->def
->os
.type
)));
2412 virDomainObjEndAPI(&vm
);
2416 /* Returns max memory in kb, 0 if error */
2417 static unsigned long long
2418 qemuDomainGetMaxMemory(virDomainPtr dom
)
2421 unsigned long long ret
= 0;
2423 if (!(vm
= qemuDomObjFromDomain(dom
)))
2426 if (virDomainGetMaxMemoryEnsureACL(dom
->conn
, vm
->def
) < 0)
2429 ret
= virDomainDefGetMemoryTotal(vm
->def
);
2432 virDomainObjEndAPI(&vm
);
2436 static int qemuDomainSetMemoryFlags(virDomainPtr dom
, unsigned long newmem
,
2439 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2440 qemuDomainObjPrivatePtr priv
;
2442 virDomainDefPtr def
;
2443 virDomainDefPtr persistentDef
;
2445 virQEMUDriverConfigPtr cfg
= NULL
;
2447 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
2448 VIR_DOMAIN_AFFECT_CONFIG
|
2449 VIR_DOMAIN_MEM_MAXIMUM
, -1);
2451 if (!(vm
= qemuDomObjFromDomain(dom
)))
2454 cfg
= virQEMUDriverGetConfig(driver
);
2456 if (virDomainSetMemoryFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
2459 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2462 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
2466 if (flags
& VIR_DOMAIN_MEM_MAXIMUM
) {
2467 /* resize the maximum memory */
2470 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2471 _("cannot resize the maximum memory on an "
2476 if (persistentDef
) {
2477 /* resizing memory with NUMA nodes specified doesn't work as there
2478 * is no way to change the individual node sizes with this API */
2479 if (virDomainNumaGetNodeCount(persistentDef
->numa
) > 0) {
2480 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2481 _("initial memory size of a domain with NUMA "
2482 "nodes cannot be modified with this API"));
2486 if (persistentDef
->mem
.max_memory
&&
2487 persistentDef
->mem
.max_memory
< newmem
) {
2488 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2489 _("cannot set initial memory size greater than "
2490 "the maximum memory size"));
2494 virDomainDefSetMemoryTotal(persistentDef
, newmem
);
2496 if (persistentDef
->mem
.cur_balloon
> newmem
)
2497 persistentDef
->mem
.cur_balloon
= newmem
;
2498 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
2504 /* resize the current memory */
2505 unsigned long oldmax
= 0;
2508 oldmax
= virDomainDefGetMemoryTotal(def
);
2509 if (persistentDef
) {
2510 if (!oldmax
|| oldmax
> virDomainDefGetMemoryTotal(persistentDef
))
2511 oldmax
= virDomainDefGetMemoryTotal(persistentDef
);
2514 if (newmem
> oldmax
) {
2515 virReportError(VIR_ERR_INVALID_ARG
, "%s",
2516 _("cannot set memory higher than max memory"));
2521 priv
= vm
->privateData
;
2522 qemuDomainObjEnterMonitor(driver
, vm
);
2523 r
= qemuMonitorSetBalloon(priv
->mon
, newmem
);
2524 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || r
< 0)
2527 /* Lack of balloon support is a fatal error */
2529 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2530 _("Unable to change memory of active domain without "
2531 "the balloon device and guest OS balloon driver"));
2536 if (persistentDef
) {
2537 persistentDef
->mem
.cur_balloon
= newmem
;
2538 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
2546 qemuDomainObjEndJob(driver
, vm
);
2549 virDomainObjEndAPI(&vm
);
2550 virObjectUnref(cfg
);
2554 static int qemuDomainSetMemory(virDomainPtr dom
, unsigned long newmem
)
2556 return qemuDomainSetMemoryFlags(dom
, newmem
, VIR_DOMAIN_AFFECT_LIVE
);
2559 static int qemuDomainSetMaxMemory(virDomainPtr dom
, unsigned long memory
)
2561 return qemuDomainSetMemoryFlags(dom
, memory
, VIR_DOMAIN_MEM_MAXIMUM
);
2564 static int qemuDomainSetMemoryStatsPeriod(virDomainPtr dom
, int period
,
2567 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2568 qemuDomainObjPrivatePtr priv
;
2570 virDomainDefPtr def
;
2571 virDomainDefPtr persistentDef
;
2573 virQEMUDriverConfigPtr cfg
= NULL
;
2575 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
2576 VIR_DOMAIN_AFFECT_CONFIG
, -1);
2578 if (!(vm
= qemuDomObjFromDomain(dom
)))
2581 cfg
= virQEMUDriverGetConfig(driver
);
2583 if (virDomainSetMemoryStatsPeriodEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
2586 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2589 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
2592 /* Set the balloon driver collection interval */
2593 priv
= vm
->privateData
;
2596 if (!virDomainDefHasMemballoon(def
)) {
2597 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
2598 _("No memory balloon device configured, "
2599 "can not set the collection period"));
2603 qemuDomainObjEnterMonitor(driver
, vm
);
2604 r
= qemuMonitorSetMemoryStatsPeriod(priv
->mon
, def
->memballoon
, period
);
2605 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2608 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2609 _("unable to set balloon driver collection period"));
2613 def
->memballoon
->period
= period
;
2614 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
2618 if (persistentDef
) {
2619 if (!virDomainDefHasMemballoon(persistentDef
)) {
2620 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
2621 _("No memory balloon device configured, "
2622 "can not set the collection period"));
2625 persistentDef
->memballoon
->period
= period
;
2626 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
);
2632 qemuDomainObjEndJob(driver
, vm
);
2635 virDomainObjEndAPI(&vm
);
2636 virObjectUnref(cfg
);
2640 static int qemuDomainInjectNMI(virDomainPtr domain
, unsigned int flags
)
2642 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
2643 virDomainObjPtr vm
= NULL
;
2645 qemuDomainObjPrivatePtr priv
;
2647 virCheckFlags(0, -1);
2649 if (!(vm
= qemuDomObjFromDomain(domain
)))
2652 if (virDomainInjectNMIEnsureACL(domain
->conn
, vm
->def
) < 0)
2655 priv
= vm
->privateData
;
2657 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2660 if (virDomainObjCheckActive(vm
) < 0)
2663 qemuDomainObjEnterMonitor(driver
, vm
);
2664 ret
= qemuMonitorInjectNMI(priv
->mon
);
2665 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2669 qemuDomainObjEndJob(driver
, vm
);
2672 virDomainObjEndAPI(&vm
);
2676 static int qemuDomainSendKey(virDomainPtr domain
,
2677 unsigned int codeset
,
2678 unsigned int holdtime
,
2679 unsigned int *keycodes
,
2683 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
2684 virDomainObjPtr vm
= NULL
;
2686 qemuDomainObjPrivatePtr priv
;
2688 virCheckFlags(0, -1);
2690 /* translate the keycode to QNUM for qemu driver */
2691 if (codeset
!= VIR_KEYCODE_SET_QNUM
) {
2695 for (i
= 0; i
< nkeycodes
; i
++) {
2696 keycode
= virKeycodeValueTranslate(codeset
, VIR_KEYCODE_SET_QNUM
,
2699 virReportError(VIR_ERR_INTERNAL_ERROR
,
2700 _("cannot translate keycode %u of %s codeset to qnum keycode"),
2702 virKeycodeSetTypeToString(codeset
));
2705 keycodes
[i
] = keycode
;
2709 if (!(vm
= qemuDomObjFromDomain(domain
)))
2712 priv
= vm
->privateData
;
2714 if (virDomainSendKeyEnsureACL(domain
->conn
, vm
->def
) < 0)
2717 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2720 if (virDomainObjCheckActive(vm
) < 0)
2723 qemuDomainObjEnterMonitor(driver
, vm
);
2724 ret
= qemuMonitorSendKey(priv
->mon
, holdtime
, keycodes
, nkeycodes
);
2725 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2729 qemuDomainObjEndJob(driver
, vm
);
2732 virDomainObjEndAPI(&vm
);
2738 qemuDomainGetInfo(virDomainPtr dom
,
2739 virDomainInfoPtr info
)
2741 unsigned long long maxmem
;
2745 if (!(vm
= qemuDomObjFromDomain(dom
)))
2748 if (virDomainGetInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
2751 qemuDomainUpdateCurrentMemorySize(vm
);
2753 memset(info
, 0, sizeof(*info
));
2755 info
->state
= virDomainObjGetState(vm
, NULL
);
2757 maxmem
= virDomainDefGetMemoryTotal(vm
->def
);
2758 if (VIR_ASSIGN_IS_OVERFLOW(info
->maxMem
, maxmem
)) {
2759 virReportError(VIR_ERR_OVERFLOW
, "%s",
2760 _("Initial memory size too large"));
2764 if (VIR_ASSIGN_IS_OVERFLOW(info
->memory
, vm
->def
->mem
.cur_balloon
)) {
2765 virReportError(VIR_ERR_OVERFLOW
, "%s",
2766 _("Current memory size too large"));
2770 if (virDomainObjIsActive(vm
)) {
2771 if (qemuGetProcessInfo(&(info
->cpuTime
), NULL
, NULL
, vm
->pid
, 0) < 0) {
2772 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
2773 _("cannot read cputime for domain"));
2778 if (VIR_ASSIGN_IS_OVERFLOW(info
->nrVirtCpu
, virDomainDefGetVcpus(vm
->def
))) {
2779 virReportError(VIR_ERR_OVERFLOW
, "%s", _("cpu count too large"));
2786 virDomainObjEndAPI(&vm
);
2791 qemuDomainGetState(virDomainPtr dom
,
2799 virCheckFlags(0, -1);
2801 if (!(vm
= qemuDomObjFromDomain(dom
)))
2804 if (virDomainGetStateEnsureACL(dom
->conn
, vm
->def
) < 0)
2807 *state
= virDomainObjGetState(vm
, reason
);
2811 virDomainObjEndAPI(&vm
);
2816 qemuDomainGetControlInfo(virDomainPtr dom
,
2817 virDomainControlInfoPtr info
,
2821 qemuDomainObjPrivatePtr priv
;
2824 virCheckFlags(0, -1);
2826 if (!(vm
= qemuDomObjFromDomain(dom
)))
2829 if (virDomainGetControlInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
2832 if (virDomainObjCheckActive(vm
) < 0)
2835 priv
= vm
->privateData
;
2837 memset(info
, 0, sizeof(*info
));
2839 if (priv
->monError
) {
2840 info
->state
= VIR_DOMAIN_CONTROL_ERROR
;
2841 info
->details
= VIR_DOMAIN_CONTROL_ERROR_REASON_MONITOR
;
2842 } else if (priv
->job
.active
) {
2843 if (virTimeMillisNow(&info
->stateTime
) < 0)
2845 if (priv
->job
.current
) {
2846 info
->state
= VIR_DOMAIN_CONTROL_JOB
;
2847 info
->stateTime
-= priv
->job
.current
->started
;
2849 if (priv
->monStart
> 0) {
2850 info
->state
= VIR_DOMAIN_CONTROL_OCCUPIED
;
2851 info
->stateTime
-= priv
->monStart
;
2853 /* At this point the domain has an active job, but monitor was
2854 * not entered and the domain object lock is not held thus we
2855 * are stuck in the job forever due to a programming error.
2857 info
->state
= VIR_DOMAIN_CONTROL_ERROR
;
2858 info
->details
= VIR_DOMAIN_CONTROL_ERROR_REASON_INTERNAL
;
2859 info
->stateTime
= 0;
2863 info
->state
= VIR_DOMAIN_CONTROL_OK
;
2869 virDomainObjEndAPI(&vm
);
2874 /* It would be nice to replace 'Qemud' with 'Qemu' but
2875 * this magic string is ABI, so it can't be changed
2877 #define QEMU_SAVE_MAGIC "LibvirtQemudSave"
2878 #define QEMU_SAVE_PARTIAL "LibvirtQemudPart"
2879 #define QEMU_SAVE_VERSION 2
2881 verify(sizeof(QEMU_SAVE_MAGIC
) == sizeof(QEMU_SAVE_PARTIAL
));
2884 QEMU_SAVE_FORMAT_RAW
= 0,
2885 QEMU_SAVE_FORMAT_GZIP
= 1,
2886 QEMU_SAVE_FORMAT_BZIP2
= 2,
2888 * Deprecated by xz and never used as part of a release
2889 * QEMU_SAVE_FORMAT_LZMA
2891 QEMU_SAVE_FORMAT_XZ
= 3,
2892 QEMU_SAVE_FORMAT_LZOP
= 4,
2893 /* Note: add new members only at the end.
2894 These values are used in the on-disk format.
2895 Do not change or re-use numbers. */
2897 QEMU_SAVE_FORMAT_LAST
2898 } virQEMUSaveFormat
;
2900 VIR_ENUM_DECL(qemuSaveCompression
);
2901 VIR_ENUM_IMPL(qemuSaveCompression
, QEMU_SAVE_FORMAT_LAST
,
2909 VIR_ENUM_DECL(qemuDumpFormat
);
2910 VIR_ENUM_IMPL(qemuDumpFormat
, VIR_DOMAIN_CORE_DUMP_FORMAT_LAST
,
2917 typedef struct _virQEMUSaveHeader virQEMUSaveHeader
;
2918 typedef virQEMUSaveHeader
*virQEMUSaveHeaderPtr
;
2919 struct _virQEMUSaveHeader
{
2920 char magic
[sizeof(QEMU_SAVE_MAGIC
)-1];
2923 uint32_t was_running
;
2924 uint32_t compressed
;
2925 uint32_t cookieOffset
;
2926 uint32_t unused
[14];
2929 typedef struct _virQEMUSaveData virQEMUSaveData
;
2930 typedef virQEMUSaveData
*virQEMUSaveDataPtr
;
2931 struct _virQEMUSaveData
{
2932 virQEMUSaveHeader header
;
2939 bswap_header(virQEMUSaveHeaderPtr hdr
)
2941 hdr
->version
= bswap_32(hdr
->version
);
2942 hdr
->data_len
= bswap_32(hdr
->data_len
);
2943 hdr
->was_running
= bswap_32(hdr
->was_running
);
2944 hdr
->compressed
= bswap_32(hdr
->compressed
);
2945 hdr
->cookieOffset
= bswap_32(hdr
->cookieOffset
);
2950 virQEMUSaveDataFree(virQEMUSaveDataPtr data
)
2955 VIR_FREE(data
->xml
);
2956 VIR_FREE(data
->cookie
);
2962 * This function steals @domXML on success.
2964 static virQEMUSaveDataPtr
2965 virQEMUSaveDataNew(char *domXML
,
2966 qemuDomainSaveCookiePtr cookieObj
,
2969 virDomainXMLOptionPtr xmlopt
)
2971 virQEMUSaveDataPtr data
= NULL
;
2972 virQEMUSaveHeaderPtr header
;
2974 if (VIR_ALLOC(data
) < 0)
2977 VIR_STEAL_PTR(data
->xml
, domXML
);
2980 !(data
->cookie
= virSaveCookieFormat((virObjectPtr
) cookieObj
,
2981 virDomainXMLOptionGetSaveCookie(xmlopt
))))
2984 header
= &data
->header
;
2985 memcpy(header
->magic
, QEMU_SAVE_PARTIAL
, sizeof(header
->magic
));
2986 header
->version
= QEMU_SAVE_VERSION
;
2987 header
->was_running
= running
? 1 : 0;
2988 header
->compressed
= compressed
;
2993 virQEMUSaveDataFree(data
);
2998 /* virQEMUSaveDataWrite:
3000 * Writes libvirt's header (including domain XML) into a saved image of a
3001 * running domain. If @header has data_len filled in (because it was previously
3002 * read from the file), the function will make sure the new data will fit
3005 * Returns -1 on failure, or 0 on success.
3008 virQEMUSaveDataWrite(virQEMUSaveDataPtr data
,
3012 virQEMUSaveHeaderPtr header
= &data
->header
;
3015 size_t cookie_len
= 0;
3017 size_t zerosLen
= 0;
3020 xml_len
= strlen(data
->xml
) + 1;
3022 cookie_len
= strlen(data
->cookie
) + 1;
3024 len
= xml_len
+ cookie_len
;
3026 if (header
->data_len
> 0) {
3027 if (len
> header
->data_len
) {
3028 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
3029 _("new xml too large to fit in file"));
3033 zerosLen
= header
->data_len
- len
;
3034 if (VIR_ALLOC_N(zeros
, zerosLen
) < 0)
3037 header
->data_len
= len
;
3041 header
->cookieOffset
= xml_len
;
3043 if (safewrite(fd
, header
, sizeof(*header
)) != sizeof(*header
)) {
3044 virReportSystemError(errno
,
3045 _("failed to write header to domain save file '%s'"),
3050 if (safewrite(fd
, data
->xml
, xml_len
) != xml_len
) {
3051 virReportSystemError(errno
,
3052 _("failed to write domain xml to '%s'"),
3058 safewrite(fd
, data
->cookie
, cookie_len
) != cookie_len
) {
3059 virReportSystemError(errno
,
3060 _("failed to write cookie to '%s'"),
3065 if (safewrite(fd
, zeros
, zerosLen
) != zerosLen
) {
3066 virReportSystemError(errno
,
3067 _("failed to write padding to '%s'"),
3081 virQEMUSaveDataFinish(virQEMUSaveDataPtr data
,
3085 virQEMUSaveHeaderPtr header
= &data
->header
;
3087 memcpy(header
->magic
, QEMU_SAVE_MAGIC
, sizeof(header
->magic
));
3089 if (safewrite(*fd
, header
, sizeof(*header
)) != sizeof(*header
) ||
3090 VIR_CLOSE(*fd
) < 0) {
3091 virReportSystemError(errno
,
3092 _("failed to write header to domain save file '%s'"),
3101 static virCommandPtr
3102 qemuCompressGetCommand(virQEMUSaveFormat compression
)
3104 virCommandPtr ret
= NULL
;
3105 const char *prog
= qemuSaveCompressionTypeToString(compression
);
3108 virReportError(VIR_ERR_OPERATION_FAILED
,
3109 _("Invalid compressed save format %d"),
3114 ret
= virCommandNew(prog
);
3115 virCommandAddArg(ret
, "-dc");
3117 if (compression
== QEMU_SAVE_FORMAT_LZOP
)
3118 virCommandAddArg(ret
, "--ignore-warn");
3125 * @driver: driver object
3126 * @vm: domain object
3127 * @path: path to file to open
3128 * @oflags: flags for opening/creation of the file
3129 * @needUnlink: set to true if file was created by this function
3131 * Internal function to properly create or open existing files, with
3132 * ownership affected by qemu driver setup and domain DAC label.
3134 * Returns the file descriptor on success and negative errno on failure.
3136 * This function should not be used on storage sources. Use
3137 * qemuDomainStorageFileInit and storage driver APIs if possible.
3140 qemuOpenFile(virQEMUDriverPtr driver
,
3147 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
3148 uid_t user
= cfg
->user
;
3149 gid_t group
= cfg
->group
;
3150 bool dynamicOwnership
= cfg
->dynamicOwnership
;
3151 virSecurityLabelDefPtr seclabel
;
3153 virObjectUnref(cfg
);
3155 /* TODO: Take imagelabel into account? */
3157 (seclabel
= virDomainDefGetSecurityLabelDef(vm
->def
, "dac")) != NULL
&&
3158 seclabel
->label
!= NULL
&&
3159 (virParseOwnershipIds(seclabel
->label
, &user
, &group
) < 0))
3162 ret
= qemuOpenFileAs(user
, group
, dynamicOwnership
,
3163 path
, oflags
, needUnlink
);
3170 qemuOpenFileAs(uid_t fallback_uid
, gid_t fallback_gid
,
3171 bool dynamicOwnership
,
3172 const char *path
, int oflags
,
3177 bool need_unlink
= false;
3178 unsigned int vfoflags
= 0;
3180 int path_shared
= virFileIsSharedFS(path
);
3181 uid_t uid
= geteuid();
3182 gid_t gid
= getegid();
3184 /* path might be a pre-existing block dev, in which case
3185 * we need to skip the create step, and also avoid unlink
3186 * in the failure case */
3187 if (oflags
& O_CREAT
) {
3190 /* Don't force chown on network-shared FS
3191 * as it is likely to fail. */
3192 if (path_shared
<= 0 || dynamicOwnership
)
3193 vfoflags
|= VIR_FILE_OPEN_FORCE_OWNER
;
3195 if (stat(path
, &sb
) == 0) {
3196 /* It already exists, we don't want to delete it on error */
3197 need_unlink
= false;
3199 is_reg
= !!S_ISREG(sb
.st_mode
);
3200 /* If the path is regular file which exists
3201 * already and dynamic_ownership is off, we don't
3202 * want to change its ownership, just open it as-is */
3203 if (is_reg
&& !dynamicOwnership
) {
3210 /* First try creating the file as root */
3212 if ((fd
= open(path
, oflags
& ~O_CREAT
)) < 0) {
3217 if ((fd
= virFileOpenAs(path
, oflags
, S_IRUSR
| S_IWUSR
, uid
, gid
,
3218 vfoflags
| VIR_FILE_OPEN_NOFORK
)) < 0) {
3219 /* If we failed as root, and the error was permission-denied
3220 (EACCES or EPERM), assume it's on a network-connected share
3221 where root access is restricted (eg, root-squashed NFS). If the
3222 qemu user is non-root, just set a flag to
3223 bypass security driver shenanigans, and retry the operation
3224 after doing setuid to qemu user */
3225 if ((fd
!= -EACCES
&& fd
!= -EPERM
) || fallback_uid
== geteuid())
3228 /* On Linux we can also verify the FS-type of the directory. */
3229 switch (path_shared
) {
3231 /* it was on a network share, so we'll continue
3237 virReportSystemError(-fd
, oflags
& O_CREAT
3238 ? _("Failed to create file "
3239 "'%s': couldn't determine fs type")
3240 : _("Failed to open file "
3241 "'%s': couldn't determine fs type"),
3247 /* local file - log the error returned by virFileOpenAs */
3251 /* If we created the file above, then we need to remove it;
3252 * otherwise, the next attempt to create will fail. If the
3253 * file had already existed before we got here, then we also
3254 * don't want to delete it and allow the following to succeed
3255 * or fail based on existing protections
3260 /* Retry creating the file as qemu user */
3262 /* Since we're passing different modes... */
3263 vfoflags
|= VIR_FILE_OPEN_FORCE_MODE
;
3265 if ((fd
= virFileOpenAs(path
, oflags
,
3266 S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IWGRP
,
3267 fallback_uid
, fallback_gid
,
3268 vfoflags
| VIR_FILE_OPEN_FORK
)) < 0) {
3269 virReportSystemError(-fd
, oflags
& O_CREAT
3270 ? _("Error from child process creating '%s'")
3271 : _("Error from child process opening '%s'"),
3279 *needUnlink
= need_unlink
;
3283 virReportSystemError(-fd
, oflags
& O_CREAT
3284 ? _("Failed to create file '%s'")
3285 : _("Failed to open file '%s'"),
3292 qemuFileWrapperFDClose(virDomainObjPtr vm
,
3293 virFileWrapperFdPtr fd
)
3297 /* virFileWrapperFd uses iohelper to write data onto disk.
3298 * However, iohelper calls fdatasync() which may take ages to
3299 * finish. Therefore, we shouldn't be waiting with the domain
3302 /* XXX Currently, this function is intended for *Save() only
3303 * as restore needs some reworking before it's ready for
3306 virObjectUnlock(vm
);
3307 ret
= virFileWrapperFdClose(fd
);
3309 if (!virDomainObjIsActive(vm
)) {
3310 if (virGetLastErrorCode() == VIR_ERR_OK
)
3311 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
3312 _("domain is no longer running"));
3319 /* Helper function to execute a migration to file with a correct save header
3320 * the caller needs to make sure that the processors are stopped and do all other
3321 * actions besides saving memory */
3323 qemuDomainSaveMemory(virQEMUDriverPtr driver
,
3326 virQEMUSaveDataPtr data
,
3327 const char *compressedpath
,
3329 qemuDomainAsyncJob asyncJob
)
3331 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
3332 bool needUnlink
= false;
3336 virFileWrapperFdPtr wrapperFd
= NULL
;
3337 unsigned int wrapperFlags
= VIR_FILE_WRAPPER_NON_BLOCKING
;
3339 /* Obtain the file handle. */
3340 if ((flags
& VIR_DOMAIN_SAVE_BYPASS_CACHE
)) {
3341 wrapperFlags
|= VIR_FILE_WRAPPER_BYPASS_CACHE
;
3342 directFlag
= virFileDirectFdFlag();
3343 if (directFlag
< 0) {
3344 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
3345 _("bypass cache unsupported by this system"));
3350 fd
= qemuOpenFileAs(cfg
->user
, cfg
->group
, false, path
,
3351 O_WRONLY
| O_TRUNC
| O_CREAT
| directFlag
,
3356 if (qemuSecuritySetImageFDLabel(driver
->securityManager
, vm
->def
, fd
) < 0)
3359 if (!(wrapperFd
= virFileWrapperFdNew(&fd
, path
, wrapperFlags
)))
3362 if (virQEMUSaveDataWrite(data
, fd
, path
) < 0)
3365 /* Perform the migration */
3366 if (qemuMigrationSrcToFile(driver
, vm
, fd
, compressedpath
, asyncJob
) < 0)
3369 /* Touch up file header to mark image complete. */
3371 /* Reopen the file to touch up the header, since we aren't set
3372 * up to seek backwards on wrapperFd. The reopened fd will
3373 * trigger a single page of file system cache pollution, but
3374 * that's acceptable. */
3375 if (VIR_CLOSE(fd
) < 0) {
3376 virReportSystemError(errno
, _("unable to close %s"), path
);
3380 if (qemuFileWrapperFDClose(vm
, wrapperFd
) < 0)
3383 if ((fd
= qemuOpenFile(driver
, vm
, path
, O_WRONLY
, NULL
)) < 0 ||
3384 virQEMUSaveDataFinish(data
, &fd
, path
) < 0)
3390 VIR_FORCE_CLOSE(fd
);
3391 if (qemuFileWrapperFDClose(vm
, wrapperFd
) < 0)
3393 virFileWrapperFdFree(wrapperFd
);
3394 virObjectUnref(cfg
);
3396 if (ret
< 0 && needUnlink
)
3402 /* The vm must be active + locked. Vm will be unlocked and
3403 * potentially free'd after this returns (eg transient VMs are freed
3404 * shutdown). So 'vm' must not be referenced by the caller after
3405 * this returns (whether returning success or failure).
3408 qemuDomainSaveInternal(virQEMUDriverPtr driver
,
3409 virDomainObjPtr vm
, const char *path
,
3410 int compressed
, const char *compressedpath
,
3411 const char *xmlin
, unsigned int flags
)
3414 bool was_running
= false;
3416 virObjectEventPtr event
= NULL
;
3417 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
3419 virQEMUSaveDataPtr data
= NULL
;
3420 qemuDomainSaveCookiePtr cookie
= NULL
;
3422 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
3425 if (!qemuMigrationSrcIsAllowed(driver
, vm
, false, 0))
3428 if (qemuDomainObjBeginAsyncJob(driver
, vm
, QEMU_ASYNC_JOB_SAVE
,
3429 VIR_DOMAIN_JOB_OPERATION_SAVE
, flags
) < 0)
3432 if (!virDomainObjIsActive(vm
)) {
3433 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
3434 _("guest unexpectedly quit"));
3438 priv
->job
.current
->statsType
= QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP
;
3441 if (virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
) {
3443 if (qemuProcessStopCPUs(driver
, vm
, VIR_DOMAIN_PAUSED_SAVE
,
3444 QEMU_ASYNC_JOB_SAVE
) < 0)
3447 if (!virDomainObjIsActive(vm
)) {
3448 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
3449 _("guest unexpectedly quit"));
3454 /* libvirt-domain.c already guaranteed these two flags are exclusive. */
3455 if (flags
& VIR_DOMAIN_SAVE_RUNNING
)
3457 else if (flags
& VIR_DOMAIN_SAVE_PAUSED
)
3458 was_running
= false;
3460 /* Get XML for the domain. Restore needs only the inactive xml,
3461 * including secure. We should get the same result whether xmlin
3462 * is NULL or whether it was the live xml of the domain moments
3465 virDomainDefPtr def
= NULL
;
3467 if (!(def
= virDomainDefParseString(xmlin
, caps
, driver
->xmlopt
, NULL
,
3468 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
3469 VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
))) {
3472 if (!qemuDomainCheckABIStability(driver
, vm
, def
)) {
3473 virDomainDefFree(def
);
3476 xml
= qemuDomainDefFormatLive(driver
, def
, NULL
, true, true);
3478 xml
= qemuDomainDefFormatLive(driver
, vm
->def
, priv
->origCPU
, true, true);
3481 virReportError(VIR_ERR_OPERATION_FAILED
,
3482 "%s", _("failed to get domain xml"));
3486 if (!(cookie
= qemuDomainSaveCookieNew(vm
)))
3489 if (!(data
= virQEMUSaveDataNew(xml
, cookie
, was_running
, compressed
,
3494 ret
= qemuDomainSaveMemory(driver
, vm
, path
, data
, compressedpath
,
3495 flags
, QEMU_ASYNC_JOB_SAVE
);
3500 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_SAVED
,
3501 QEMU_ASYNC_JOB_SAVE
, 0);
3502 virDomainAuditStop(vm
, "saved");
3503 event
= virDomainEventLifecycleNewFromObj(vm
, VIR_DOMAIN_EVENT_STOPPED
,
3504 VIR_DOMAIN_EVENT_STOPPED_SAVED
);
3507 if (was_running
&& virDomainObjIsActive(vm
)) {
3508 virErrorPtr save_err
= virSaveLastError();
3509 if (qemuProcessStartCPUs(driver
, vm
,
3510 VIR_DOMAIN_RUNNING_SAVE_CANCELED
,
3511 QEMU_ASYNC_JOB_SAVE
) < 0) {
3512 VIR_WARN("Unable to resume guest CPUs after save failure");
3513 virObjectEventStateQueue(driver
->domainEventState
,
3514 virDomainEventLifecycleNewFromObj(vm
,
3515 VIR_DOMAIN_EVENT_SUSPENDED
,
3516 VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR
));
3518 virSetError(save_err
);
3519 virFreeError(save_err
);
3522 qemuDomainObjEndAsyncJob(driver
, vm
);
3524 qemuDomainRemoveInactiveJob(driver
, vm
);
3527 virObjectUnref(cookie
);
3529 virQEMUSaveDataFree(data
);
3530 virObjectEventStateQueue(driver
->domainEventState
, event
);
3531 virObjectUnref(caps
);
3536 /* qemuGetCompressionProgram:
3537 * @imageFormat: String representation from qemu.conf for the compression
3538 * image format being used (dump, save, or snapshot).
3539 * @compresspath: Pointer to a character string to store the fully qualified
3540 * path from virFindFileInPath.
3541 * @styleFormat: String representing the style of format (dump, save, snapshot)
3542 * @use_raw_on_fail: Boolean indicating how to handle the error path. For
3543 * callers that are OK with invalid data or inability to
3544 * find the compression program, just return a raw format
3545 * and let the path remain as NULL.
3548 * virQEMUSaveFormat - Integer representation of the compression
3549 * program to be used for particular style
3550 * (e.g. dump, save, or snapshot).
3551 * QEMU_SAVE_FORMAT_RAW - If there is no qemu.conf imageFormat value or
3552 * no there was an error, then just return RAW
3555 static int ATTRIBUTE_NONNULL(2)
3556 qemuGetCompressionProgram(const char *imageFormat
,
3557 char **compresspath
,
3558 const char *styleFormat
,
3559 bool use_raw_on_fail
)
3563 *compresspath
= NULL
;
3566 return QEMU_SAVE_FORMAT_RAW
;
3568 if ((ret
= qemuSaveCompressionTypeFromString(imageFormat
)) < 0)
3571 if (ret
== QEMU_SAVE_FORMAT_RAW
)
3572 return QEMU_SAVE_FORMAT_RAW
;
3574 if (!(*compresspath
= virFindFileInPath(imageFormat
)))
3581 if (use_raw_on_fail
)
3582 VIR_WARN("Invalid %s image format specified in "
3583 "configuration file, using raw",
3586 virReportError(VIR_ERR_OPERATION_FAILED
,
3587 _("Invalid %s image format specified "
3588 "in configuration file"),
3591 if (use_raw_on_fail
)
3592 VIR_WARN("Compression program for %s image format in "
3593 "configuration file isn't available, using raw",
3596 virReportError(VIR_ERR_OPERATION_FAILED
,
3597 _("Compression program for %s image format "
3598 "in configuration file isn't available"),
3602 /* Use "raw" as the format if the specified format is not valid,
3603 * or the compress program is not available. */
3604 if (use_raw_on_fail
)
3605 return QEMU_SAVE_FORMAT_RAW
;
3612 qemuDomainSaveFlags(virDomainPtr dom
, const char *path
, const char *dxml
,
3615 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
3617 char *compressedpath
= NULL
;
3619 virDomainObjPtr vm
= NULL
;
3620 virQEMUDriverConfigPtr cfg
= NULL
;
3622 virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE
|
3623 VIR_DOMAIN_SAVE_RUNNING
|
3624 VIR_DOMAIN_SAVE_PAUSED
, -1);
3626 cfg
= virQEMUDriverGetConfig(driver
);
3627 if ((compressed
= qemuGetCompressionProgram(cfg
->saveImageFormat
,
3629 "save", false)) < 0)
3632 if (!(vm
= qemuDomObjFromDomain(dom
)))
3635 if (virDomainSaveFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
3638 if (virDomainObjCheckActive(vm
) < 0)
3641 ret
= qemuDomainSaveInternal(driver
, vm
, path
, compressed
,
3642 compressedpath
, dxml
, flags
);
3645 virDomainObjEndAPI(&vm
);
3646 VIR_FREE(compressedpath
);
3647 virObjectUnref(cfg
);
3652 qemuDomainSave(virDomainPtr dom
, const char *path
)
3654 return qemuDomainSaveFlags(dom
, path
, NULL
, 0);
3658 qemuDomainManagedSavePath(virQEMUDriverPtr driver
, virDomainObjPtr vm
)
3661 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
3663 if (virAsprintf(&ret
, "%s/%s.save", cfg
->saveDir
, vm
->def
->name
) < 0) {
3664 virObjectUnref(cfg
);
3668 virObjectUnref(cfg
);
3673 qemuDomainManagedSave(virDomainPtr dom
, unsigned int flags
)
3675 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
3676 virQEMUDriverConfigPtr cfg
= NULL
;
3678 char *compressedpath
= NULL
;
3683 virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE
|
3684 VIR_DOMAIN_SAVE_RUNNING
|
3685 VIR_DOMAIN_SAVE_PAUSED
, -1);
3687 if (!(vm
= qemuDomObjFromDomain(dom
)))
3690 if (virDomainManagedSaveEnsureACL(dom
->conn
, vm
->def
) < 0)
3693 if (virDomainObjCheckActive(vm
) < 0)
3696 if (!vm
->persistent
) {
3697 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
3698 _("cannot do managed save for transient domain"));
3702 cfg
= virQEMUDriverGetConfig(driver
);
3703 if ((compressed
= qemuGetCompressionProgram(cfg
->saveImageFormat
,
3705 "save", false)) < 0)
3708 if (!(name
= qemuDomainManagedSavePath(driver
, vm
)))
3711 VIR_INFO("Saving state of domain '%s' to '%s'", vm
->def
->name
, name
);
3713 ret
= qemuDomainSaveInternal(driver
, vm
, name
, compressed
,
3714 compressedpath
, NULL
, flags
);
3716 vm
->hasManagedSave
= true;
3719 virDomainObjEndAPI(&vm
);
3721 VIR_FREE(compressedpath
);
3722 virObjectUnref(cfg
);
3728 qemuDomainManagedSaveLoad(virDomainObjPtr vm
,
3731 virQEMUDriverPtr driver
= opaque
;
3737 if (!(name
= qemuDomainManagedSavePath(driver
, vm
)))
3740 vm
->hasManagedSave
= virFileExists(name
);
3744 virObjectUnlock(vm
);
3751 qemuDomainHasManagedSaveImage(virDomainPtr dom
, unsigned int flags
)
3753 virDomainObjPtr vm
= NULL
;
3756 virCheckFlags(0, -1);
3758 if (!(vm
= qemuDomObjFromDomain(dom
)))
3761 if (virDomainHasManagedSaveImageEnsureACL(dom
->conn
, vm
->def
) < 0)
3764 ret
= vm
->hasManagedSave
;
3767 virDomainObjEndAPI(&vm
);
3772 qemuDomainManagedSaveRemove(virDomainPtr dom
, unsigned int flags
)
3774 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
3779 virCheckFlags(0, -1);
3781 if (!(vm
= qemuDomObjFromDomain(dom
)))
3784 if (virDomainManagedSaveRemoveEnsureACL(dom
->conn
, vm
->def
) < 0)
3787 if (!(name
= qemuDomainManagedSavePath(driver
, vm
)))
3790 if (unlink(name
) < 0) {
3791 virReportSystemError(errno
,
3792 _("Failed to remove managed save file '%s'"),
3797 vm
->hasManagedSave
= false;
3802 virDomainObjEndAPI(&vm
);
3808 * qemuDumpWaitForCompletion:
3809 * @vm: domain object
3811 * If the query dump capability exists, then it's possible to start a
3812 * guest memory dump operation using a thread via a 'detach' qualifier
3813 * to the dump guest memory command. This allows the async check if the
3816 * Returns 0 on success, -1 on failure
3819 qemuDumpWaitForCompletion(virDomainObjPtr vm
)
3821 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
3824 VIR_DEBUG("Waiting for dump completion");
3825 while (!priv
->job
.dumpCompleted
&& !priv
->job
.abortJob
) {
3826 if (virDomainObjWait(vm
) < 0)
3830 if (priv
->job
.current
->stats
.dump
.status
== QEMU_MONITOR_DUMP_STATUS_FAILED
) {
3831 if (priv
->job
.error
)
3832 virReportError(VIR_ERR_OPERATION_FAILED
,
3833 _("memory-only dump failed: %s"),
3836 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
3837 _("memory-only dump failed for unknown reason"));
3841 qemuDomainJobInfoUpdateTime(priv
->job
.current
);
3851 qemuDumpToFd(virQEMUDriverPtr driver
,
3854 qemuDomainAsyncJob asyncJob
,
3855 const char *dumpformat
)
3857 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
3858 bool detach
= false;
3861 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DUMP_GUEST_MEMORY
)) {
3862 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
3863 _("dump-guest-memory is not supported"));
3867 detach
= virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DUMP_COMPLETED
);
3869 if (qemuSecuritySetImageFDLabel(driver
->securityManager
, vm
->def
, fd
) < 0)
3873 priv
->job
.current
->statsType
= QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP
;
3875 VIR_FREE(priv
->job
.current
);
3877 if (qemuDomainObjEnterMonitorAsync(driver
, vm
, asyncJob
) < 0)
3881 ret
= qemuMonitorGetDumpGuestMemoryCapability(priv
->mon
, dumpformat
);
3884 virReportError(VIR_ERR_INVALID_ARG
,
3885 _("unsupported dumpformat '%s' "
3886 "for this QEMU binary"),
3889 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
3894 ret
= qemuMonitorDumpToFd(priv
->mon
, fd
, dumpformat
, detach
);
3896 if ((qemuDomainObjExitMonitor(driver
, vm
) < 0) || ret
< 0)
3900 ret
= qemuDumpWaitForCompletion(vm
);
3908 doCoreDump(virQEMUDriverPtr driver
,
3911 unsigned int dump_flags
,
3912 unsigned int dumpformat
)
3916 virFileWrapperFdPtr wrapperFd
= NULL
;
3918 unsigned int flags
= VIR_FILE_WRAPPER_NON_BLOCKING
;
3919 const char *memory_dump_format
= NULL
;
3920 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
3921 char *compressedpath
= NULL
;
3923 /* We reuse "save" flag for "dump" here. Then, we can support the same
3924 * format in "save" and "dump". This path doesn't need the compression
3925 * program to exist and can ignore the return value - it only cares to
3926 * get the compressedpath */
3927 ignore_value(qemuGetCompressionProgram(cfg
->dumpImageFormat
,
3931 /* Create an empty file with appropriate ownership. */
3932 if (dump_flags
& VIR_DUMP_BYPASS_CACHE
) {
3933 flags
|= VIR_FILE_WRAPPER_BYPASS_CACHE
;
3934 directFlag
= virFileDirectFdFlag();
3935 if (directFlag
< 0) {
3936 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
3937 _("bypass cache unsupported by this system"));
3941 /* Core dumps usually imply last-ditch analysis efforts are
3942 * desired, so we intentionally do not unlink even if a file was
3944 if ((fd
= qemuOpenFileAs(cfg
->user
, cfg
->group
, false, path
,
3945 O_CREAT
| O_TRUNC
| O_WRONLY
| directFlag
,
3949 if (!(wrapperFd
= virFileWrapperFdNew(&fd
, path
, flags
)))
3952 if (dump_flags
& VIR_DUMP_MEMORY_ONLY
) {
3953 if (!(memory_dump_format
= qemuDumpFormatTypeToString(dumpformat
))) {
3954 virReportError(VIR_ERR_INVALID_ARG
,
3955 _("unknown dumpformat '%d'"), dumpformat
);
3959 /* qemu dumps in "elf" without dumpformat set */
3960 if (STREQ(memory_dump_format
, "elf"))
3961 memory_dump_format
= NULL
;
3963 ret
= qemuDumpToFd(driver
, vm
, fd
, QEMU_ASYNC_JOB_DUMP
,
3964 memory_dump_format
);
3966 if (dumpformat
!= VIR_DOMAIN_CORE_DUMP_FORMAT_RAW
) {
3967 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
3968 _("kdump-compressed format is only supported with "
3969 "memory-only dump"));
3973 if (!qemuMigrationSrcIsAllowed(driver
, vm
, false, 0))
3976 ret
= qemuMigrationSrcToFile(driver
, vm
, fd
, compressedpath
,
3977 QEMU_ASYNC_JOB_DUMP
);
3983 if (VIR_CLOSE(fd
) < 0) {
3984 virReportSystemError(errno
,
3985 _("unable to close file %s"),
3989 if (qemuFileWrapperFDClose(vm
, wrapperFd
) < 0)
3995 VIR_FORCE_CLOSE(fd
);
3996 if (qemuFileWrapperFDClose(vm
, wrapperFd
) < 0)
3998 virFileWrapperFdFree(wrapperFd
);
4001 VIR_FREE(compressedpath
);
4002 virObjectUnref(cfg
);
4008 qemuDomainCoreDumpWithFormat(virDomainPtr dom
,
4010 unsigned int dumpformat
,
4013 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
4015 qemuDomainObjPrivatePtr priv
= NULL
;
4016 bool resume
= false, paused
= false;
4018 virObjectEventPtr event
= NULL
;
4020 virCheckFlags(VIR_DUMP_LIVE
| VIR_DUMP_CRASH
|
4021 VIR_DUMP_BYPASS_CACHE
| VIR_DUMP_RESET
|
4022 VIR_DUMP_MEMORY_ONLY
, -1);
4024 if (!(vm
= qemuDomObjFromDomain(dom
)))
4027 if (virDomainCoreDumpWithFormatEnsureACL(dom
->conn
, vm
->def
) < 0)
4030 if (qemuDomainObjBeginAsyncJob(driver
, vm
,
4031 QEMU_ASYNC_JOB_DUMP
,
4032 VIR_DOMAIN_JOB_OPERATION_DUMP
,
4036 if (virDomainObjCheckActive(vm
) < 0)
4039 priv
= vm
->privateData
;
4040 priv
->job
.current
->statsType
= QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP
;
4042 /* Migrate will always stop the VM, so the resume condition is
4043 independent of whether the stop command is issued. */
4044 resume
= virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
;
4046 /* Pause domain for non-live dump */
4047 if (!(flags
& VIR_DUMP_LIVE
) &&
4048 virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
) {
4049 if (qemuProcessStopCPUs(driver
, vm
, VIR_DOMAIN_PAUSED_DUMP
,
4050 QEMU_ASYNC_JOB_DUMP
) < 0)
4054 if (!virDomainObjIsActive(vm
)) {
4055 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
4056 _("guest unexpectedly quit"));
4061 if ((ret
= doCoreDump(driver
, vm
, path
, flags
, dumpformat
)) < 0)
4067 if ((ret
== 0) && (flags
& VIR_DUMP_CRASH
)) {
4068 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_CRASHED
,
4069 QEMU_ASYNC_JOB_DUMP
, 0);
4070 virDomainAuditStop(vm
, "crashed");
4071 event
= virDomainEventLifecycleNewFromObj(vm
,
4072 VIR_DOMAIN_EVENT_STOPPED
,
4073 VIR_DOMAIN_EVENT_STOPPED_CRASHED
);
4074 } else if (((resume
&& paused
) || (flags
& VIR_DUMP_RESET
)) &&
4075 virDomainObjIsActive(vm
)) {
4076 if ((ret
== 0) && (flags
& VIR_DUMP_RESET
)) {
4077 qemuDomainObjEnterMonitor(driver
, vm
);
4078 ret
= qemuMonitorSystemReset(priv
->mon
);
4079 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
4083 if (resume
&& virDomainObjIsActive(vm
)) {
4084 if (qemuProcessStartCPUs(driver
, vm
,
4085 VIR_DOMAIN_RUNNING_UNPAUSED
,
4086 QEMU_ASYNC_JOB_DUMP
) < 0) {
4087 event
= virDomainEventLifecycleNewFromObj(vm
,
4088 VIR_DOMAIN_EVENT_SUSPENDED
,
4089 VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR
);
4090 if (virGetLastErrorCode() == VIR_ERR_OK
)
4091 virReportError(VIR_ERR_OPERATION_FAILED
,
4092 "%s", _("resuming after dump failed"));
4097 qemuDomainObjEndAsyncJob(driver
, vm
);
4098 if (ret
== 0 && flags
& VIR_DUMP_CRASH
)
4099 qemuDomainRemoveInactiveJob(driver
, vm
);
4102 virDomainObjEndAPI(&vm
);
4103 virObjectEventStateQueue(driver
->domainEventState
, event
);
4109 qemuDomainCoreDump(virDomainPtr dom
,
4113 return qemuDomainCoreDumpWithFormat(dom
, path
,
4114 VIR_DOMAIN_CORE_DUMP_FORMAT_RAW
,
4120 qemuDomainScreenshot(virDomainPtr dom
,
4122 unsigned int screen
,
4125 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
4127 qemuDomainObjPrivatePtr priv
;
4131 const char *videoAlias
= NULL
;
4133 bool unlink_tmp
= false;
4134 virQEMUDriverConfigPtr cfg
= NULL
;
4136 virCheckFlags(0, NULL
);
4138 if (!(vm
= qemuDomObjFromDomain(dom
)))
4141 priv
= vm
->privateData
;
4142 cfg
= virQEMUDriverGetConfig(driver
);
4144 if (virDomainScreenshotEnsureACL(dom
->conn
, vm
->def
) < 0)
4147 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
4150 if (virDomainObjCheckActive(vm
) < 0)
4153 if (!vm
->def
->nvideos
) {
4154 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
4155 _("no screens to take screenshot from"));
4160 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_SCREENDUMP_DEVICE
)) {
4161 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
4162 _("qemu does not allow specifying screen ID"));
4166 for (i
= 0; i
< vm
->def
->nvideos
; i
++) {
4167 const virDomainVideoDef
*video
= vm
->def
->videos
[i
];
4169 if (screen
< video
->heads
) {
4170 videoAlias
= video
->info
.alias
;
4174 screen
-= video
->heads
;
4177 if (i
== vm
->def
->nvideos
) {
4178 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
4179 _("no such screen ID"));
4184 if (virAsprintf(&tmp
, "%s/qemu.screendump.XXXXXX", cfg
->cacheDir
) < 0)
4187 if ((tmp_fd
= mkostemp(tmp
, O_CLOEXEC
)) == -1) {
4188 virReportSystemError(errno
, _("mkostemp(\"%s\") failed"), tmp
);
4193 qemuSecuritySetSavedStateLabel(driver
, vm
, tmp
);
4195 qemuDomainObjEnterMonitor(driver
, vm
);
4196 if (qemuMonitorScreendump(priv
->mon
, videoAlias
, screen
, tmp
) < 0) {
4197 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
4200 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
4203 if (VIR_CLOSE(tmp_fd
) < 0) {
4204 virReportSystemError(errno
, _("unable to close %s"), tmp
);
4208 if (virFDStreamOpenFile(st
, tmp
, 0, 0, O_RDONLY
) < 0) {
4209 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
4210 _("unable to open stream"));
4214 ignore_value(VIR_STRDUP(ret
, "image/x-portable-pixmap"));
4217 VIR_FORCE_CLOSE(tmp_fd
);
4222 qemuDomainObjEndJob(driver
, vm
);
4225 virDomainObjEndAPI(&vm
);
4226 virObjectUnref(cfg
);
4231 getAutoDumpPath(virQEMUDriverPtr driver
,
4234 char *dumpfile
= NULL
;
4235 char *domname
= virDomainDefGetShortName(vm
->def
);
4237 struct tm time_info
;
4238 time_t curtime
= time(NULL
);
4239 virQEMUDriverConfigPtr cfg
= NULL
;
4244 cfg
= virQEMUDriverGetConfig(driver
);
4246 localtime_r(&curtime
, &time_info
);
4247 strftime(timestr
, sizeof(timestr
), "%Y-%m-%d-%H:%M:%S", &time_info
);
4249 ignore_value(virAsprintf(&dumpfile
, "%s/%s-%s",
4254 virObjectUnref(cfg
);
4260 processWatchdogEvent(virQEMUDriverPtr driver
,
4265 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4266 char *dumpfile
= getAutoDumpPath(driver
, vm
);
4267 unsigned int flags
= VIR_DUMP_MEMORY_ONLY
;
4273 case VIR_DOMAIN_WATCHDOG_ACTION_DUMP
:
4274 if (qemuDomainObjBeginAsyncJob(driver
, vm
,
4275 QEMU_ASYNC_JOB_DUMP
,
4276 VIR_DOMAIN_JOB_OPERATION_DUMP
,
4281 if (virDomainObjCheckActive(vm
) < 0)
4284 flags
|= cfg
->autoDumpBypassCache
? VIR_DUMP_BYPASS_CACHE
: 0;
4285 if ((ret
= doCoreDump(driver
, vm
, dumpfile
, flags
,
4286 VIR_DOMAIN_CORE_DUMP_FORMAT_RAW
)) < 0)
4287 virReportError(VIR_ERR_OPERATION_FAILED
,
4288 "%s", _("Dump failed"));
4290 ret
= qemuProcessStartCPUs(driver
, vm
,
4291 VIR_DOMAIN_RUNNING_UNPAUSED
,
4292 QEMU_ASYNC_JOB_DUMP
);
4295 virReportError(VIR_ERR_OPERATION_FAILED
,
4296 "%s", _("Resuming after dump failed"));
4303 qemuDomainObjEndAsyncJob(driver
, vm
);
4306 virObjectUnref(cfg
);
4311 doCoreDumpToAutoDumpPath(virQEMUDriverPtr driver
,
4316 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4317 char *dumpfile
= getAutoDumpPath(driver
, vm
);
4322 flags
|= cfg
->autoDumpBypassCache
? VIR_DUMP_BYPASS_CACHE
: 0;
4323 if ((ret
= doCoreDump(driver
, vm
, dumpfile
, flags
,
4324 VIR_DOMAIN_CORE_DUMP_FORMAT_RAW
)) < 0)
4325 virReportError(VIR_ERR_OPERATION_FAILED
,
4326 "%s", _("Dump failed"));
4329 virObjectUnref(cfg
);
4335 qemuProcessGuestPanicEventInfo(virQEMUDriverPtr driver
,
4337 qemuMonitorEventPanicInfoPtr info
)
4339 char *msg
= qemuMonitorGuestPanicEventInfoFormatMsg(info
);
4340 char *timestamp
= virTimeStringNow();
4342 if (msg
&& timestamp
)
4343 qemuDomainLogAppendMessage(driver
, vm
, "%s: panic %s\n", timestamp
, msg
);
4345 VIR_FREE(timestamp
);
4351 processGuestPanicEvent(virQEMUDriverPtr driver
,
4354 qemuMonitorEventPanicInfoPtr info
)
4356 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
4357 virObjectEventPtr event
= NULL
;
4358 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4359 bool removeInactive
= false;
4360 unsigned long flags
= VIR_DUMP_MEMORY_ONLY
;
4362 if (qemuDomainObjBeginAsyncJob(driver
, vm
, QEMU_ASYNC_JOB_DUMP
,
4363 VIR_DOMAIN_JOB_OPERATION_DUMP
, flags
) < 0)
4366 if (!virDomainObjIsActive(vm
)) {
4367 VIR_DEBUG("Ignoring GUEST_PANICKED event from inactive domain %s",
4373 qemuProcessGuestPanicEventInfo(driver
, vm
, info
);
4375 virDomainObjSetState(vm
, VIR_DOMAIN_CRASHED
, VIR_DOMAIN_CRASHED_PANICKED
);
4377 event
= virDomainEventLifecycleNewFromObj(vm
,
4378 VIR_DOMAIN_EVENT_CRASHED
,
4379 VIR_DOMAIN_EVENT_CRASHED_PANICKED
);
4381 virObjectEventStateQueue(driver
->domainEventState
, event
);
4383 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0) {
4384 VIR_WARN("Unable to save status on vm %s after state change",
4388 if (virDomainLockProcessPause(driver
->lockManager
, vm
, &priv
->lockState
) < 0)
4389 VIR_WARN("Unable to release lease on %s", vm
->def
->name
);
4390 VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv
->lockState
));
4393 case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY
:
4394 if (doCoreDumpToAutoDumpPath(driver
, vm
, flags
) < 0)
4396 ATTRIBUTE_FALLTHROUGH
;
4398 case VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY
:
4399 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_CRASHED
,
4400 QEMU_ASYNC_JOB_DUMP
, 0);
4401 event
= virDomainEventLifecycleNewFromObj(vm
,
4402 VIR_DOMAIN_EVENT_STOPPED
,
4403 VIR_DOMAIN_EVENT_STOPPED_CRASHED
);
4405 virObjectEventStateQueue(driver
->domainEventState
, event
);
4406 virDomainAuditStop(vm
, "destroyed");
4407 removeInactive
= true;
4410 case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART
:
4411 if (doCoreDumpToAutoDumpPath(driver
, vm
, flags
) < 0)
4413 ATTRIBUTE_FALLTHROUGH
;
4415 case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART
:
4416 qemuDomainSetFakeReboot(driver
, vm
, true);
4417 qemuProcessShutdownOrReboot(driver
, vm
);
4420 case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE
:
4428 qemuDomainObjEndAsyncJob(driver
, vm
);
4430 qemuDomainRemoveInactiveJob(driver
, vm
);
4433 virObjectUnref(cfg
);
4438 processDeviceDeletedEvent(virQEMUDriverPtr driver
,
4440 const char *devAlias
)
4442 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4443 virDomainDeviceDef dev
;
4445 VIR_DEBUG("Removing device %s from domain %p %s",
4446 devAlias
, vm
, vm
->def
->name
);
4448 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
4451 if (!virDomainObjIsActive(vm
)) {
4452 VIR_DEBUG("Domain is not running");
4456 if (STRPREFIX(devAlias
, "vcpu")) {
4457 qemuDomainRemoveVcpuAlias(driver
, vm
, devAlias
);
4459 if (virDomainDefFindDevice(vm
->def
, devAlias
, &dev
, true) < 0)
4462 if (qemuDomainRemoveDevice(driver
, vm
, &dev
) < 0)
4466 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
4467 VIR_WARN("unable to save domain status after removing device %s",
4471 qemuDomainObjEndJob(driver
, vm
);
4474 virObjectUnref(cfg
);
4479 syncNicRxFilterMacAddr(char *ifname
, virNetDevRxFilterPtr guestFilter
,
4480 virNetDevRxFilterPtr hostFilter
)
4482 char newMacStr
[VIR_MAC_STRING_BUFLEN
];
4484 if (virMacAddrCmp(&hostFilter
->mac
, &guestFilter
->mac
)) {
4485 virMacAddrFormat(&guestFilter
->mac
, newMacStr
);
4487 /* set new MAC address from guest to associated macvtap device */
4488 if (virNetDevSetMAC(ifname
, &guestFilter
->mac
) < 0) {
4489 VIR_WARN("Couldn't set new MAC address %s to device %s "
4490 "while responding to NIC_RX_FILTER_CHANGED",
4493 VIR_DEBUG("device %s MAC address set to %s", ifname
, newMacStr
);
4500 syncNicRxFilterGuestMulticast(char *ifname
, virNetDevRxFilterPtr guestFilter
,
4501 virNetDevRxFilterPtr hostFilter
)
4505 char macstr
[VIR_MAC_STRING_BUFLEN
];
4507 for (i
= 0; i
< guestFilter
->multicast
.nTable
; i
++) {
4510 for (j
= 0; j
< hostFilter
->multicast
.nTable
; j
++) {
4511 if (virMacAddrCmp(&guestFilter
->multicast
.table
[i
],
4512 &hostFilter
->multicast
.table
[j
]) == 0) {
4519 virMacAddrFormat(&guestFilter
->multicast
.table
[i
], macstr
);
4521 if (virNetDevAddMulti(ifname
, &guestFilter
->multicast
.table
[i
]) < 0) {
4522 VIR_WARN("Couldn't add new multicast MAC address %s to "
4523 "device %s while responding to NIC_RX_FILTER_CHANGED",
4526 VIR_DEBUG("Added multicast MAC %s to %s interface",
4535 syncNicRxFilterHostMulticast(char *ifname
, virNetDevRxFilterPtr guestFilter
,
4536 virNetDevRxFilterPtr hostFilter
)
4540 char macstr
[VIR_MAC_STRING_BUFLEN
];
4542 for (i
= 0; i
< hostFilter
->multicast
.nTable
; i
++) {
4545 for (j
= 0; j
< guestFilter
->multicast
.nTable
; j
++) {
4546 if (virMacAddrCmp(&hostFilter
->multicast
.table
[i
],
4547 &guestFilter
->multicast
.table
[j
]) == 0) {
4554 virMacAddrFormat(&hostFilter
->multicast
.table
[i
], macstr
);
4556 if (virNetDevDelMulti(ifname
, &hostFilter
->multicast
.table
[i
]) < 0) {
4557 VIR_WARN("Couldn't delete multicast MAC address %s from "
4558 "device %s while responding to NIC_RX_FILTER_CHANGED",
4561 VIR_DEBUG("Deleted multicast MAC %s from %s interface",
4570 syncNicRxFilterPromiscMode(char *ifname
,
4571 virNetDevRxFilterPtr guestFilter
,
4572 virNetDevRxFilterPtr hostFilter
)
4575 bool setpromisc
= false;
4577 /* Set macvtap promisc mode to true if the guest has vlans defined */
4578 /* or synchronize the macvtap promisc mode if different from guest */
4579 if (guestFilter
->vlan
.nTable
> 0) {
4580 if (!hostFilter
->promiscuous
) {
4584 } else if (hostFilter
->promiscuous
!= guestFilter
->promiscuous
) {
4586 promisc
= guestFilter
->promiscuous
;
4590 if (virNetDevSetPromiscuous(ifname
, promisc
) < 0) {
4591 VIR_WARN("Couldn't set PROMISC flag to %s for device %s "
4592 "while responding to NIC_RX_FILTER_CHANGED",
4593 promisc
? "true" : "false", ifname
);
4600 syncNicRxFilterMultiMode(char *ifname
, virNetDevRxFilterPtr guestFilter
,
4601 virNetDevRxFilterPtr hostFilter
)
4603 if (hostFilter
->multicast
.mode
!= guestFilter
->multicast
.mode
||
4604 (guestFilter
->multicast
.overflow
&&
4605 guestFilter
->multicast
.mode
== VIR_NETDEV_RX_FILTER_MODE_NORMAL
)) {
4606 switch (guestFilter
->multicast
.mode
) {
4607 case VIR_NETDEV_RX_FILTER_MODE_ALL
:
4608 if (virNetDevSetRcvAllMulti(ifname
, true) < 0) {
4609 VIR_WARN("Couldn't set allmulticast flag to 'on' for "
4610 "device %s while responding to "
4611 "NIC_RX_FILTER_CHANGED", ifname
);
4615 case VIR_NETDEV_RX_FILTER_MODE_NORMAL
:
4616 if (guestFilter
->multicast
.overflow
&&
4617 (hostFilter
->multicast
.mode
== VIR_NETDEV_RX_FILTER_MODE_ALL
)) {
4621 if (virNetDevSetRcvMulti(ifname
, true) < 0) {
4622 VIR_WARN("Couldn't set multicast flag to 'on' for "
4623 "device %s while responding to "
4624 "NIC_RX_FILTER_CHANGED", ifname
);
4627 if (virNetDevSetRcvAllMulti(ifname
,
4628 guestFilter
->multicast
.overflow
) < 0) {
4629 VIR_WARN("Couldn't set allmulticast flag to '%s' for "
4630 "device %s while responding to "
4631 "NIC_RX_FILTER_CHANGED",
4632 virTristateSwitchTypeToString(virTristateSwitchFromBool(guestFilter
->multicast
.overflow
)),
4637 case VIR_NETDEV_RX_FILTER_MODE_NONE
:
4638 if (virNetDevSetRcvAllMulti(ifname
, false) < 0) {
4639 VIR_WARN("Couldn't set allmulticast flag to 'off' for "
4640 "device %s while responding to "
4641 "NIC_RX_FILTER_CHANGED", ifname
);
4644 if (virNetDevSetRcvMulti(ifname
, false) < 0) {
4645 VIR_WARN("Couldn't set multicast flag to 'off' for "
4646 "device %s while responding to "
4647 "NIC_RX_FILTER_CHANGED",
4657 syncNicRxFilterDeviceOptions(char *ifname
, virNetDevRxFilterPtr guestFilter
,
4658 virNetDevRxFilterPtr hostFilter
)
4660 syncNicRxFilterPromiscMode(ifname
, guestFilter
, hostFilter
);
4661 syncNicRxFilterMultiMode(ifname
, guestFilter
, hostFilter
);
4666 syncNicRxFilterMulticast(char *ifname
,
4667 virNetDevRxFilterPtr guestFilter
,
4668 virNetDevRxFilterPtr hostFilter
)
4670 syncNicRxFilterGuestMulticast(ifname
, guestFilter
, hostFilter
);
4671 syncNicRxFilterHostMulticast(ifname
, guestFilter
, hostFilter
);
4675 processNicRxFilterChangedEvent(virQEMUDriverPtr driver
,
4677 const char *devAlias
)
4679 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4680 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
4681 virDomainDeviceDef dev
;
4682 virDomainNetDefPtr def
;
4683 virNetDevRxFilterPtr guestFilter
= NULL
;
4684 virNetDevRxFilterPtr hostFilter
= NULL
;
4687 VIR_DEBUG("Received NIC_RX_FILTER_CHANGED event for device %s "
4688 "from domain %p %s",
4689 devAlias
, vm
, vm
->def
->name
);
4691 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
4694 if (!virDomainObjIsActive(vm
)) {
4695 VIR_DEBUG("Domain is not running");
4699 if (virDomainDefFindDevice(vm
->def
, devAlias
, &dev
, true) < 0) {
4700 VIR_WARN("NIC_RX_FILTER_CHANGED event received for "
4701 "non-existent device %s in domain %s",
4702 devAlias
, vm
->def
->name
);
4705 if (dev
.type
!= VIR_DOMAIN_DEVICE_NET
) {
4706 VIR_WARN("NIC_RX_FILTER_CHANGED event received for "
4707 "non-network device %s in domain %s",
4708 devAlias
, vm
->def
->name
);
4713 if (!virDomainNetGetActualTrustGuestRxFilters(def
)) {
4714 VIR_DEBUG("ignore NIC_RX_FILTER_CHANGED event for network "
4715 "device %s in domain %s",
4716 def
->info
.alias
, vm
->def
->name
);
4717 /* not sending "query-rx-filter" will also suppress any
4718 * further NIC_RX_FILTER_CHANGED events for this device
4723 /* handle the event - send query-rx-filter and respond to it. */
4725 VIR_DEBUG("process NIC_RX_FILTER_CHANGED event for network "
4726 "device %s in domain %s", def
->info
.alias
, vm
->def
->name
);
4728 qemuDomainObjEnterMonitor(driver
, vm
);
4729 ret
= qemuMonitorQueryRxFilter(priv
->mon
, devAlias
, &guestFilter
);
4730 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
4735 if (virDomainNetGetActualType(def
) == VIR_DOMAIN_NET_TYPE_DIRECT
) {
4737 if (virNetDevGetRxFilter(def
->ifname
, &hostFilter
)) {
4738 VIR_WARN("Couldn't get current RX filter for device %s "
4739 "while responding to NIC_RX_FILTER_CHANGED",
4744 /* For macvtap connections, set the following macvtap network device
4745 * attributes to match those of the guest network device:
4747 * - Multicast MAC address table
4753 syncNicRxFilterMacAddr(def
->ifname
, guestFilter
, hostFilter
);
4754 syncNicRxFilterMulticast(def
->ifname
, guestFilter
, hostFilter
);
4755 syncNicRxFilterDeviceOptions(def
->ifname
, guestFilter
, hostFilter
);
4758 if (virDomainNetGetActualType(def
) == VIR_DOMAIN_NET_TYPE_NETWORK
) {
4759 const char *brname
= virDomainNetGetActualBridgeName(def
);
4761 /* For libivrt network connections, set the following TUN/TAP network
4762 * device attributes to match those of the guest network device:
4763 * - QoS filters (which are based on MAC address)
4765 if (virDomainNetGetActualBandwidth(def
) &&
4766 def
->data
.network
.actual
&&
4767 virNetDevBandwidthUpdateFilter(brname
, &guestFilter
->mac
,
4768 def
->data
.network
.actual
->class_id
) < 0)
4773 qemuDomainObjEndJob(driver
, vm
);
4776 virNetDevRxFilterFree(hostFilter
);
4777 virNetDevRxFilterFree(guestFilter
);
4778 virObjectUnref(cfg
);
4783 processSerialChangedEvent(virQEMUDriverPtr driver
,
4785 const char *devAlias
,
4788 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4789 virDomainChrDeviceState newstate
;
4790 virObjectEventPtr event
= NULL
;
4791 virDomainDeviceDef dev
;
4792 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
4795 newstate
= VIR_DOMAIN_CHR_DEVICE_STATE_CONNECTED
;
4797 newstate
= VIR_DOMAIN_CHR_DEVICE_STATE_DISCONNECTED
;
4799 VIR_DEBUG("Changing serial port state %s in domain %p %s",
4800 devAlias
, vm
, vm
->def
->name
);
4802 if (newstate
== VIR_DOMAIN_CHR_DEVICE_STATE_DISCONNECTED
&&
4803 virDomainObjIsActive(vm
) && priv
->agent
) {
4804 /* peek into the domain definition to find the channel */
4805 if (virDomainDefFindDevice(vm
->def
, devAlias
, &dev
, true) == 0 &&
4806 dev
.type
== VIR_DOMAIN_DEVICE_CHR
&&
4807 dev
.data
.chr
->deviceType
== VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL
&&
4808 dev
.data
.chr
->targetType
== VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO
&&
4809 STREQ_NULLABLE(dev
.data
.chr
->target
.name
, "org.qemu.guest_agent.0"))
4810 /* Close agent monitor early, so that other threads
4811 * waiting for the agent to reply can finish and our
4812 * job we acquire below can succeed. */
4813 qemuAgentNotifyClose(priv
->agent
);
4815 /* now discard the data, since it may possibly change once we unlock
4816 * while entering the job */
4817 memset(&dev
, 0, sizeof(dev
));
4820 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
4823 if (!virDomainObjIsActive(vm
)) {
4824 VIR_DEBUG("Domain is not running");
4828 if (virDomainDefFindDevice(vm
->def
, devAlias
, &dev
, true) < 0)
4831 /* we care only about certain devices */
4832 if (dev
.type
!= VIR_DOMAIN_DEVICE_CHR
||
4833 dev
.data
.chr
->deviceType
!= VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL
||
4834 dev
.data
.chr
->targetType
!= VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO
)
4837 dev
.data
.chr
->state
= newstate
;
4839 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
4840 VIR_WARN("unable to save status of domain %s after updating state of "
4841 "channel %s", vm
->def
->name
, devAlias
);
4843 if (STREQ_NULLABLE(dev
.data
.chr
->target
.name
, "org.qemu.guest_agent.0")) {
4844 if (newstate
== VIR_DOMAIN_CHR_DEVICE_STATE_CONNECTED
) {
4845 if (qemuConnectAgent(driver
, vm
) < 0)
4849 qemuAgentClose(priv
->agent
);
4852 priv
->agentError
= false;
4855 event
= virDomainEventAgentLifecycleNewFromObj(vm
, newstate
,
4856 VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL
);
4857 virObjectEventStateQueue(driver
->domainEventState
, event
);
4861 qemuDomainObjEndJob(driver
, vm
);
4864 virObjectUnref(cfg
);
4869 processBlockJobEvent(virQEMUDriverPtr driver
,
4871 const char *diskAlias
,
4875 virDomainDiskDefPtr disk
;
4876 qemuBlockJobDataPtr job
= NULL
;
4878 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
4881 if (!virDomainObjIsActive(vm
)) {
4882 VIR_DEBUG("Domain is not running");
4886 if (!(disk
= qemuProcessFindDomainDiskByAliasOrQOM(vm
, diskAlias
, NULL
))) {
4887 VIR_DEBUG("disk %s not found", diskAlias
);
4891 if (!(job
= qemuBlockJobDiskGetJob(disk
))) {
4892 if (!(job
= qemuBlockJobDiskNew(disk
, type
, diskAlias
)))
4894 qemuBlockJobStarted(job
);
4897 job
->newstate
= status
;
4899 qemuBlockJobUpdate(vm
, job
, QEMU_ASYNC_JOB_NONE
);
4902 qemuBlockJobStartupFinalize(job
);
4903 qemuDomainObjEndJob(driver
, vm
);
4908 processMonitorEOFEvent(virQEMUDriverPtr driver
,
4911 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
4912 int eventReason
= VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN
;
4913 int stopReason
= VIR_DOMAIN_SHUTOFF_SHUTDOWN
;
4914 const char *auditReason
= "shutdown";
4915 unsigned int stopFlags
= 0;
4916 virObjectEventPtr event
= NULL
;
4918 if (qemuProcessBeginStopJob(driver
, vm
, QEMU_JOB_DESTROY
, true) < 0)
4921 if (!virDomainObjIsActive(vm
)) {
4922 VIR_DEBUG("Domain %p '%s' is not active, ignoring EOF",
4927 if (priv
->monJSON
&&
4928 virDomainObjGetState(vm
, NULL
) != VIR_DOMAIN_SHUTDOWN
) {
4929 VIR_DEBUG("Monitor connection to '%s' closed without SHUTDOWN event; "
4930 "assuming the domain crashed", vm
->def
->name
);
4931 eventReason
= VIR_DOMAIN_EVENT_STOPPED_FAILED
;
4932 stopReason
= VIR_DOMAIN_SHUTOFF_CRASHED
;
4933 auditReason
= "failed";
4936 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_IN
) {
4937 stopFlags
|= VIR_QEMU_PROCESS_STOP_MIGRATED
;
4938 qemuMigrationDstErrorSave(driver
, vm
->def
->name
,
4939 qemuMonitorLastError(priv
->mon
));
4942 event
= virDomainEventLifecycleNewFromObj(vm
, VIR_DOMAIN_EVENT_STOPPED
,
4944 qemuProcessStop(driver
, vm
, stopReason
, QEMU_ASYNC_JOB_NONE
, stopFlags
);
4945 virDomainAuditStop(vm
, auditReason
);
4946 virObjectEventStateQueue(driver
->domainEventState
, event
);
4949 qemuDomainRemoveInactive(driver
, vm
);
4950 qemuDomainObjEndJob(driver
, vm
);
4955 processPRDisconnectEvent(virDomainObjPtr vm
)
4957 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
4959 if (!virDomainObjIsActive(vm
))
4962 if (!priv
->prDaemonRunning
&&
4963 virDomainDefHasManagedPR(vm
->def
))
4964 qemuProcessStartManagedPRDaemon(vm
);
4969 processRdmaGidStatusChangedEvent(virDomainObjPtr vm
,
4970 qemuMonitorRdmaGidStatusPtr info
)
4972 unsigned int prefix_len
;
4974 VIR_AUTOFREE(char *) addrStr
= NULL
;
4977 if (!virDomainObjIsActive(vm
))
4980 VIR_DEBUG("netdev=%s, gid_status=%d, subnet_prefix=0x%llx, interface_id=0x%llx",
4981 info
->netdev
, info
->gid_status
, info
->subnet_prefix
,
4982 info
->interface_id
);
4984 if (info
->subnet_prefix
) {
4985 uint32_t ipv6
[4] = {0};
4988 memcpy(&ipv6
[0], &info
->subnet_prefix
, sizeof(info
->subnet_prefix
));
4989 memcpy(&ipv6
[2], &info
->interface_id
, sizeof(info
->interface_id
));
4990 virSocketAddrSetIPv6AddrNetOrder(&addr
, ipv6
);
4993 virSocketAddrSetIPv4AddrNetOrder(&addr
, info
->interface_id
>> 32);
4996 if (!(addrStr
= virSocketAddrFormat(&addr
)))
4999 if (info
->gid_status
) {
5000 VIR_DEBUG("Adding %s to %s", addrStr
, info
->netdev
);
5001 rc
= virNetDevIPAddrAdd(info
->netdev
, &addr
, NULL
, prefix_len
);
5003 VIR_DEBUG("Removing %s from %s", addrStr
, info
->netdev
);
5004 rc
= virNetDevIPAddrDel(info
->netdev
, &addr
, prefix_len
);
5008 VIR_WARN("Fail to update address %s to %s", addrStr
, info
->netdev
);
5012 static void qemuProcessEventHandler(void *data
, void *opaque
)
5014 struct qemuProcessEvent
*processEvent
= data
;
5015 virDomainObjPtr vm
= processEvent
->vm
;
5016 virQEMUDriverPtr driver
= opaque
;
5018 VIR_DEBUG("vm=%p, event=%d", vm
, processEvent
->eventType
);
5022 switch (processEvent
->eventType
) {
5023 case QEMU_PROCESS_EVENT_WATCHDOG
:
5024 processWatchdogEvent(driver
, vm
, processEvent
->action
);
5026 case QEMU_PROCESS_EVENT_GUESTPANIC
:
5027 processGuestPanicEvent(driver
, vm
, processEvent
->action
,
5028 processEvent
->data
);
5030 case QEMU_PROCESS_EVENT_DEVICE_DELETED
:
5031 processDeviceDeletedEvent(driver
, vm
, processEvent
->data
);
5033 case QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED
:
5034 processNicRxFilterChangedEvent(driver
, vm
, processEvent
->data
);
5036 case QEMU_PROCESS_EVENT_SERIAL_CHANGED
:
5037 processSerialChangedEvent(driver
, vm
, processEvent
->data
,
5038 processEvent
->action
);
5040 case QEMU_PROCESS_EVENT_BLOCK_JOB
:
5041 processBlockJobEvent(driver
, vm
,
5043 processEvent
->action
,
5044 processEvent
->status
);
5046 case QEMU_PROCESS_EVENT_MONITOR_EOF
:
5047 processMonitorEOFEvent(driver
, vm
);
5049 case QEMU_PROCESS_EVENT_PR_DISCONNECT
:
5050 processPRDisconnectEvent(vm
);
5052 case QEMU_PROCESS_EVENT_RDMA_GID_STATUS_CHANGED
:
5053 processRdmaGidStatusChangedEvent(vm
, processEvent
->data
);
5055 case QEMU_PROCESS_EVENT_LAST
:
5059 virDomainObjEndAPI(&vm
);
5060 qemuProcessEventFree(processEvent
);
5065 qemuDomainSetVcpusAgent(virDomainObjPtr vm
,
5066 unsigned int nvcpus
)
5068 qemuAgentCPUInfoPtr cpuinfo
= NULL
;
5073 if (!qemuDomainAgentAvailable(vm
, true))
5076 if (nvcpus
> virDomainDefGetVcpus(vm
->def
)) {
5077 virReportError(VIR_ERR_INVALID_ARG
,
5078 _("requested vcpu count is greater than the count "
5079 "of enabled vcpus in the domain: %d > %d"),
5080 nvcpus
, virDomainDefGetVcpus(vm
->def
));
5084 agent
= qemuDomainObjEnterAgent(vm
);
5085 ncpuinfo
= qemuAgentGetVCPUs(agent
, &cpuinfo
);
5086 qemuDomainObjExitAgent(vm
, agent
);
5092 if (qemuAgentUpdateCPUInfo(nvcpus
, cpuinfo
, ncpuinfo
) < 0)
5095 if (!qemuDomainAgentAvailable(vm
, true))
5098 agent
= qemuDomainObjEnterAgent(vm
);
5099 ret
= qemuAgentSetVCPUs(agent
, cpuinfo
, ncpuinfo
);
5100 qemuDomainObjExitAgent(vm
, agent
);
5110 qemuDomainSetVcpusMax(virQEMUDriverPtr driver
,
5111 virDomainDefPtr def
,
5112 virDomainDefPtr persistentDef
,
5113 unsigned int nvcpus
)
5115 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
5116 unsigned int topologycpus
;
5120 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
5121 _("maximum vcpu count of a live domain can't be modified"));
5125 if (virDomainNumaGetCPUCountTotal(persistentDef
->numa
) > nvcpus
) {
5126 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5127 _("Number of CPUs in <numa> exceeds the desired "
5128 "maximum vcpu count"));
5132 if (virDomainDefGetVcpusTopology(persistentDef
, &topologycpus
) == 0 &&
5133 nvcpus
!= topologycpus
) {
5134 /* allow setting a valid vcpu count for the topology so an invalid
5135 * setting may be corrected via this API */
5136 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5137 _("CPU topology doesn't match the desired vcpu count"));
5141 /* ordering information may become invalid, thus clear it */
5142 virDomainDefVcpuOrderClear(persistentDef
);
5144 if (virDomainDefSetVcpusMax(persistentDef
, nvcpus
, driver
->xmlopt
) < 0)
5147 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
5153 virObjectUnref(cfg
);
5159 qemuDomainSetVcpusFlags(virDomainPtr dom
,
5160 unsigned int nvcpus
,
5163 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5164 virDomainObjPtr vm
= NULL
;
5165 virDomainDefPtr def
;
5166 virDomainDefPtr persistentDef
;
5167 bool hotpluggable
= !!(flags
& VIR_DOMAIN_VCPU_HOTPLUGGABLE
);
5168 bool useAgent
= !!(flags
& VIR_DOMAIN_VCPU_GUEST
);
5169 qemuDomainJob job
= QEMU_JOB_NONE
;
5170 qemuDomainAgentJob agentJob
= QEMU_AGENT_JOB_NONE
;
5173 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5174 VIR_DOMAIN_AFFECT_CONFIG
|
5175 VIR_DOMAIN_VCPU_MAXIMUM
|
5176 VIR_DOMAIN_VCPU_GUEST
|
5177 VIR_DOMAIN_VCPU_HOTPLUGGABLE
, -1);
5179 if (!(vm
= qemuDomObjFromDomain(dom
)))
5182 if (virDomainSetVcpusFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
5186 agentJob
= QEMU_AGENT_JOB_MODIFY
;
5188 job
= QEMU_JOB_MODIFY
;
5190 if (qemuDomainObjBeginJobWithAgent(driver
, vm
, job
, agentJob
) < 0)
5193 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
5197 ret
= qemuDomainSetVcpusAgent(vm
, nvcpus
);
5198 else if (flags
& VIR_DOMAIN_VCPU_MAXIMUM
)
5199 ret
= qemuDomainSetVcpusMax(driver
, def
, persistentDef
, nvcpus
);
5201 ret
= qemuDomainSetVcpusInternal(driver
, vm
, def
, persistentDef
,
5202 nvcpus
, hotpluggable
);
5206 qemuDomainObjEndAgentJob(vm
);
5208 qemuDomainObjEndJob(driver
, vm
);
5211 virDomainObjEndAPI(&vm
);
5217 qemuDomainSetVcpus(virDomainPtr dom
, unsigned int nvcpus
)
5219 return qemuDomainSetVcpusFlags(dom
, nvcpus
, VIR_DOMAIN_AFFECT_LIVE
);
5224 qemuDomainPinVcpuLive(virDomainObjPtr vm
,
5225 virDomainDefPtr def
,
5227 virQEMUDriverPtr driver
,
5228 virQEMUDriverConfigPtr cfg
,
5229 virBitmapPtr cpumap
)
5231 virBitmapPtr tmpmap
= NULL
;
5232 virDomainVcpuDefPtr vcpuinfo
;
5233 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
5234 virCgroupPtr cgroup_vcpu
= NULL
;
5236 virObjectEventPtr event
= NULL
;
5237 char paramField
[VIR_TYPED_PARAM_FIELD_LENGTH
] = "";
5238 virTypedParameterPtr eventParams
= NULL
;
5239 int eventNparams
= 0;
5240 int eventMaxparams
= 0;
5243 if (!qemuDomainHasVcpuPids(vm
)) {
5244 virReportError(VIR_ERR_OPERATION_INVALID
,
5245 "%s", _("cpu affinity is not supported"));
5249 if (!(vcpuinfo
= virDomainDefGetVcpu(def
, vcpu
))) {
5250 virReportError(VIR_ERR_INVALID_ARG
,
5251 _("vcpu %d is out of range of live cpu count %d"),
5252 vcpu
, virDomainDefGetVcpusMax(def
));
5256 if (!(tmpmap
= virBitmapNewCopy(cpumap
)))
5259 if (!(str
= virBitmapFormat(cpumap
)))
5262 if (vcpuinfo
->online
) {
5263 /* Configure the corresponding cpuset cgroup before set affinity. */
5264 if (virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPUSET
)) {
5265 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_VCPU
, vcpu
,
5266 false, &cgroup_vcpu
) < 0)
5268 if (qemuSetupCgroupCpusetCpus(cgroup_vcpu
, cpumap
) < 0)
5272 if (virProcessSetAffinity(qemuDomainGetVcpuPid(vm
, vcpu
), cpumap
) < 0)
5276 virBitmapFree(vcpuinfo
->cpumask
);
5277 vcpuinfo
->cpumask
= tmpmap
;
5280 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
5283 if (snprintf(paramField
, VIR_TYPED_PARAM_FIELD_LENGTH
,
5284 VIR_DOMAIN_TUNABLE_CPU_VCPUPIN
, vcpu
) < 0) {
5288 if (virTypedParamsAddString(&eventParams
, &eventNparams
,
5289 &eventMaxparams
, paramField
, str
) < 0)
5292 event
= virDomainEventTunableNewFromObj(vm
, eventParams
, eventNparams
);
5297 virBitmapFree(tmpmap
);
5298 virCgroupFree(&cgroup_vcpu
);
5300 virObjectEventStateQueue(driver
->domainEventState
, event
);
5306 qemuDomainPinVcpuFlags(virDomainPtr dom
,
5308 unsigned char *cpumap
,
5312 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5314 virDomainDefPtr def
;
5315 virDomainDefPtr persistentDef
;
5317 virBitmapPtr pcpumap
= NULL
;
5318 virDomainVcpuDefPtr vcpuinfo
= NULL
;
5319 virQEMUDriverConfigPtr cfg
= NULL
;
5321 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5322 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5324 cfg
= virQEMUDriverGetConfig(driver
);
5326 if (!(vm
= qemuDomObjFromDomain(dom
)))
5329 if (virDomainPinVcpuFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
5332 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
5335 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
5338 if (persistentDef
&&
5339 !(vcpuinfo
= virDomainDefGetVcpu(persistentDef
, vcpu
))) {
5340 virReportError(VIR_ERR_INVALID_ARG
,
5341 _("vcpu %d is out of range of persistent cpu count %d"),
5342 vcpu
, virDomainDefGetVcpus(persistentDef
));
5346 if (!(pcpumap
= virBitmapNewData(cpumap
, maplen
)))
5349 if (virBitmapIsAllClear(pcpumap
)) {
5350 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5351 _("Empty cpu list for pinning"));
5356 qemuDomainPinVcpuLive(vm
, def
, vcpu
, driver
, cfg
, pcpumap
) < 0)
5359 if (persistentDef
) {
5360 virBitmapFree(vcpuinfo
->cpumask
);
5361 vcpuinfo
->cpumask
= pcpumap
;
5364 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
);
5371 qemuDomainObjEndJob(driver
, vm
);
5374 virDomainObjEndAPI(&vm
);
5375 virBitmapFree(pcpumap
);
5376 virObjectUnref(cfg
);
5381 qemuDomainPinVcpu(virDomainPtr dom
,
5383 unsigned char *cpumap
,
5386 return qemuDomainPinVcpuFlags(dom
, vcpu
, cpumap
, maplen
,
5387 VIR_DOMAIN_AFFECT_LIVE
);
5391 qemuDomainGetVcpuPinInfo(virDomainPtr dom
,
5393 unsigned char *cpumaps
,
5397 virDomainObjPtr vm
= NULL
;
5398 virDomainDefPtr def
;
5401 virBitmapPtr autoCpuset
= NULL
;
5403 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5404 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5406 if (!(vm
= qemuDomObjFromDomain(dom
)))
5409 if (virDomainGetVcpuPinInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
5412 if (!(def
= virDomainObjGetOneDefState(vm
, flags
, &live
)))
5416 autoCpuset
= QEMU_DOMAIN_PRIVATE(vm
)->autoCpuset
;
5418 ret
= virDomainDefGetVcpuPinInfoHelper(def
, maplen
, ncpumaps
, cpumaps
,
5419 virHostCPUGetCount(), autoCpuset
);
5421 virDomainObjEndAPI(&vm
);
5426 qemuDomainPinEmulator(virDomainPtr dom
,
5427 unsigned char *cpumap
,
5431 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5433 virCgroupPtr cgroup_emulator
= NULL
;
5434 virDomainDefPtr def
;
5435 virDomainDefPtr persistentDef
;
5437 qemuDomainObjPrivatePtr priv
;
5438 virBitmapPtr pcpumap
= NULL
;
5439 virQEMUDriverConfigPtr cfg
= NULL
;
5440 virObjectEventPtr event
= NULL
;
5442 virTypedParameterPtr eventParams
= NULL
;
5443 int eventNparams
= 0;
5444 int eventMaxparams
= 0;
5446 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5447 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5449 cfg
= virQEMUDriverGetConfig(driver
);
5451 if (!(vm
= qemuDomObjFromDomain(dom
)))
5454 if (virDomainPinEmulatorEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
5457 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
5460 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
5463 priv
= vm
->privateData
;
5465 if (!(pcpumap
= virBitmapNewData(cpumap
, maplen
)))
5468 if (virBitmapIsAllClear(pcpumap
)) {
5469 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5470 _("Empty cpu list for pinning"));
5475 if (virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPUSET
)) {
5476 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_EMULATOR
,
5477 0, false, &cgroup_emulator
) < 0)
5480 if (qemuSetupCgroupCpusetCpus(cgroup_emulator
, pcpumap
) < 0) {
5481 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
5482 _("failed to set cpuset.cpus in cgroup"
5483 " for emulator threads"));
5488 if (virProcessSetAffinity(vm
->pid
, pcpumap
) < 0)
5491 virBitmapFree(def
->cputune
.emulatorpin
);
5492 def
->cputune
.emulatorpin
= NULL
;
5494 if (!(def
->cputune
.emulatorpin
= virBitmapNewCopy(pcpumap
)))
5497 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
5500 str
= virBitmapFormat(pcpumap
);
5501 if (virTypedParamsAddString(&eventParams
, &eventNparams
,
5503 VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN
,
5507 event
= virDomainEventTunableNewFromDom(dom
, eventParams
, eventNparams
);
5510 if (persistentDef
) {
5511 virBitmapFree(persistentDef
->cputune
.emulatorpin
);
5512 persistentDef
->cputune
.emulatorpin
= NULL
;
5514 if (!(persistentDef
->cputune
.emulatorpin
= virBitmapNewCopy(pcpumap
)))
5517 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
);
5524 qemuDomainObjEndJob(driver
, vm
);
5527 if (cgroup_emulator
)
5528 virCgroupFree(&cgroup_emulator
);
5529 virObjectEventStateQueue(driver
->domainEventState
, event
);
5531 virBitmapFree(pcpumap
);
5532 virDomainObjEndAPI(&vm
);
5533 virObjectUnref(cfg
);
5538 qemuDomainGetEmulatorPinInfo(virDomainPtr dom
,
5539 unsigned char *cpumaps
,
5543 virDomainObjPtr vm
= NULL
;
5544 virDomainDefPtr def
;
5548 virBitmapPtr cpumask
= NULL
;
5549 virBitmapPtr bitmap
= NULL
;
5550 virBitmapPtr autoCpuset
= NULL
;
5552 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5553 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5555 if (!(vm
= qemuDomObjFromDomain(dom
)))
5558 if (virDomainGetEmulatorPinInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
5561 if (!(def
= virDomainObjGetOneDefState(vm
, flags
, &live
)))
5564 if ((hostcpus
= virHostCPUGetCount()) < 0)
5568 autoCpuset
= QEMU_DOMAIN_PRIVATE(vm
)->autoCpuset
;
5570 if (def
->cputune
.emulatorpin
) {
5571 cpumask
= def
->cputune
.emulatorpin
;
5572 } else if (def
->cpumask
) {
5573 cpumask
= def
->cpumask
;
5574 } else if (vm
->def
->placement_mode
== VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO
&&
5576 cpumask
= autoCpuset
;
5578 if (!(bitmap
= virBitmapNew(hostcpus
)))
5580 virBitmapSetAll(bitmap
);
5584 virBitmapToDataBuf(cpumask
, cpumaps
, maplen
);
5589 virDomainObjEndAPI(&vm
);
5590 virBitmapFree(bitmap
);
5595 qemuDomainGetVcpus(virDomainPtr dom
,
5596 virVcpuInfoPtr info
,
5598 unsigned char *cpumaps
,
5604 if (!(vm
= qemuDomObjFromDomain(dom
)))
5607 if (virDomainGetVcpusEnsureACL(dom
->conn
, vm
->def
) < 0)
5610 if (!virDomainObjIsActive(vm
)) {
5611 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
5612 _("cannot retrieve vcpu information for inactive domain"));
5616 ret
= qemuDomainHelperGetVcpus(vm
, info
, NULL
, maxinfo
, cpumaps
, maplen
);
5619 virDomainObjEndAPI(&vm
);
5625 qemuDomainGetVcpusFlags(virDomainPtr dom
, unsigned int flags
)
5627 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5629 virDomainDefPtr def
;
5631 qemuAgentCPUInfoPtr cpuinfo
= NULL
;
5636 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5637 VIR_DOMAIN_AFFECT_CONFIG
|
5638 VIR_DOMAIN_VCPU_MAXIMUM
|
5639 VIR_DOMAIN_VCPU_GUEST
, -1);
5641 if (!(vm
= qemuDomObjFromDomain(dom
)))
5644 if (virDomainGetVcpusFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
5647 if (!(def
= virDomainObjGetOneDef(vm
, flags
)))
5650 if (flags
& VIR_DOMAIN_VCPU_GUEST
) {
5651 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
5654 if (!virDomainObjIsActive(vm
)) {
5655 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5656 _("vCPU count provided by the guest agent can only be "
5657 "requested for live domains"));
5661 if (!qemuDomainAgentAvailable(vm
, true))
5664 agent
= qemuDomainObjEnterAgent(vm
);
5665 ncpuinfo
= qemuAgentGetVCPUs(agent
, &cpuinfo
);
5666 qemuDomainObjExitAgent(vm
, agent
);
5669 qemuDomainObjEndAgentJob(vm
);
5674 if (flags
& VIR_DOMAIN_VCPU_MAXIMUM
) {
5679 /* count the online vcpus */
5681 for (i
= 0; i
< ncpuinfo
; i
++) {
5682 if (cpuinfo
[i
].online
)
5686 if (flags
& VIR_DOMAIN_VCPU_MAXIMUM
)
5687 ret
= virDomainDefGetVcpusMax(def
);
5689 ret
= virDomainDefGetVcpus(def
);
5694 virDomainObjEndAPI(&vm
);
5700 qemuDomainGetMaxVcpus(virDomainPtr dom
)
5702 return qemuDomainGetVcpusFlags(dom
, (VIR_DOMAIN_AFFECT_LIVE
|
5703 VIR_DOMAIN_VCPU_MAXIMUM
));
5708 qemuDomainGetIOThreadsMon(virQEMUDriverPtr driver
,
5710 qemuMonitorIOThreadInfoPtr
**iothreads
)
5712 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
5715 qemuDomainObjEnterMonitor(driver
, vm
);
5716 niothreads
= qemuMonitorGetIOThreads(priv
->mon
, iothreads
);
5717 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || niothreads
< 0)
5725 qemuDomainGetIOThreadsLive(virQEMUDriverPtr driver
,
5727 virDomainIOThreadInfoPtr
**info
)
5729 qemuDomainObjPrivatePtr priv
;
5730 qemuMonitorIOThreadInfoPtr
*iothreads
= NULL
;
5731 virDomainIOThreadInfoPtr
*info_ret
= NULL
;
5736 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
5739 if (!virDomainObjIsActive(vm
)) {
5740 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
5741 _("cannot list IOThreads for an inactive domain"));
5745 priv
= vm
->privateData
;
5746 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_OBJECT_IOTHREAD
)) {
5747 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
5748 _("IOThreads not supported with this binary"));
5752 if ((niothreads
= qemuDomainGetIOThreadsMon(driver
, vm
, &iothreads
)) < 0)
5756 if (niothreads
== 0) {
5761 if (VIR_ALLOC_N(info_ret
, niothreads
) < 0)
5764 for (i
= 0; i
< niothreads
; i
++) {
5765 virBitmapPtr map
= NULL
;
5767 if (VIR_ALLOC(info_ret
[i
]) < 0)
5769 info_ret
[i
]->iothread_id
= iothreads
[i
]->iothread_id
;
5771 if (!(map
= virProcessGetAffinity(iothreads
[i
]->thread_id
)))
5774 if (virBitmapToData(map
, &info_ret
[i
]->cpumap
,
5775 &info_ret
[i
]->cpumaplen
) < 0) {
5782 VIR_STEAL_PTR(*info
, info_ret
);
5786 qemuDomainObjEndJob(driver
, vm
);
5790 for (i
= 0; i
< niothreads
; i
++)
5791 virDomainIOThreadInfoFree(info_ret
[i
]);
5795 for (i
= 0; i
< niothreads
; i
++)
5796 VIR_FREE(iothreads
[i
]);
5797 VIR_FREE(iothreads
);
5804 qemuDomainGetIOThreadsConfig(virDomainDefPtr targetDef
,
5805 virDomainIOThreadInfoPtr
**info
)
5807 virDomainIOThreadInfoPtr
*info_ret
= NULL
;
5808 virBitmapPtr bitmap
= NULL
;
5809 virBitmapPtr cpumask
= NULL
;
5814 if (targetDef
->niothreadids
== 0)
5817 if ((hostcpus
= virHostCPUGetCount()) < 0)
5820 if (VIR_ALLOC_N(info_ret
, targetDef
->niothreadids
) < 0)
5823 for (i
= 0; i
< targetDef
->niothreadids
; i
++) {
5824 if (VIR_ALLOC(info_ret
[i
]) < 0)
5827 /* IOThread ID's are taken from the iothreadids list */
5828 info_ret
[i
]->iothread_id
= targetDef
->iothreadids
[i
]->iothread_id
;
5830 cpumask
= targetDef
->iothreadids
[i
]->cpumask
;
5832 if (targetDef
->cpumask
) {
5833 cpumask
= targetDef
->cpumask
;
5835 if (!(bitmap
= virBitmapNew(hostcpus
)))
5837 virBitmapSetAll(bitmap
);
5841 if (virBitmapToData(cpumask
, &info_ret
[i
]->cpumap
,
5842 &info_ret
[i
]->cpumaplen
) < 0)
5844 virBitmapFree(bitmap
);
5850 ret
= targetDef
->niothreadids
;
5854 for (i
= 0; i
< targetDef
->niothreadids
; i
++)
5855 virDomainIOThreadInfoFree(info_ret
[i
]);
5858 virBitmapFree(bitmap
);
5864 qemuDomainGetIOThreadInfo(virDomainPtr dom
,
5865 virDomainIOThreadInfoPtr
**info
,
5868 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5870 virDomainDefPtr targetDef
= NULL
;
5873 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5874 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5876 if (!(vm
= qemuDomObjFromDomain(dom
)))
5879 if (virDomainGetIOThreadInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
5882 if (virDomainObjGetDefs(vm
, flags
, NULL
, &targetDef
) < 0)
5886 ret
= qemuDomainGetIOThreadsLive(driver
, vm
, info
);
5888 ret
= qemuDomainGetIOThreadsConfig(targetDef
, info
);
5891 virDomainObjEndAPI(&vm
);
5896 qemuDomainPinIOThread(virDomainPtr dom
,
5897 unsigned int iothread_id
,
5898 unsigned char *cpumap
,
5903 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5904 virQEMUDriverConfigPtr cfg
= NULL
;
5906 virDomainDefPtr def
;
5907 virDomainDefPtr persistentDef
;
5908 virBitmapPtr pcpumap
= NULL
;
5909 qemuDomainObjPrivatePtr priv
;
5910 virCgroupPtr cgroup_iothread
= NULL
;
5911 virObjectEventPtr event
= NULL
;
5912 char paramField
[VIR_TYPED_PARAM_FIELD_LENGTH
] = "";
5914 virTypedParameterPtr eventParams
= NULL
;
5915 int eventNparams
= 0;
5916 int eventMaxparams
= 0;
5918 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5919 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5921 cfg
= virQEMUDriverGetConfig(driver
);
5923 if (!(vm
= qemuDomObjFromDomain(dom
)))
5925 priv
= vm
->privateData
;
5927 if (virDomainPinIOThreadEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
5930 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
5933 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
5936 if (!(pcpumap
= virBitmapNewData(cpumap
, maplen
)))
5939 if (virBitmapIsAllClear(pcpumap
)) {
5940 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5941 _("Empty iothread cpumap list for pinning"));
5946 virDomainIOThreadIDDefPtr iothrid
;
5947 virBitmapPtr cpumask
;
5949 if (!(iothrid
= virDomainIOThreadIDFind(def
, iothread_id
))) {
5950 virReportError(VIR_ERR_INVALID_ARG
,
5951 _("iothread %d not found"), iothread_id
);
5955 if (!(cpumask
= virBitmapNewData(cpumap
, maplen
)))
5958 virBitmapFree(iothrid
->cpumask
);
5959 iothrid
->cpumask
= cpumask
;
5960 iothrid
->autofill
= false;
5962 /* Configure the corresponding cpuset cgroup before set affinity. */
5963 if (virCgroupHasController(priv
->cgroup
,
5964 VIR_CGROUP_CONTROLLER_CPUSET
)) {
5965 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_IOTHREAD
,
5966 iothread_id
, false, &cgroup_iothread
) < 0)
5968 if (qemuSetupCgroupCpusetCpus(cgroup_iothread
, pcpumap
) < 0) {
5969 virReportError(VIR_ERR_OPERATION_INVALID
,
5970 _("failed to set cpuset.cpus in cgroup"
5971 " for iothread %d"), iothread_id
);
5976 if (virProcessSetAffinity(iothrid
->thread_id
, pcpumap
) < 0)
5979 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
5982 if (snprintf(paramField
, VIR_TYPED_PARAM_FIELD_LENGTH
,
5983 VIR_DOMAIN_TUNABLE_CPU_IOTHREADSPIN
, iothread_id
) < 0) {
5987 str
= virBitmapFormat(pcpumap
);
5988 if (virTypedParamsAddString(&eventParams
, &eventNparams
,
5989 &eventMaxparams
, paramField
, str
) < 0)
5992 event
= virDomainEventTunableNewFromDom(dom
, eventParams
, eventNparams
);
5995 if (persistentDef
) {
5996 virDomainIOThreadIDDefPtr iothrid
;
5997 virBitmapPtr cpumask
;
5999 if (!(iothrid
= virDomainIOThreadIDFind(persistentDef
, iothread_id
))) {
6000 virReportError(VIR_ERR_INVALID_ARG
,
6001 _("iothreadid %d not found"), iothread_id
);
6005 if (!(cpumask
= virBitmapNewData(cpumap
, maplen
)))
6008 virBitmapFree(iothrid
->cpumask
);
6009 iothrid
->cpumask
= cpumask
;
6010 iothrid
->autofill
= false;
6012 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
);
6019 qemuDomainObjEndJob(driver
, vm
);
6022 if (cgroup_iothread
)
6023 virCgroupFree(&cgroup_iothread
);
6024 virObjectEventStateQueue(driver
->domainEventState
, event
);
6026 virBitmapFree(pcpumap
);
6027 virDomainObjEndAPI(&vm
);
6028 virObjectUnref(cfg
);
6033 qemuDomainHotplugAddIOThread(virQEMUDriverPtr driver
,
6035 unsigned int iothread_id
)
6037 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
6041 unsigned int orig_niothreads
= vm
->def
->niothreadids
;
6042 unsigned int exp_niothreads
= vm
->def
->niothreadids
;
6043 int new_niothreads
= 0;
6044 qemuMonitorIOThreadInfoPtr
*new_iothreads
= NULL
;
6045 virDomainIOThreadIDDefPtr iothrid
;
6046 virJSONValuePtr props
= NULL
;
6048 if (virAsprintf(&alias
, "iothread%u", iothread_id
) < 0)
6051 if (qemuMonitorCreateObjectProps(&props
, "iothread", alias
, NULL
) < 0)
6054 qemuDomainObjEnterMonitor(driver
, vm
);
6056 if (qemuMonitorAddObject(priv
->mon
, &props
, NULL
) < 0)
6061 /* After hotplugging the IOThreads we need to re-detect the
6062 * IOThreads thread_id's, adjust the cgroups, thread affinity,
6063 * and add the thread_id to the vm->def->iothreadids list.
6065 if ((new_niothreads
= qemuMonitorGetIOThreads(priv
->mon
,
6066 &new_iothreads
)) < 0)
6069 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
6072 if (new_niothreads
!= exp_niothreads
) {
6073 virReportError(VIR_ERR_INTERNAL_ERROR
,
6074 _("got wrong number of IOThread ids from QEMU monitor. "
6075 "got %d, wanted %d"),
6076 new_niothreads
, exp_niothreads
);
6081 * If we've successfully added an IOThread, find out where we added it
6082 * in the QEMU IOThread list, so we can add it to our iothreadids list
6084 for (idx
= 0; idx
< new_niothreads
; idx
++) {
6085 if (new_iothreads
[idx
]->iothread_id
== iothread_id
)
6089 if (idx
== new_niothreads
) {
6090 virReportError(VIR_ERR_INTERNAL_ERROR
,
6091 _("cannot find new IOThread '%u' in QEMU monitor."),
6096 if (!(iothrid
= virDomainIOThreadIDAdd(vm
->def
, iothread_id
)))
6099 iothrid
->thread_id
= new_iothreads
[idx
]->thread_id
;
6101 if (qemuProcessSetupIOThread(vm
, iothrid
) < 0)
6107 if (new_iothreads
) {
6108 for (idx
= 0; idx
< new_niothreads
; idx
++)
6109 VIR_FREE(new_iothreads
[idx
]);
6110 VIR_FREE(new_iothreads
);
6112 virDomainAuditIOThread(vm
, orig_niothreads
, new_niothreads
,
6113 "update", ret
== 0);
6115 virJSONValueFree(props
);
6119 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
6125 qemuDomainHotplugModIOThread(virQEMUDriverPtr driver
,
6127 qemuMonitorIOThreadInfo iothread
)
6129 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
6132 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_IOTHREAD_POLLING
)) {
6133 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
6134 _("IOThreads polling is not supported for this QEMU"));
6138 qemuDomainObjEnterMonitor(driver
, vm
);
6140 rc
= qemuMonitorSetIOThread(priv
->mon
, &iothread
);
6142 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
6153 qemuDomainHotplugDelIOThread(virQEMUDriverPtr driver
,
6155 unsigned int iothread_id
)
6157 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
6162 unsigned int orig_niothreads
= vm
->def
->niothreadids
;
6163 unsigned int exp_niothreads
= vm
->def
->niothreadids
;
6164 int new_niothreads
= 0;
6165 qemuMonitorIOThreadInfoPtr
*new_iothreads
= NULL
;
6167 if (virAsprintf(&alias
, "iothread%u", iothread_id
) < 0)
6170 qemuDomainObjEnterMonitor(driver
, vm
);
6172 rc
= qemuMonitorDelObject(priv
->mon
, alias
);
6177 if ((new_niothreads
= qemuMonitorGetIOThreads(priv
->mon
,
6178 &new_iothreads
)) < 0)
6181 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
6184 if (new_niothreads
!= exp_niothreads
) {
6185 virReportError(VIR_ERR_INTERNAL_ERROR
,
6186 _("got wrong number of IOThread ids from QEMU monitor. "
6187 "got %d, wanted %d"),
6188 new_niothreads
, exp_niothreads
);
6192 virDomainIOThreadIDDel(vm
->def
, iothread_id
);
6194 if (virCgroupDelThread(priv
->cgroup
, VIR_CGROUP_THREAD_IOTHREAD
,
6201 if (new_iothreads
) {
6202 for (idx
= 0; idx
< new_niothreads
; idx
++)
6203 VIR_FREE(new_iothreads
[idx
]);
6204 VIR_FREE(new_iothreads
);
6206 virDomainAuditIOThread(vm
, orig_niothreads
, new_niothreads
,
6212 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
6218 qemuDomainAddIOThreadCheck(virDomainDefPtr def
,
6219 unsigned int iothread_id
)
6221 if (virDomainIOThreadIDFind(def
, iothread_id
)) {
6222 virReportError(VIR_ERR_INVALID_ARG
,
6223 _("an IOThread is already using iothread_id '%u'"),
6233 qemuDomainDelIOThreadCheck(virDomainDefPtr def
,
6234 unsigned int iothread_id
)
6238 if (!virDomainIOThreadIDFind(def
, iothread_id
)) {
6239 virReportError(VIR_ERR_INVALID_ARG
,
6240 _("cannot find IOThread '%u' in iothreadids list"),
6245 for (i
= 0; i
< def
->ndisks
; i
++) {
6246 if (def
->disks
[i
]->iothread
== iothread_id
) {
6247 virReportError(VIR_ERR_INVALID_ARG
,
6248 _("cannot remove IOThread %u since it "
6249 "is being used by disk '%s'"),
6250 iothread_id
, def
->disks
[i
]->dst
);
6255 for (i
= 0; i
< def
->ncontrollers
; i
++) {
6256 if (def
->controllers
[i
]->iothread
== iothread_id
) {
6257 virReportError(VIR_ERR_INVALID_ARG
,
6258 _("cannot remove IOThread '%u' since it "
6259 "is being used by controller"),
6270 * @params: Pointer to params list
6271 * @nparams: Number of params to be parsed
6272 * @iothread: Buffer to store the values
6274 * The following is a description of each value parsed:
6276 * - "poll-max-ns" for each IOThread is the maximum time in nanoseconds
6277 * to allow each polling interval to occur. A polling interval is a
6278 * period of time allowed for a thread to process data before it returns
6279 * the CPU quantum back to the host. A value set too small will not allow
6280 * the IOThread to run long enough on a CPU to process data. A value set
6281 * too high will consume too much CPU time per IOThread failing to allow
6282 * other threads running on the CPU to get time. A value of 0 (zero) will
6283 * disable the polling.
6285 * - "poll-grow" - factor to grow the current polling time when deemed
6286 * necessary. If a 0 (zero) value is provided, QEMU currently doubles
6287 * its polling interval unless the current value is greater than the
6290 * - "poll-shrink" - divisor to reduced the current polling time when deemed
6291 * necessary. If a 0 (zero) value is provided, QEMU resets the polling
6292 * interval to 0 (zero) allowing the poll-grow to manipulate the time.
6294 * QEMU keeps track of the polling time elapsed and may grow or shrink the
6295 * its polling interval based upon its heuristic algorithm. It is possible
6296 * that calculations determine that it has found a "sweet spot" and no
6297 * adjustments are made. The polling time value is not available.
6299 * Returns 0 on success, -1 on failure with error set.
6302 qemuDomainIOThreadParseParams(virTypedParameterPtr params
,
6304 qemuMonitorIOThreadInfoPtr iothread
)
6308 if (virTypedParamsValidate(params
, nparams
,
6309 VIR_DOMAIN_IOTHREAD_POLL_MAX_NS
,
6310 VIR_TYPED_PARAM_ULLONG
,
6311 VIR_DOMAIN_IOTHREAD_POLL_GROW
,
6312 VIR_TYPED_PARAM_UINT
,
6313 VIR_DOMAIN_IOTHREAD_POLL_SHRINK
,
6314 VIR_TYPED_PARAM_UINT
,
6318 if ((rc
= virTypedParamsGetULLong(params
, nparams
,
6319 VIR_DOMAIN_IOTHREAD_POLL_MAX_NS
,
6320 &iothread
->poll_max_ns
)) < 0)
6323 iothread
->set_poll_max_ns
= true;
6325 if ((rc
= virTypedParamsGetUInt(params
, nparams
,
6326 VIR_DOMAIN_IOTHREAD_POLL_GROW
,
6327 &iothread
->poll_grow
)) < 0)
6330 iothread
->set_poll_grow
= true;
6332 if ((rc
= virTypedParamsGetUInt(params
, nparams
,
6333 VIR_DOMAIN_IOTHREAD_POLL_SHRINK
,
6334 &iothread
->poll_shrink
)) < 0)
6337 iothread
->set_poll_shrink
= true;
6339 if (iothread
->set_poll_max_ns
&& iothread
->poll_max_ns
> INT_MAX
) {
6340 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
6341 _("poll-max-ns (%llu) must be less than or equal to %d"),
6342 iothread
->poll_max_ns
, INT_MAX
);
6346 if (iothread
->set_poll_grow
&& iothread
->poll_grow
> INT_MAX
) {
6347 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
6348 _("poll-grow (%u) must be less than or equal to %d"),
6349 iothread
->poll_grow
, INT_MAX
);
6353 if (iothread
->set_poll_shrink
&& iothread
->poll_shrink
> INT_MAX
) {
6354 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
6355 _("poll-shrink (%u) must be less than or equal to %d"),
6356 iothread
->poll_shrink
, INT_MAX
);
6365 VIR_DOMAIN_IOTHREAD_ACTION_ADD
,
6366 VIR_DOMAIN_IOTHREAD_ACTION_DEL
,
6367 VIR_DOMAIN_IOTHREAD_ACTION_MOD
,
6368 } virDomainIOThreadAction
;
6371 qemuDomainChgIOThread(virQEMUDriverPtr driver
,
6373 qemuMonitorIOThreadInfo iothread
,
6374 virDomainIOThreadAction action
,
6377 virQEMUDriverConfigPtr cfg
= NULL
;
6378 qemuDomainObjPrivatePtr priv
;
6379 virDomainDefPtr def
;
6380 virDomainDefPtr persistentDef
;
6383 cfg
= virQEMUDriverGetConfig(driver
);
6385 priv
= vm
->privateData
;
6387 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
6390 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
6394 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_OBJECT_IOTHREAD
)) {
6395 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
6396 _("IOThreads not supported with this binary"));
6401 case VIR_DOMAIN_IOTHREAD_ACTION_ADD
:
6402 if (qemuDomainAddIOThreadCheck(def
, iothread
.iothread_id
) < 0)
6405 if (qemuDomainHotplugAddIOThread(driver
, vm
, iothread
.iothread_id
) < 0)
6410 case VIR_DOMAIN_IOTHREAD_ACTION_DEL
:
6411 if (qemuDomainDelIOThreadCheck(def
, iothread
.iothread_id
) < 0)
6414 if (qemuDomainHotplugDelIOThread(driver
, vm
, iothread
.iothread_id
) < 0)
6419 case VIR_DOMAIN_IOTHREAD_ACTION_MOD
:
6420 if (!(virDomainIOThreadIDFind(def
, iothread
.iothread_id
))) {
6421 virReportError(VIR_ERR_INVALID_ARG
,
6422 _("cannot find IOThread '%u' in iothreadids"),
6423 iothread
.iothread_id
);
6427 if (qemuDomainHotplugModIOThread(driver
, vm
, iothread
) < 0)
6434 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
6438 if (persistentDef
) {
6440 case VIR_DOMAIN_IOTHREAD_ACTION_ADD
:
6441 if (qemuDomainAddIOThreadCheck(persistentDef
, iothread
.iothread_id
) < 0)
6444 if (!virDomainIOThreadIDAdd(persistentDef
, iothread
.iothread_id
))
6449 case VIR_DOMAIN_IOTHREAD_ACTION_DEL
:
6450 if (qemuDomainDelIOThreadCheck(persistentDef
, iothread
.iothread_id
) < 0)
6453 virDomainIOThreadIDDel(persistentDef
, iothread
.iothread_id
);
6457 case VIR_DOMAIN_IOTHREAD_ACTION_MOD
:
6458 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
6459 _("configuring persistent polling values is "
6466 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
6474 qemuDomainObjEndJob(driver
, vm
);
6477 virObjectUnref(cfg
);
6482 qemuDomainAddIOThread(virDomainPtr dom
,
6483 unsigned int iothread_id
,
6486 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
6487 virDomainObjPtr vm
= NULL
;
6488 qemuMonitorIOThreadInfo iothread
= {0};
6491 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
6492 VIR_DOMAIN_AFFECT_CONFIG
, -1);
6494 if (iothread_id
== 0) {
6495 virReportError(VIR_ERR_INVALID_ARG
, "%s",
6496 _("invalid value of 0 for iothread_id"));
6500 if (!(vm
= qemuDomObjFromDomain(dom
)))
6503 if (virDomainAddIOThreadEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
6506 iothread
.iothread_id
= iothread_id
;
6507 ret
= qemuDomainChgIOThread(driver
, vm
, iothread
,
6508 VIR_DOMAIN_IOTHREAD_ACTION_ADD
, flags
);
6511 virDomainObjEndAPI(&vm
);
6517 qemuDomainDelIOThread(virDomainPtr dom
,
6518 unsigned int iothread_id
,
6521 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
6522 virDomainObjPtr vm
= NULL
;
6523 qemuMonitorIOThreadInfo iothread
= {0};
6526 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
6527 VIR_DOMAIN_AFFECT_CONFIG
, -1);
6529 if (iothread_id
== 0) {
6530 virReportError(VIR_ERR_INVALID_ARG
, "%s",
6531 _("invalid value of 0 for iothread_id"));
6535 if (!(vm
= qemuDomObjFromDomain(dom
)))
6538 if (virDomainDelIOThreadEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
6541 iothread
.iothread_id
= iothread_id
;
6542 ret
= qemuDomainChgIOThread(driver
, vm
, iothread
,
6543 VIR_DOMAIN_IOTHREAD_ACTION_DEL
, flags
);
6546 virDomainObjEndAPI(&vm
);
6552 * @dom: Domain to set IOThread params
6553 * @iothread_id: IOThread 'id' that will be modified
6554 * @params: List of parameters to change
6555 * @nparams: Number of parameters in the list
6556 * @flags: Flags for the set (only supports live alteration)
6558 * Alter the specified @iothread_id with the values provided.
6560 * Returs 0 on success, -1 on failure
6563 qemuDomainSetIOThreadParams(virDomainPtr dom
,
6564 unsigned int iothread_id
,
6565 virTypedParameterPtr params
,
6569 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
6570 virDomainObjPtr vm
= NULL
;
6571 qemuMonitorIOThreadInfo iothread
= {0};
6574 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
, -1);
6576 if (iothread_id
== 0) {
6577 virReportError(VIR_ERR_INVALID_ARG
, "%s",
6578 _("invalid value of 0 for iothread_id"));
6582 iothread
.iothread_id
= iothread_id
;
6584 if (!(vm
= qemuDomObjFromDomain(dom
)))
6587 if (virDomainSetIOThreadParamsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
6590 if (qemuDomainIOThreadParseParams(params
, nparams
, &iothread
) < 0)
6593 ret
= qemuDomainChgIOThread(driver
, vm
, iothread
,
6594 VIR_DOMAIN_IOTHREAD_ACTION_MOD
, flags
);
6597 virDomainObjEndAPI(&vm
);
6602 static int qemuDomainGetSecurityLabel(virDomainPtr dom
, virSecurityLabelPtr seclabel
)
6604 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
6608 memset(seclabel
, 0, sizeof(*seclabel
));
6610 if (!(vm
= qemuDomObjFromDomain(dom
)))
6613 if (virDomainGetSecurityLabelEnsureACL(dom
->conn
, vm
->def
) < 0)
6617 * Theoretically, the pid can be replaced during this operation and
6618 * return the label of a different process. If atomicity is needed,
6619 * further validation will be required.
6621 * Comment from Dan Berrange:
6623 * Well the PID as stored in the virDomainObjPtr can't be changed
6624 * because you've got a locked object. The OS level PID could have
6625 * exited, though and in extreme circumstances have cycled through all
6626 * PIDs back to ours. We could sanity check that our PID still exists
6627 * after reading the label, by checking that our FD connecting to the
6628 * QEMU monitor hasn't seen SIGHUP/ERR on poll().
6630 if (virDomainObjIsActive(vm
)) {
6631 if (qemuSecurityGetProcessLabel(driver
->securityManager
,
6632 vm
->def
, vm
->pid
, seclabel
) < 0)
6639 virDomainObjEndAPI(&vm
);
6643 static int qemuDomainGetSecurityLabelList(virDomainPtr dom
,
6644 virSecurityLabelPtr
* seclabels
)
6646 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
6651 if (!(vm
= qemuDomObjFromDomain(dom
)))
6654 if (virDomainGetSecurityLabelListEnsureACL(dom
->conn
, vm
->def
) < 0)
6658 * Check the comment in qemuDomainGetSecurityLabel function.
6660 if (!virDomainObjIsActive(vm
)) {
6666 virSecurityManagerPtr
* mgrs
= qemuSecurityGetNested(driver
->securityManager
);
6670 /* Allocate seclabels array */
6671 for (i
= 0; mgrs
[i
]; i
++)
6674 if (VIR_ALLOC_N((*seclabels
), len
) < 0) {
6678 memset(*seclabels
, 0, sizeof(**seclabels
) * len
);
6680 /* Fill the array */
6681 for (i
= 0; i
< len
; i
++) {
6682 if (qemuSecurityGetProcessLabel(mgrs
[i
], vm
->def
, vm
->pid
,
6683 &(*seclabels
)[i
]) < 0) {
6685 VIR_FREE(*seclabels
);
6694 virDomainObjEndAPI(&vm
);
6699 static int qemuNodeGetSecurityModel(virConnectPtr conn
,
6700 virSecurityModelPtr secmodel
)
6702 virQEMUDriverPtr driver
= conn
->privateData
;
6705 virCapsPtr caps
= NULL
;
6707 memset(secmodel
, 0, sizeof(*secmodel
));
6709 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
6712 if (virNodeGetSecurityModelEnsureACL(conn
) < 0)
6715 /* We treat no driver as success, but simply return no data in *secmodel */
6716 if (caps
->host
.nsecModels
== 0 ||
6717 caps
->host
.secModels
[0].model
== NULL
)
6720 p
= caps
->host
.secModels
[0].model
;
6721 if (strlen(p
) >= VIR_SECURITY_MODEL_BUFLEN
-1) {
6722 virReportError(VIR_ERR_INTERNAL_ERROR
,
6723 _("security model string exceeds max %d bytes"),
6724 VIR_SECURITY_MODEL_BUFLEN
-1);
6728 strcpy(secmodel
->model
, p
);
6730 p
= caps
->host
.secModels
[0].doi
;
6731 if (strlen(p
) >= VIR_SECURITY_DOI_BUFLEN
-1) {
6732 virReportError(VIR_ERR_INTERNAL_ERROR
,
6733 _("security DOI string exceeds max %d bytes"),
6734 VIR_SECURITY_DOI_BUFLEN
-1);
6738 strcpy(secmodel
->doi
, p
);
6741 virObjectUnref(caps
);
6747 * qemuDomainSaveImageUpdateDef:
6748 * @driver: qemu driver data
6749 * @def: def of the domain from the save image
6750 * @newxml: user provided replacement XML
6752 * Returns the new domain definition in case @newxml is ABI compatible with the
6755 static virDomainDefPtr
6756 qemuDomainSaveImageUpdateDef(virQEMUDriverPtr driver
,
6757 virDomainDefPtr def
,
6760 virDomainDefPtr ret
= NULL
;
6761 virDomainDefPtr newdef_migr
= NULL
;
6762 virDomainDefPtr newdef
= NULL
;
6763 virCapsPtr caps
= NULL
;
6765 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
6768 if (!(newdef
= virDomainDefParseString(newxml
, caps
, driver
->xmlopt
, NULL
,
6769 VIR_DOMAIN_DEF_PARSE_INACTIVE
)))
6772 if (!(newdef_migr
= qemuDomainDefCopy(driver
,
6774 QEMU_DOMAIN_FORMAT_LIVE_FLAGS
|
6775 VIR_DOMAIN_XML_MIGRATABLE
)))
6778 if (!virDomainDefCheckABIStability(def
, newdef_migr
, driver
->xmlopt
)) {
6779 virErrorPtr err
= virSaveLastError();
6781 /* Due to a bug in older version of external snapshot creation
6782 * code, the XML saved in the save image was not a migratable
6783 * XML. To ensure backwards compatibility with the change of the
6784 * saved XML type, we need to check the ABI compatibility against
6785 * the user provided XML if the check against the migratable XML
6786 * fails. Snapshots created prior to v1.1.3 have this issue. */
6787 if (!virDomainDefCheckABIStability(def
, newdef
, driver
->xmlopt
)) {
6794 /* use the user provided XML */
6795 VIR_STEAL_PTR(ret
, newdef
);
6797 VIR_STEAL_PTR(ret
, newdef_migr
);
6801 virObjectUnref(caps
);
6802 virDomainDefFree(newdef
);
6803 virDomainDefFree(newdef_migr
);
6810 * qemuDomainSaveImageOpen:
6811 * @driver: qemu driver data
6812 * @path: path of the save image
6813 * @ret_def: returns domain definition created from the XML stored in the image
6814 * @ret_data: returns structure filled with data from the image header
6815 * @bypass_cache: bypass cache when opening the file
6816 * @wrapperFd: returns the file wrapper structure
6817 * @open_write: open the file for writing (for updates)
6818 * @unlink_corrupt: remove the image file if it is corrupted
6820 * Returns the opened fd of the save image file and fills the appropriate fields
6821 * on success. On error returns -1 on most failures, -3 if corrupt image was
6822 * unlinked (no error raised).
6824 static int ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
6825 qemuDomainSaveImageOpen(virQEMUDriverPtr driver
,
6827 virDomainDefPtr
*ret_def
,
6828 virQEMUSaveDataPtr
*ret_data
,
6830 virFileWrapperFdPtr
*wrapperFd
,
6832 bool unlink_corrupt
)
6835 virQEMUSaveDataPtr data
= NULL
;
6836 virQEMUSaveHeaderPtr header
;
6837 virDomainDefPtr def
= NULL
;
6838 int oflags
= open_write
? O_RDWR
: O_RDONLY
;
6839 virCapsPtr caps
= NULL
;
6844 int directFlag
= virFileDirectFdFlag();
6845 if (directFlag
< 0) {
6846 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
6847 _("bypass cache unsupported by this system"));
6850 oflags
|= directFlag
;
6853 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
6856 if ((fd
= qemuOpenFile(driver
, NULL
, path
, oflags
, NULL
)) < 0)
6859 !(*wrapperFd
= virFileWrapperFdNew(&fd
, path
,
6860 VIR_FILE_WRAPPER_BYPASS_CACHE
)))
6863 if (VIR_ALLOC(data
) < 0)
6866 header
= &data
->header
;
6867 if (saferead(fd
, header
, sizeof(*header
)) != sizeof(*header
)) {
6868 if (unlink_corrupt
) {
6869 if (VIR_CLOSE(fd
) < 0 || unlink(path
) < 0) {
6870 virReportSystemError(errno
,
6871 _("cannot remove corrupt file: %s"),
6877 virReportError(VIR_ERR_OPERATION_FAILED
,
6878 "%s", _("failed to read qemu header"));
6883 if (memcmp(header
->magic
, QEMU_SAVE_MAGIC
, sizeof(header
->magic
)) != 0) {
6884 const char *msg
= _("image magic is incorrect");
6886 if (memcmp(header
->magic
, QEMU_SAVE_PARTIAL
,
6887 sizeof(header
->magic
)) == 0) {
6888 msg
= _("save image is incomplete");
6889 if (unlink_corrupt
) {
6890 if (VIR_CLOSE(fd
) < 0 || unlink(path
) < 0) {
6891 virReportSystemError(errno
,
6892 _("cannot remove corrupt file: %s"),
6900 virReportError(VIR_ERR_OPERATION_FAILED
, "%s", msg
);
6904 if (header
->version
> QEMU_SAVE_VERSION
) {
6905 /* convert endianess and try again */
6906 bswap_header(header
);
6909 if (header
->version
> QEMU_SAVE_VERSION
) {
6910 virReportError(VIR_ERR_OPERATION_FAILED
,
6911 _("image version is not supported (%d > %d)"),
6912 header
->version
, QEMU_SAVE_VERSION
);
6916 if (header
->data_len
<= 0) {
6917 virReportError(VIR_ERR_OPERATION_FAILED
,
6918 _("invalid header data length: %d"), header
->data_len
);
6922 if (header
->cookieOffset
)
6923 xml_len
= header
->cookieOffset
;
6925 xml_len
= header
->data_len
;
6927 cookie_len
= header
->data_len
- xml_len
;
6929 if (VIR_ALLOC_N(data
->xml
, xml_len
) < 0)
6932 if (saferead(fd
, data
->xml
, xml_len
) != xml_len
) {
6933 virReportError(VIR_ERR_OPERATION_FAILED
,
6934 "%s", _("failed to read domain XML"));
6938 if (cookie_len
> 0) {
6939 if (VIR_ALLOC_N(data
->cookie
, cookie_len
) < 0)
6942 if (saferead(fd
, data
->cookie
, cookie_len
) != cookie_len
) {
6943 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
6944 _("failed to read cookie"));
6949 /* Create a domain from this XML */
6950 if (!(def
= virDomainDefParseString(data
->xml
, caps
, driver
->xmlopt
, NULL
,
6951 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
6952 VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
)))
6959 virObjectUnref(caps
);
6963 virDomainDefFree(def
);
6964 virQEMUSaveDataFree(data
);
6965 VIR_FORCE_CLOSE(fd
);
6969 static int ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6)
6970 qemuDomainSaveImageStartVM(virConnectPtr conn
,
6971 virQEMUDriverPtr driver
,
6974 virQEMUSaveDataPtr data
,
6977 qemuDomainAsyncJob asyncJob
)
6980 bool restored
= false;
6981 virObjectEventPtr event
;
6982 int intermediatefd
= -1;
6983 virCommandPtr cmd
= NULL
;
6984 char *errbuf
= NULL
;
6985 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
6986 virQEMUSaveHeaderPtr header
= &data
->header
;
6987 qemuDomainSaveCookiePtr cookie
= NULL
;
6989 if (virSaveCookieParseString(data
->cookie
, (virObjectPtr
*)&cookie
,
6990 virDomainXMLOptionGetSaveCookie(driver
->xmlopt
)) < 0)
6993 if ((header
->version
== 2) &&
6994 (header
->compressed
!= QEMU_SAVE_FORMAT_RAW
)) {
6995 if (!(cmd
= qemuCompressGetCommand(header
->compressed
)))
6998 intermediatefd
= *fd
;
7001 virCommandSetInputFD(cmd
, intermediatefd
);
7002 virCommandSetOutputFD(cmd
, fd
);
7003 virCommandSetErrorBuffer(cmd
, &errbuf
);
7004 virCommandDoAsyncIO(cmd
);
7006 if (virCommandRunAsync(cmd
, NULL
) < 0) {
7007 *fd
= intermediatefd
;
7012 /* No cookie means libvirt which saved the domain was too old to mess up
7013 * the CPU definitions.
7016 qemuDomainFixupCPUs(vm
, &cookie
->cpu
) < 0)
7019 if (qemuProcessStart(conn
, driver
, vm
, cookie
? cookie
->cpu
: NULL
,
7020 asyncJob
, "stdio", *fd
, path
, NULL
,
7021 VIR_NETDEV_VPORT_PROFILE_OP_RESTORE
,
7022 VIR_QEMU_PROCESS_START_PAUSED
|
7023 VIR_QEMU_PROCESS_START_GEN_VMID
) == 0)
7026 if (intermediatefd
!= -1) {
7027 virErrorPtr orig_err
= NULL
;
7030 /* if there was an error setting up qemu, the intermediate
7031 * process will wait forever to write to stdout, so we
7032 * must manually kill it and ignore any error related to
7035 orig_err
= virSaveLastError();
7036 VIR_FORCE_CLOSE(intermediatefd
);
7037 VIR_FORCE_CLOSE(*fd
);
7040 if (virCommandWait(cmd
, NULL
) < 0) {
7041 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_FAILED
, asyncJob
, 0);
7044 VIR_DEBUG("Decompression binary stderr: %s", NULLSTR(errbuf
));
7047 virSetError(orig_err
);
7048 virFreeError(orig_err
);
7051 VIR_FORCE_CLOSE(intermediatefd
);
7053 if (VIR_CLOSE(*fd
) < 0) {
7054 virReportSystemError(errno
, _("cannot close file: %s"), path
);
7058 virDomainAuditStart(vm
, "restored", restored
);
7062 /* qemuProcessStart doesn't unset the qemu error reporting infrastructure
7063 * in case of migration (which is used in this case) so we need to reset it
7064 * so that the handle to virtlogd is not held open unnecessarily */
7065 qemuMonitorSetDomainLog(qemuDomainGetMonitor(vm
), NULL
, NULL
, NULL
);
7067 event
= virDomainEventLifecycleNewFromObj(vm
,
7068 VIR_DOMAIN_EVENT_STARTED
,
7069 VIR_DOMAIN_EVENT_STARTED_RESTORED
);
7070 virObjectEventStateQueue(driver
->domainEventState
, event
);
7073 /* If it was running before, resume it now unless caller requested pause. */
7074 if (header
->was_running
&& !start_paused
) {
7075 if (qemuProcessStartCPUs(driver
, vm
,
7076 VIR_DOMAIN_RUNNING_RESTORED
,
7078 if (virGetLastErrorCode() == VIR_ERR_OK
)
7079 virReportError(VIR_ERR_OPERATION_FAILED
,
7080 "%s", _("failed to resume domain"));
7083 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0) {
7084 VIR_WARN("Failed to save status on vm %s", vm
->def
->name
);
7088 int detail
= (start_paused
? VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
:
7089 VIR_DOMAIN_EVENT_SUSPENDED_RESTORED
);
7090 event
= virDomainEventLifecycleNewFromObj(vm
,
7091 VIR_DOMAIN_EVENT_SUSPENDED
,
7093 virObjectEventStateQueue(driver
->domainEventState
, event
);
7099 virObjectUnref(cookie
);
7100 virCommandFree(cmd
);
7102 if (qemuSecurityRestoreSavedStateLabel(driver
, vm
, path
) < 0)
7103 VIR_WARN("failed to restore save state label on %s", path
);
7104 virObjectUnref(cfg
);
7109 qemuDomainRestoreFlags(virConnectPtr conn
,
7114 virQEMUDriverPtr driver
= conn
->privateData
;
7115 qemuDomainObjPrivatePtr priv
= NULL
;
7116 virDomainDefPtr def
= NULL
;
7117 virDomainObjPtr vm
= NULL
;
7118 char *xmlout
= NULL
;
7119 const char *newxml
= dxml
;
7122 virQEMUSaveDataPtr data
= NULL
;
7123 virFileWrapperFdPtr wrapperFd
= NULL
;
7124 bool hook_taint
= false;
7126 virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE
|
7127 VIR_DOMAIN_SAVE_RUNNING
|
7128 VIR_DOMAIN_SAVE_PAUSED
, -1);
7131 virNWFilterReadLockFilterUpdates();
7133 fd
= qemuDomainSaveImageOpen(driver
, path
, &def
, &data
,
7134 (flags
& VIR_DOMAIN_SAVE_BYPASS_CACHE
) != 0,
7135 &wrapperFd
, false, false);
7139 if (virDomainRestoreFlagsEnsureACL(conn
, def
) < 0)
7142 if (virHookPresent(VIR_HOOK_DRIVER_QEMU
)) {
7145 if ((hookret
= virHookCall(VIR_HOOK_DRIVER_QEMU
, def
->name
,
7146 VIR_HOOK_QEMU_OP_RESTORE
,
7147 VIR_HOOK_SUBOP_BEGIN
,
7149 dxml
? dxml
: data
->xml
,
7153 if (hookret
== 0 && !virStringIsEmpty(xmlout
)) {
7154 VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout
);
7161 virDomainDefPtr tmp
;
7162 if (!(tmp
= qemuDomainSaveImageUpdateDef(driver
, def
, newxml
)))
7165 virDomainDefFree(def
);
7169 if (!(vm
= virDomainObjListAdd(driver
->domains
, def
,
7171 VIR_DOMAIN_OBJ_LIST_ADD_LIVE
|
7172 VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE
,
7177 if (flags
& VIR_DOMAIN_SAVE_RUNNING
)
7178 data
->header
.was_running
= 1;
7179 else if (flags
& VIR_DOMAIN_SAVE_PAUSED
)
7180 data
->header
.was_running
= 0;
7183 priv
= vm
->privateData
;
7184 priv
->hookRun
= true;
7187 if (qemuProcessBeginJob(driver
, vm
, VIR_DOMAIN_JOB_OPERATION_RESTORE
,
7191 ret
= qemuDomainSaveImageStartVM(conn
, driver
, vm
, &fd
, data
, path
,
7192 false, QEMU_ASYNC_JOB_START
);
7194 qemuProcessEndJob(driver
, vm
);
7197 virDomainDefFree(def
);
7198 VIR_FORCE_CLOSE(fd
);
7199 if (virFileWrapperFdClose(wrapperFd
) < 0)
7201 virFileWrapperFdFree(wrapperFd
);
7202 virQEMUSaveDataFree(data
);
7205 qemuDomainRemoveInactiveJob(driver
, vm
);
7206 virDomainObjEndAPI(&vm
);
7207 virNWFilterUnlockFilterUpdates();
7212 qemuDomainRestore(virConnectPtr conn
,
7215 return qemuDomainRestoreFlags(conn
, path
, NULL
, 0);
7219 qemuDomainSaveImageGetXMLDesc(virConnectPtr conn
, const char *path
,
7222 virQEMUDriverPtr driver
= conn
->privateData
;
7224 virDomainDefPtr def
= NULL
;
7226 virQEMUSaveDataPtr data
= NULL
;
7228 virCheckFlags(VIR_DOMAIN_SAVE_IMAGE_XML_SECURE
, NULL
);
7230 fd
= qemuDomainSaveImageOpen(driver
, path
, &def
, &data
,
7231 false, NULL
, false, false);
7236 if (virDomainSaveImageGetXMLDescEnsureACL(conn
, def
, flags
) < 0)
7239 ret
= qemuDomainDefFormatXML(driver
, def
, flags
);
7242 virQEMUSaveDataFree(data
);
7243 virDomainDefFree(def
);
7244 VIR_FORCE_CLOSE(fd
);
7249 qemuDomainSaveImageDefineXML(virConnectPtr conn
, const char *path
,
7250 const char *dxml
, unsigned int flags
)
7252 virQEMUDriverPtr driver
= conn
->privateData
;
7254 virDomainDefPtr def
= NULL
;
7255 virDomainDefPtr newdef
= NULL
;
7257 virQEMUSaveDataPtr data
= NULL
;
7260 virCheckFlags(VIR_DOMAIN_SAVE_RUNNING
|
7261 VIR_DOMAIN_SAVE_PAUSED
, -1);
7263 if (flags
& VIR_DOMAIN_SAVE_RUNNING
)
7265 else if (flags
& VIR_DOMAIN_SAVE_PAUSED
)
7268 fd
= qemuDomainSaveImageOpen(driver
, path
, &def
, &data
,
7269 false, NULL
, true, false);
7274 if (virDomainSaveImageDefineXMLEnsureACL(conn
, def
) < 0)
7277 if (STREQ(data
->xml
, dxml
) &&
7278 (state
< 0 || state
== data
->header
.was_running
)) {
7279 /* no change to the XML */
7285 data
->header
.was_running
= state
;
7287 if (!(newdef
= qemuDomainSaveImageUpdateDef(driver
, def
, dxml
)))
7290 VIR_FREE(data
->xml
);
7292 if (!(data
->xml
= qemuDomainDefFormatXML(driver
, newdef
,
7293 VIR_DOMAIN_XML_INACTIVE
|
7294 VIR_DOMAIN_XML_SECURE
|
7295 VIR_DOMAIN_XML_MIGRATABLE
)))
7298 if (lseek(fd
, 0, SEEK_SET
) != 0) {
7299 virReportSystemError(errno
, _("cannot seek in '%s'"), path
);
7303 if (virQEMUSaveDataWrite(data
, fd
, path
) < 0)
7306 if (VIR_CLOSE(fd
) < 0) {
7307 virReportSystemError(errno
, _("failed to write header data to '%s'"), path
);
7314 virDomainDefFree(def
);
7315 virDomainDefFree(newdef
);
7316 VIR_FORCE_CLOSE(fd
);
7317 virQEMUSaveDataFree(data
);
7322 qemuDomainManagedSaveGetXMLDesc(virDomainPtr dom
, unsigned int flags
)
7324 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
7328 virDomainDefPtr def
= NULL
;
7330 virQEMUSaveDataPtr data
= NULL
;
7332 virCheckFlags(VIR_DOMAIN_SAVE_IMAGE_XML_SECURE
, NULL
);
7334 if (!(vm
= qemuDomObjFromDomain(dom
)))
7337 if (virDomainManagedSaveGetXMLDescEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
7340 if (!(path
= qemuDomainManagedSavePath(driver
, vm
)))
7343 if (!virFileExists(path
)) {
7344 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
7345 _("domain does not have managed save image"));
7349 if ((fd
= qemuDomainSaveImageOpen(driver
, path
, &def
, &data
,
7350 false, NULL
, false, false)) < 0)
7353 ret
= qemuDomainDefFormatXML(driver
, def
, flags
);
7356 virQEMUSaveDataFree(data
);
7357 virDomainDefFree(def
);
7358 VIR_FORCE_CLOSE(fd
);
7359 virDomainObjEndAPI(&vm
);
7365 qemuDomainManagedSaveDefineXML(virDomainPtr dom
, const char *dxml
,
7368 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
7369 virConnectPtr conn
= dom
->conn
;
7374 if (!(vm
= qemuDomObjFromDomain(dom
)))
7377 if (virDomainManagedSaveDefineXMLEnsureACL(conn
, vm
->def
) < 0)
7380 if (!(path
= qemuDomainManagedSavePath(driver
, vm
)))
7383 if (!virFileExists(path
)) {
7384 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
7385 _("domain does not have managed save image"));
7389 ret
= qemuDomainSaveImageDefineXML(conn
, path
, dxml
, flags
);
7392 virDomainObjEndAPI(&vm
);
7397 /* Return 0 on success, 1 if incomplete saved image was silently unlinked,
7398 * and -1 on failure with error raised. */
7400 qemuDomainObjRestore(virConnectPtr conn
,
7401 virQEMUDriverPtr driver
,
7406 qemuDomainAsyncJob asyncJob
)
7408 virDomainDefPtr def
= NULL
;
7409 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
7412 char *xmlout
= NULL
;
7413 virQEMUSaveDataPtr data
= NULL
;
7414 virFileWrapperFdPtr wrapperFd
= NULL
;
7416 fd
= qemuDomainSaveImageOpen(driver
, path
, &def
, &data
,
7417 bypass_cache
, &wrapperFd
, false, true);
7424 if (virHookPresent(VIR_HOOK_DRIVER_QEMU
)) {
7427 if ((hookret
= virHookCall(VIR_HOOK_DRIVER_QEMU
, def
->name
,
7428 VIR_HOOK_QEMU_OP_RESTORE
,
7429 VIR_HOOK_SUBOP_BEGIN
,
7430 NULL
, data
->xml
, &xmlout
)) < 0)
7433 if (hookret
== 0 && !virStringIsEmpty(xmlout
)) {
7434 virDomainDefPtr tmp
;
7436 VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout
);
7438 if (!(tmp
= qemuDomainSaveImageUpdateDef(driver
, def
, xmlout
)))
7441 virDomainDefFree(def
);
7443 priv
->hookRun
= true;
7447 if (STRNEQ(vm
->def
->name
, def
->name
) ||
7448 memcmp(vm
->def
->uuid
, def
->uuid
, VIR_UUID_BUFLEN
)) {
7449 char vm_uuidstr
[VIR_UUID_STRING_BUFLEN
];
7450 char def_uuidstr
[VIR_UUID_STRING_BUFLEN
];
7451 virUUIDFormat(vm
->def
->uuid
, vm_uuidstr
);
7452 virUUIDFormat(def
->uuid
, def_uuidstr
);
7453 virReportError(VIR_ERR_OPERATION_FAILED
,
7454 _("cannot restore domain '%s' uuid %s from a file"
7455 " which belongs to domain '%s' uuid %s"),
7456 vm
->def
->name
, vm_uuidstr
,
7457 def
->name
, def_uuidstr
);
7461 virDomainObjAssignDef(vm
, def
, true, NULL
);
7464 ret
= qemuDomainSaveImageStartVM(conn
, driver
, vm
, &fd
, data
, path
,
7465 start_paused
, asyncJob
);
7468 virQEMUSaveDataFree(data
);
7470 virDomainDefFree(def
);
7471 VIR_FORCE_CLOSE(fd
);
7472 if (virFileWrapperFdClose(wrapperFd
) < 0)
7474 virFileWrapperFdFree(wrapperFd
);
7480 *qemuDomainGetXMLDesc(virDomainPtr dom
,
7483 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
7487 virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS
| VIR_DOMAIN_XML_UPDATE_CPU
,
7490 if (!(vm
= qemuDomObjFromDomain(dom
)))
7493 if (virDomainGetXMLDescEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
7496 qemuDomainUpdateCurrentMemorySize(vm
);
7498 if ((flags
& VIR_DOMAIN_XML_MIGRATABLE
))
7499 flags
|= QEMU_DOMAIN_FORMAT_LIVE_FLAGS
;
7501 /* The CPU is already updated in the domain's live definition, we need to
7502 * ignore the VIR_DOMAIN_XML_UPDATE_CPU flag.
7504 if (virDomainObjIsActive(vm
) &&
7505 !(flags
& VIR_DOMAIN_XML_INACTIVE
))
7506 flags
&= ~VIR_DOMAIN_XML_UPDATE_CPU
;
7508 ret
= qemuDomainFormatXML(driver
, vm
, flags
);
7511 virDomainObjEndAPI(&vm
);
7516 static char *qemuConnectDomainXMLFromNative(virConnectPtr conn
,
7521 virQEMUDriverPtr driver
= conn
->privateData
;
7522 virDomainDefPtr def
= NULL
;
7524 virCapsPtr caps
= NULL
;
7526 virCheckFlags(0, NULL
);
7528 if (virConnectDomainXMLFromNativeEnsureACL(conn
) < 0)
7531 if (STRNEQ(format
, QEMU_CONFIG_FORMAT_ARGV
)) {
7532 virReportError(VIR_ERR_INVALID_ARG
,
7533 _("unsupported config type %s"), format
);
7537 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
7540 def
= qemuParseCommandLineString(driver
->qemuCapsCache
,
7541 caps
, driver
->xmlopt
, config
,
7546 if (!def
->name
&& VIR_STRDUP(def
->name
, "unnamed") < 0)
7549 xml
= qemuDomainDefFormatXML(driver
, def
, VIR_DOMAIN_XML_INACTIVE
);
7552 virDomainDefFree(def
);
7553 virObjectUnref(caps
);
7557 static char *qemuConnectDomainXMLToNative(virConnectPtr conn
,
7559 const char *xmlData
,
7562 virQEMUDriverPtr driver
= conn
->privateData
;
7563 virDomainObjPtr vm
= NULL
;
7564 virCommandPtr cmd
= NULL
;
7567 virQEMUDriverConfigPtr cfg
;
7568 virCapsPtr caps
= NULL
;
7570 virCheckFlags(0, NULL
);
7572 cfg
= virQEMUDriverGetConfig(driver
);
7574 if (virConnectDomainXMLToNativeEnsureACL(conn
) < 0)
7577 if (STRNEQ(format
, QEMU_CONFIG_FORMAT_ARGV
)) {
7578 virReportError(VIR_ERR_INVALID_ARG
,
7579 _("unsupported config type %s"), format
);
7583 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
7586 if (!(vm
= virDomainObjNew(driver
->xmlopt
)))
7589 if (!(vm
->def
= virDomainDefParseString(xmlData
, caps
, driver
->xmlopt
, NULL
,
7590 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
7591 VIR_DOMAIN_DEF_PARSE_ABI_UPDATE
)))
7594 /* Since we're just exporting args, we can't do bridge/network/direct
7595 * setups, since libvirt will normally create TAP/macvtap devices
7596 * directly. We convert those configs into generic 'ethernet'
7597 * config and assume the user has suitable 'ifup-qemu' scripts
7599 for (i
= 0; i
< vm
->def
->nnets
; i
++) {
7600 virDomainNetDefPtr net
= vm
->def
->nets
[i
];
7601 unsigned int bootIndex
= net
->info
.bootIndex
;
7602 char *model
= net
->model
;
7603 virMacAddr mac
= net
->mac
;
7604 char *script
= net
->script
;
7609 virDomainNetDefClear(net
);
7611 net
->type
= VIR_DOMAIN_NET_TYPE_ETHERNET
;
7612 net
->info
.bootIndex
= bootIndex
;
7615 net
->script
= script
;
7618 if (!(cmd
= qemuProcessCreatePretendCmd(driver
, vm
, NULL
,
7619 qemuCheckFips(), true,
7620 VIR_QEMU_PROCESS_START_COLD
)))
7623 ret
= virCommandToString(cmd
, false);
7626 virCommandFree(cmd
);
7628 virObjectUnref(caps
);
7629 virObjectUnref(cfg
);
7634 static int qemuConnectListDefinedDomains(virConnectPtr conn
,
7635 char **const names
, int nnames
) {
7636 virQEMUDriverPtr driver
= conn
->privateData
;
7639 if (virConnectListDefinedDomainsEnsureACL(conn
) < 0)
7642 ret
= virDomainObjListGetInactiveNames(driver
->domains
, names
, nnames
,
7643 virConnectListDefinedDomainsCheckACL
,
7650 static int qemuConnectNumOfDefinedDomains(virConnectPtr conn
)
7652 virQEMUDriverPtr driver
= conn
->privateData
;
7655 if (virConnectNumOfDefinedDomainsEnsureACL(conn
) < 0)
7658 ret
= virDomainObjListNumOfDomains(driver
->domains
, false,
7659 virConnectNumOfDefinedDomainsCheckACL
,
7668 qemuDomainObjStart(virConnectPtr conn
,
7669 virQEMUDriverPtr driver
,
7672 qemuDomainAsyncJob asyncJob
)
7676 bool start_paused
= (flags
& VIR_DOMAIN_START_PAUSED
) != 0;
7677 bool autodestroy
= (flags
& VIR_DOMAIN_START_AUTODESTROY
) != 0;
7678 bool bypass_cache
= (flags
& VIR_DOMAIN_START_BYPASS_CACHE
) != 0;
7679 bool force_boot
= (flags
& VIR_DOMAIN_START_FORCE_BOOT
) != 0;
7680 unsigned int start_flags
= VIR_QEMU_PROCESS_START_COLD
;
7681 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
7683 start_flags
|= start_paused
? VIR_QEMU_PROCESS_START_PAUSED
: 0;
7684 start_flags
|= autodestroy
? VIR_QEMU_PROCESS_START_AUTODESTROY
: 0;
7687 * If there is a managed saved state restore it instead of starting
7688 * from scratch. The old state is removed once the restoring succeeded.
7690 managed_save
= qemuDomainManagedSavePath(driver
, vm
);
7695 if (virFileExists(managed_save
)) {
7697 if (unlink(managed_save
) < 0) {
7698 virReportSystemError(errno
,
7699 _("cannot remove managed save file %s"),
7703 vm
->hasManagedSave
= false;
7705 virDomainJobOperation op
= priv
->job
.current
->operation
;
7706 priv
->job
.current
->operation
= VIR_DOMAIN_JOB_OPERATION_RESTORE
;
7708 ret
= qemuDomainObjRestore(conn
, driver
, vm
, managed_save
,
7709 start_paused
, bypass_cache
, asyncJob
);
7712 if (unlink(managed_save
) < 0)
7713 VIR_WARN("Failed to remove the managed state %s", managed_save
);
7715 vm
->hasManagedSave
= false;
7718 } else if (ret
< 0) {
7719 VIR_WARN("Unable to restore from managed state %s. "
7720 "Maybe the file is corrupted?", managed_save
);
7723 VIR_WARN("Ignoring incomplete managed state %s", managed_save
);
7724 priv
->job
.current
->operation
= op
;
7725 vm
->hasManagedSave
= false;
7730 ret
= qemuProcessStart(conn
, driver
, vm
, NULL
, asyncJob
,
7731 NULL
, -1, NULL
, NULL
,
7732 VIR_NETDEV_VPORT_PROFILE_OP_CREATE
, start_flags
);
7733 virDomainAuditStart(vm
, "booted", ret
>= 0);
7735 virObjectEventPtr event
=
7736 virDomainEventLifecycleNewFromObj(vm
,
7737 VIR_DOMAIN_EVENT_STARTED
,
7738 VIR_DOMAIN_EVENT_STARTED_BOOTED
);
7739 virObjectEventStateQueue(driver
->domainEventState
, event
);
7741 event
= virDomainEventLifecycleNewFromObj(vm
,
7742 VIR_DOMAIN_EVENT_SUSPENDED
,
7743 VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
);
7744 virObjectEventStateQueue(driver
->domainEventState
, event
);
7749 VIR_FREE(managed_save
);
7754 qemuDomainCreateWithFlags(virDomainPtr dom
, unsigned int flags
)
7756 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
7760 virCheckFlags(VIR_DOMAIN_START_PAUSED
|
7761 VIR_DOMAIN_START_AUTODESTROY
|
7762 VIR_DOMAIN_START_BYPASS_CACHE
|
7763 VIR_DOMAIN_START_FORCE_BOOT
, -1);
7765 virNWFilterReadLockFilterUpdates();
7767 if (!(vm
= qemuDomObjFromDomain(dom
)))
7770 if (virDomainCreateWithFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
7773 if (qemuProcessBeginJob(driver
, vm
, VIR_DOMAIN_JOB_OPERATION_START
,
7777 if (virDomainObjIsActive(vm
)) {
7778 virReportError(VIR_ERR_OPERATION_INVALID
,
7779 "%s", _("domain is already running"));
7783 if (qemuDomainObjStart(dom
->conn
, driver
, vm
, flags
,
7784 QEMU_ASYNC_JOB_START
) < 0)
7787 dom
->id
= vm
->def
->id
;
7791 qemuProcessEndJob(driver
, vm
);
7794 virDomainObjEndAPI(&vm
);
7795 virNWFilterUnlockFilterUpdates();
7800 qemuDomainCreate(virDomainPtr dom
)
7802 return qemuDomainCreateWithFlags(dom
, 0);
7806 qemuDomainDefineXMLFlags(virConnectPtr conn
,
7810 virQEMUDriverPtr driver
= conn
->privateData
;
7811 virDomainDefPtr def
= NULL
;
7812 virDomainDefPtr oldDef
= NULL
;
7813 virDomainObjPtr vm
= NULL
;
7814 virDomainPtr dom
= NULL
;
7815 virObjectEventPtr event
= NULL
;
7816 virQEMUDriverConfigPtr cfg
;
7817 virCapsPtr caps
= NULL
;
7818 unsigned int parse_flags
= VIR_DOMAIN_DEF_PARSE_INACTIVE
|
7819 VIR_DOMAIN_DEF_PARSE_ABI_UPDATE
;
7821 virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE
, NULL
);
7823 if (flags
& VIR_DOMAIN_DEFINE_VALIDATE
)
7824 parse_flags
|= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA
;
7826 cfg
= virQEMUDriverGetConfig(driver
);
7828 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
7831 if (!(def
= virDomainDefParseString(xml
, caps
, driver
->xmlopt
,
7832 NULL
, parse_flags
)))
7835 if (virXMLCheckIllegalChars("name", def
->name
, "\n") < 0)
7838 if (virDomainDefineXMLFlagsEnsureACL(conn
, def
) < 0)
7841 if (!(vm
= virDomainObjListAdd(driver
->domains
, def
,
7849 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
7850 vm
->newDef
? vm
->newDef
: vm
->def
) < 0) {
7852 /* There is backup so this VM was defined before.
7853 * Just restore the backup. */
7854 VIR_INFO("Restoring domain '%s' definition", vm
->def
->name
);
7855 if (virDomainObjIsActive(vm
))
7856 vm
->newDef
= oldDef
;
7861 /* Brand new domain. Remove it */
7862 VIR_INFO("Deleting domain '%s'", vm
->def
->name
);
7864 qemuDomainRemoveInactiveJob(driver
, vm
);
7869 event
= virDomainEventLifecycleNewFromObj(vm
,
7870 VIR_DOMAIN_EVENT_DEFINED
,
7872 VIR_DOMAIN_EVENT_DEFINED_ADDED
:
7873 VIR_DOMAIN_EVENT_DEFINED_UPDATED
);
7875 VIR_INFO("Creating domain '%s'", vm
->def
->name
);
7876 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
7879 virDomainDefFree(oldDef
);
7880 virDomainDefFree(def
);
7881 virDomainObjEndAPI(&vm
);
7882 virObjectEventStateQueue(driver
->domainEventState
, event
);
7883 virObjectUnref(caps
);
7884 virObjectUnref(cfg
);
7889 qemuDomainDefineXML(virConnectPtr conn
, const char *xml
)
7891 return qemuDomainDefineXMLFlags(conn
, xml
, 0);
7895 qemuDomainUndefineFlags(virDomainPtr dom
,
7898 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
7900 virObjectEventPtr event
= NULL
;
7904 virQEMUDriverConfigPtr cfg
= NULL
;
7906 virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE
|
7907 VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA
|
7908 VIR_DOMAIN_UNDEFINE_NVRAM
|
7909 VIR_DOMAIN_UNDEFINE_KEEP_NVRAM
, -1);
7911 if ((flags
& VIR_DOMAIN_UNDEFINE_NVRAM
) &&
7912 (flags
& VIR_DOMAIN_UNDEFINE_KEEP_NVRAM
)) {
7913 virReportError(VIR_ERR_OPERATION_INVALID
,
7914 "%s", _("cannot both keep and delete nvram"));
7918 if (!(vm
= qemuDomObjFromDomain(dom
)))
7921 cfg
= virQEMUDriverGetConfig(driver
);
7923 if (virDomainUndefineFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
7926 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
7929 if (!vm
->persistent
) {
7930 virReportError(VIR_ERR_OPERATION_INVALID
,
7931 "%s", _("cannot undefine transient domain"));
7935 if (!virDomainObjIsActive(vm
) &&
7936 (nsnapshots
= virDomainSnapshotObjListNum(vm
->snapshots
, NULL
, 0))) {
7937 if (!(flags
& VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA
)) {
7938 virReportError(VIR_ERR_OPERATION_INVALID
,
7939 _("cannot delete inactive domain with %d "
7944 if (qemuDomainSnapshotDiscardAllMetadata(driver
, vm
) < 0)
7947 /* TODO: Restrict deletion if checkpoints exist? */
7949 name
= qemuDomainManagedSavePath(driver
, vm
);
7953 if (virFileExists(name
)) {
7954 if (flags
& VIR_DOMAIN_UNDEFINE_MANAGED_SAVE
) {
7955 if (unlink(name
) < 0) {
7956 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
7957 _("Failed to remove domain managed "
7962 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
7963 _("Refusing to undefine while domain managed "
7964 "save image exists"));
7969 if (vm
->def
->os
.loader
&&
7970 vm
->def
->os
.loader
->nvram
&&
7971 virFileExists(vm
->def
->os
.loader
->nvram
)) {
7972 if ((flags
& VIR_DOMAIN_UNDEFINE_NVRAM
)) {
7973 if (unlink(vm
->def
->os
.loader
->nvram
) < 0) {
7974 virReportSystemError(errno
,
7975 _("failed to remove nvram: %s"),
7976 vm
->def
->os
.loader
->nvram
);
7979 } else if (!(flags
& VIR_DOMAIN_UNDEFINE_KEEP_NVRAM
)) {
7980 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
7981 _("cannot undefine domain with nvram"));
7986 if (virDomainDeleteConfig(cfg
->configDir
, cfg
->autostartDir
, vm
) < 0)
7989 event
= virDomainEventLifecycleNewFromObj(vm
,
7990 VIR_DOMAIN_EVENT_UNDEFINED
,
7991 VIR_DOMAIN_EVENT_UNDEFINED_REMOVED
);
7993 VIR_INFO("Undefining domain '%s'", vm
->def
->name
);
7995 /* If the domain is active, keep it running but set it as transient.
7996 * domainDestroy and domainShutdown will take care of removing the
7997 * domain obj from the hash table.
8000 if (!virDomainObjIsActive(vm
))
8001 qemuDomainRemoveInactive(driver
, vm
);
8005 qemuDomainObjEndJob(driver
, vm
);
8009 virDomainObjEndAPI(&vm
);
8010 virObjectEventStateQueue(driver
->domainEventState
, event
);
8011 virObjectUnref(cfg
);
8016 qemuDomainUndefine(virDomainPtr dom
)
8018 return qemuDomainUndefineFlags(dom
, 0);
8022 qemuDomainAttachDeviceLive(virDomainObjPtr vm
,
8023 virDomainDeviceDefPtr dev
,
8024 virQEMUDriverPtr driver
)
8027 const char *alias
= NULL
;
8029 switch ((virDomainDeviceType
)dev
->type
) {
8030 case VIR_DOMAIN_DEVICE_DISK
:
8031 qemuDomainObjCheckDiskTaint(driver
, vm
, dev
->data
.disk
, NULL
);
8032 ret
= qemuDomainAttachDeviceDiskLive(driver
, vm
, dev
);
8034 alias
= dev
->data
.disk
->info
.alias
;
8035 dev
->data
.disk
= NULL
;
8039 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8040 ret
= qemuDomainAttachControllerDevice(driver
, vm
, dev
->data
.controller
);
8042 alias
= dev
->data
.controller
->info
.alias
;
8043 dev
->data
.controller
= NULL
;
8047 case VIR_DOMAIN_DEVICE_LEASE
:
8048 ret
= qemuDomainAttachLease(driver
, vm
,
8051 dev
->data
.lease
= NULL
;
8054 case VIR_DOMAIN_DEVICE_NET
:
8055 qemuDomainObjCheckNetTaint(driver
, vm
, dev
->data
.net
, NULL
);
8056 ret
= qemuDomainAttachNetDevice(driver
, vm
, dev
->data
.net
);
8058 alias
= dev
->data
.net
->info
.alias
;
8059 dev
->data
.net
= NULL
;
8063 case VIR_DOMAIN_DEVICE_HOSTDEV
:
8064 qemuDomainObjCheckHostdevTaint(driver
, vm
, dev
->data
.hostdev
, NULL
);
8065 ret
= qemuDomainAttachHostDevice(driver
, vm
,
8068 alias
= dev
->data
.hostdev
->info
->alias
;
8069 dev
->data
.hostdev
= NULL
;
8073 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8074 ret
= qemuDomainAttachRedirdevDevice(driver
, vm
,
8075 dev
->data
.redirdev
);
8077 alias
= dev
->data
.redirdev
->info
.alias
;
8078 dev
->data
.redirdev
= NULL
;
8082 case VIR_DOMAIN_DEVICE_CHR
:
8083 ret
= qemuDomainAttachChrDevice(driver
, vm
,
8086 alias
= dev
->data
.chr
->info
.alias
;
8087 dev
->data
.chr
= NULL
;
8091 case VIR_DOMAIN_DEVICE_RNG
:
8092 ret
= qemuDomainAttachRNGDevice(driver
, vm
,
8095 alias
= dev
->data
.rng
->info
.alias
;
8096 dev
->data
.rng
= NULL
;
8100 case VIR_DOMAIN_DEVICE_MEMORY
:
8101 /* note that qemuDomainAttachMemory always consumes dev->data.memory
8102 * and dispatches DeviceAdded event on success */
8103 ret
= qemuDomainAttachMemory(driver
, vm
,
8105 dev
->data
.memory
= NULL
;
8108 case VIR_DOMAIN_DEVICE_SHMEM
:
8109 ret
= qemuDomainAttachShmemDevice(driver
, vm
,
8112 alias
= dev
->data
.shmem
->info
.alias
;
8113 dev
->data
.shmem
= NULL
;
8117 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8118 ret
= qemuDomainAttachWatchdog(driver
, vm
,
8119 dev
->data
.watchdog
);
8121 alias
= dev
->data
.watchdog
->info
.alias
;
8122 dev
->data
.watchdog
= NULL
;
8126 case VIR_DOMAIN_DEVICE_INPUT
:
8127 ret
= qemuDomainAttachInputDevice(driver
, vm
, dev
->data
.input
);
8129 alias
= dev
->data
.input
->info
.alias
;
8130 dev
->data
.input
= NULL
;
8134 case VIR_DOMAIN_DEVICE_VSOCK
:
8135 ret
= qemuDomainAttachVsockDevice(driver
, vm
, dev
->data
.vsock
);
8137 alias
= dev
->data
.vsock
->info
.alias
;
8138 dev
->data
.vsock
= NULL
;
8142 case VIR_DOMAIN_DEVICE_NONE
:
8143 case VIR_DOMAIN_DEVICE_FS
:
8144 case VIR_DOMAIN_DEVICE_SOUND
:
8145 case VIR_DOMAIN_DEVICE_VIDEO
:
8146 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8147 case VIR_DOMAIN_DEVICE_HUB
:
8148 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8149 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8150 case VIR_DOMAIN_DEVICE_NVRAM
:
8151 case VIR_DOMAIN_DEVICE_TPM
:
8152 case VIR_DOMAIN_DEVICE_PANIC
:
8153 case VIR_DOMAIN_DEVICE_IOMMU
:
8154 case VIR_DOMAIN_DEVICE_LAST
:
8155 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
8156 _("live attach of device '%s' is not supported"),
8157 virDomainDeviceTypeToString(dev
->type
));
8162 /* queue the event before the alias has a chance to get freed
8163 * if the domain disappears while qemuDomainUpdateDeviceList
8165 virObjectEventPtr event
;
8166 event
= virDomainEventDeviceAddedNewFromObj(vm
, alias
);
8167 virObjectEventStateQueue(driver
->domainEventState
, event
);
8171 ret
= qemuDomainUpdateDeviceList(driver
, vm
, QEMU_ASYNC_JOB_NONE
);
8178 qemuDomainChangeDiskLive(virDomainObjPtr vm
,
8179 virDomainDeviceDefPtr dev
,
8180 virQEMUDriverPtr driver
,
8183 virDomainDiskDefPtr disk
= dev
->data
.disk
;
8184 virDomainDiskDefPtr orig_disk
= NULL
;
8185 virDomainDeviceDef oldDev
= { .type
= dev
->type
};
8188 if (!(orig_disk
= virDomainDiskFindByBusAndDst(vm
->def
,
8189 disk
->bus
, disk
->dst
))) {
8190 virReportError(VIR_ERR_INTERNAL_ERROR
,
8191 _("No device with bus '%s' and target '%s'"),
8192 virDomainDiskBusTypeToString(disk
->bus
),
8197 oldDev
.data
.disk
= orig_disk
;
8198 if (virDomainDefCompatibleDevice(vm
->def
, dev
, &oldDev
,
8199 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8203 if (!qemuDomainDiskChangeSupported(disk
, orig_disk
))
8206 if (!virStorageSourceIsSameLocation(disk
->src
, orig_disk
->src
)) {
8207 /* Disk source can be changed only for removable devices */
8208 if (disk
->device
!= VIR_DOMAIN_DISK_DEVICE_CDROM
&&
8209 disk
->device
!= VIR_DOMAIN_DISK_DEVICE_FLOPPY
) {
8210 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
8211 _("disk source can be changed only in removable "
8216 if (qemuDomainChangeEjectableMedia(driver
, vm
, orig_disk
,
8217 dev
->data
.disk
->src
, force
) < 0)
8220 dev
->data
.disk
->src
= NULL
;
8223 orig_disk
->startupPolicy
= dev
->data
.disk
->startupPolicy
;
8224 orig_disk
->snapshot
= dev
->data
.disk
->snapshot
;
8232 qemuDomainUpdateDeviceLive(virDomainObjPtr vm
,
8233 virDomainDeviceDefPtr dev
,
8237 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
8238 virDomainDeviceDef oldDev
= { .type
= dev
->type
};
8242 switch ((virDomainDeviceType
)dev
->type
) {
8243 case VIR_DOMAIN_DEVICE_DISK
:
8244 qemuDomainObjCheckDiskTaint(driver
, vm
, dev
->data
.disk
, NULL
);
8245 ret
= qemuDomainChangeDiskLive(vm
, dev
, driver
, force
);
8248 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8249 if ((idx
= qemuDomainFindGraphicsIndex(vm
->def
, dev
->data
.graphics
)) >= 0) {
8250 oldDev
.data
.graphics
= vm
->def
->graphics
[idx
];
8251 if (virDomainDefCompatibleDevice(vm
->def
, dev
, &oldDev
,
8252 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8257 ret
= qemuDomainChangeGraphics(driver
, vm
, dev
->data
.graphics
);
8260 case VIR_DOMAIN_DEVICE_NET
:
8261 if ((idx
= virDomainNetFindIdx(vm
->def
, dev
->data
.net
)) >= 0) {
8262 oldDev
.data
.net
= vm
->def
->nets
[idx
];
8263 if (virDomainDefCompatibleDevice(vm
->def
, dev
, &oldDev
,
8264 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8269 ret
= qemuDomainChangeNet(driver
, vm
, dev
);
8272 case VIR_DOMAIN_DEVICE_FS
:
8273 case VIR_DOMAIN_DEVICE_INPUT
:
8274 case VIR_DOMAIN_DEVICE_SOUND
:
8275 case VIR_DOMAIN_DEVICE_VIDEO
:
8276 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8277 case VIR_DOMAIN_DEVICE_HUB
:
8278 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8279 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8280 case VIR_DOMAIN_DEVICE_NVRAM
:
8281 case VIR_DOMAIN_DEVICE_RNG
:
8282 case VIR_DOMAIN_DEVICE_SHMEM
:
8283 case VIR_DOMAIN_DEVICE_LEASE
:
8284 case VIR_DOMAIN_DEVICE_HOSTDEV
:
8285 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8286 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8287 case VIR_DOMAIN_DEVICE_MEMORY
:
8288 case VIR_DOMAIN_DEVICE_CHR
:
8289 case VIR_DOMAIN_DEVICE_NONE
:
8290 case VIR_DOMAIN_DEVICE_TPM
:
8291 case VIR_DOMAIN_DEVICE_PANIC
:
8292 case VIR_DOMAIN_DEVICE_IOMMU
:
8293 case VIR_DOMAIN_DEVICE_VSOCK
:
8294 case VIR_DOMAIN_DEVICE_LAST
:
8295 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
8296 _("live update of device '%s' is not supported"),
8297 virDomainDeviceTypeToString(dev
->type
));
8305 qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef
,
8306 virDomainDeviceDefPtr dev
,
8308 unsigned int parse_flags
,
8309 virDomainXMLOptionPtr xmlopt
)
8311 virDomainDiskDefPtr disk
;
8312 virDomainNetDefPtr net
;
8313 virDomainHostdevDefPtr hostdev
;
8314 virDomainLeaseDefPtr lease
;
8315 virDomainControllerDefPtr controller
;
8316 virDomainFSDefPtr fs
;
8317 virDomainRedirdevDefPtr redirdev
;
8318 virDomainShmemDefPtr shmem
;
8320 switch ((virDomainDeviceType
)dev
->type
) {
8321 case VIR_DOMAIN_DEVICE_DISK
:
8322 disk
= dev
->data
.disk
;
8323 if (virDomainDiskIndexByName(vmdef
, disk
->dst
, true) >= 0) {
8324 virReportError(VIR_ERR_OPERATION_INVALID
,
8325 _("target %s already exists"), disk
->dst
);
8328 if (virDomainDiskTranslateSourcePool(disk
) < 0)
8330 if (qemuCheckDiskConfig(disk
, NULL
) < 0)
8332 if (virDomainDiskInsert(vmdef
, disk
))
8334 /* vmdef has the pointer. Generic codes for vmdef will do all jobs */
8335 dev
->data
.disk
= NULL
;
8338 case VIR_DOMAIN_DEVICE_NET
:
8339 net
= dev
->data
.net
;
8340 if (virDomainNetInsert(vmdef
, net
))
8342 dev
->data
.net
= NULL
;
8345 case VIR_DOMAIN_DEVICE_HOSTDEV
:
8346 hostdev
= dev
->data
.hostdev
;
8347 if (virDomainHostdevFind(vmdef
, hostdev
, NULL
) >= 0) {
8348 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
8349 _("device is already in the domain configuration"));
8352 if (virDomainHostdevInsert(vmdef
, hostdev
))
8354 dev
->data
.hostdev
= NULL
;
8357 case VIR_DOMAIN_DEVICE_LEASE
:
8358 lease
= dev
->data
.lease
;
8359 if (virDomainLeaseIndex(vmdef
, lease
) >= 0) {
8360 virReportError(VIR_ERR_OPERATION_INVALID
,
8361 _("Lease %s in lockspace %s already exists"),
8362 lease
->key
, NULLSTR(lease
->lockspace
));
8365 if (virDomainLeaseInsert(vmdef
, lease
) < 0)
8368 /* vmdef has the pointer. Generic codes for vmdef will do all jobs */
8369 dev
->data
.lease
= NULL
;
8372 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8373 controller
= dev
->data
.controller
;
8374 if (controller
->idx
!= -1 &&
8375 virDomainControllerFind(vmdef
, controller
->type
,
8376 controller
->idx
) >= 0) {
8377 virReportError(VIR_ERR_OPERATION_INVALID
,
8378 _("controller index='%d' already exists"),
8383 if (virDomainControllerInsert(vmdef
, controller
) < 0)
8385 dev
->data
.controller
= NULL
;
8389 case VIR_DOMAIN_DEVICE_CHR
:
8390 if (qemuDomainChrInsert(vmdef
, dev
->data
.chr
) < 0)
8392 dev
->data
.chr
= NULL
;
8395 case VIR_DOMAIN_DEVICE_FS
:
8397 if (virDomainFSIndexByName(vmdef
, fs
->dst
) >= 0) {
8398 virReportError(VIR_ERR_OPERATION_INVALID
,
8399 "%s", _("Target already exists"));
8403 if (virDomainFSInsert(vmdef
, fs
) < 0)
8405 dev
->data
.fs
= NULL
;
8408 case VIR_DOMAIN_DEVICE_RNG
:
8409 if (dev
->data
.rng
->info
.type
!= VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
&&
8410 virDomainDefHasDeviceAddress(vmdef
, &dev
->data
.rng
->info
)) {
8411 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
8412 _("a device with the same address already exists "));
8416 if (VIR_APPEND_ELEMENT(vmdef
->rngs
, vmdef
->nrngs
, dev
->data
.rng
) < 0)
8418 dev
->data
.rng
= NULL
;
8422 case VIR_DOMAIN_DEVICE_MEMORY
:
8423 if (vmdef
->nmems
== vmdef
->mem
.memory_slots
) {
8424 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
8425 _("no free memory device slot available"));
8429 vmdef
->mem
.cur_balloon
+= dev
->data
.memory
->size
;
8431 if (virDomainMemoryInsert(vmdef
, dev
->data
.memory
) < 0)
8433 dev
->data
.memory
= NULL
;
8436 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8437 redirdev
= dev
->data
.redirdev
;
8439 if (VIR_APPEND_ELEMENT(vmdef
->redirdevs
, vmdef
->nredirdevs
, redirdev
) < 0)
8441 dev
->data
.redirdev
= NULL
;
8444 case VIR_DOMAIN_DEVICE_SHMEM
:
8445 shmem
= dev
->data
.shmem
;
8446 if (virDomainShmemDefFind(vmdef
, shmem
) >= 0) {
8447 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
8448 _("device is already in the domain configuration"));
8451 if (virDomainShmemDefInsert(vmdef
, shmem
) < 0)
8453 dev
->data
.shmem
= NULL
;
8456 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8457 if (vmdef
->watchdog
) {
8458 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
8459 _("domain already has a watchdog"));
8462 VIR_STEAL_PTR(vmdef
->watchdog
, dev
->data
.watchdog
);
8465 case VIR_DOMAIN_DEVICE_INPUT
:
8466 if (VIR_APPEND_ELEMENT(vmdef
->inputs
, vmdef
->ninputs
, dev
->data
.input
) < 0)
8470 case VIR_DOMAIN_DEVICE_VSOCK
:
8472 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
8473 _("domain already has a vsock device"));
8476 VIR_STEAL_PTR(vmdef
->vsock
, dev
->data
.vsock
);
8479 case VIR_DOMAIN_DEVICE_SOUND
:
8480 case VIR_DOMAIN_DEVICE_VIDEO
:
8481 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8482 case VIR_DOMAIN_DEVICE_HUB
:
8483 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8484 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8485 case VIR_DOMAIN_DEVICE_NVRAM
:
8486 case VIR_DOMAIN_DEVICE_NONE
:
8487 case VIR_DOMAIN_DEVICE_TPM
:
8488 case VIR_DOMAIN_DEVICE_PANIC
:
8489 case VIR_DOMAIN_DEVICE_IOMMU
:
8490 case VIR_DOMAIN_DEVICE_LAST
:
8491 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
8492 _("persistent attach of device '%s' is not supported"),
8493 virDomainDeviceTypeToString(dev
->type
));
8497 if (virDomainDefPostParse(vmdef
, caps
, parse_flags
, xmlopt
, NULL
) < 0)
8505 qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef
,
8506 virDomainDeviceDefPtr dev
,
8508 unsigned int parse_flags
,
8509 virDomainXMLOptionPtr xmlopt
)
8511 virDomainDiskDefPtr disk
, det_disk
;
8512 virDomainNetDefPtr net
;
8513 virDomainHostdevDefPtr hostdev
, det_hostdev
;
8514 virDomainLeaseDefPtr lease
, det_lease
;
8515 virDomainControllerDefPtr cont
, det_cont
;
8516 virDomainChrDefPtr chr
;
8517 virDomainFSDefPtr fs
;
8518 virDomainMemoryDefPtr mem
;
8521 switch ((virDomainDeviceType
)dev
->type
) {
8522 case VIR_DOMAIN_DEVICE_DISK
:
8523 disk
= dev
->data
.disk
;
8524 if (!(det_disk
= virDomainDiskRemoveByName(vmdef
, disk
->dst
))) {
8525 virReportError(VIR_ERR_DEVICE_MISSING
,
8526 _("no target device %s"), disk
->dst
);
8529 virDomainDiskDefFree(det_disk
);
8532 case VIR_DOMAIN_DEVICE_NET
:
8533 net
= dev
->data
.net
;
8534 if ((idx
= virDomainNetFindIdx(vmdef
, net
)) < 0)
8537 /* this is guaranteed to succeed */
8538 virDomainNetDefFree(virDomainNetRemove(vmdef
, idx
));
8541 case VIR_DOMAIN_DEVICE_HOSTDEV
: {
8542 hostdev
= dev
->data
.hostdev
;
8543 if ((idx
= virDomainHostdevFind(vmdef
, hostdev
, &det_hostdev
)) < 0) {
8544 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8545 _("device not present in domain configuration"));
8548 virDomainHostdevRemove(vmdef
, idx
);
8549 virDomainHostdevDefFree(det_hostdev
);
8553 case VIR_DOMAIN_DEVICE_LEASE
:
8554 lease
= dev
->data
.lease
;
8555 if (!(det_lease
= virDomainLeaseRemove(vmdef
, lease
))) {
8556 virReportError(VIR_ERR_DEVICE_MISSING
,
8557 _("Lease %s in lockspace %s does not exist"),
8558 lease
->key
, NULLSTR(lease
->lockspace
));
8561 virDomainLeaseDefFree(det_lease
);
8564 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8565 cont
= dev
->data
.controller
;
8566 if ((idx
= virDomainControllerFind(vmdef
, cont
->type
,
8568 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8569 _("device not present in domain configuration"));
8572 det_cont
= virDomainControllerRemove(vmdef
, idx
);
8573 virDomainControllerDefFree(det_cont
);
8577 case VIR_DOMAIN_DEVICE_CHR
:
8578 if (!(chr
= qemuDomainChrRemove(vmdef
, dev
->data
.chr
)))
8581 virDomainChrDefFree(chr
);
8584 case VIR_DOMAIN_DEVICE_FS
:
8586 idx
= virDomainFSIndexByName(vmdef
, fs
->dst
);
8588 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8589 _("no matching filesystem device was found"));
8593 fs
= virDomainFSRemove(vmdef
, idx
);
8594 virDomainFSDefFree(fs
);
8597 case VIR_DOMAIN_DEVICE_RNG
:
8598 if ((idx
= virDomainRNGFind(vmdef
, dev
->data
.rng
)) < 0) {
8599 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8600 _("no matching RNG device was found"));
8604 virDomainRNGDefFree(virDomainRNGRemove(vmdef
, idx
));
8607 case VIR_DOMAIN_DEVICE_MEMORY
:
8608 if ((idx
= virDomainMemoryFindInactiveByDef(vmdef
,
8609 dev
->data
.memory
)) < 0) {
8610 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8611 _("matching memory device was not found"));
8614 mem
= virDomainMemoryRemove(vmdef
, idx
);
8615 vmdef
->mem
.cur_balloon
-= mem
->size
;
8616 virDomainMemoryDefFree(mem
);
8619 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8620 if ((idx
= virDomainRedirdevDefFind(vmdef
,
8621 dev
->data
.redirdev
)) < 0) {
8622 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8623 _("no matching redirdev was not found"));
8627 virDomainRedirdevDefFree(virDomainRedirdevDefRemove(vmdef
, idx
));
8630 case VIR_DOMAIN_DEVICE_SHMEM
:
8631 if ((idx
= virDomainShmemDefFind(vmdef
, dev
->data
.shmem
)) < 0) {
8632 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8633 _("matching shmem device was not found"));
8637 virDomainShmemDefFree(virDomainShmemDefRemove(vmdef
, idx
));
8641 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8642 if (!vmdef
->watchdog
) {
8643 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8644 _("domain has no watchdog"));
8647 virDomainWatchdogDefFree(vmdef
->watchdog
);
8648 vmdef
->watchdog
= NULL
;
8651 case VIR_DOMAIN_DEVICE_INPUT
:
8652 if ((idx
= virDomainInputDefFind(vmdef
, dev
->data
.input
)) < 0) {
8653 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8654 _("matching input device not found"));
8657 VIR_DELETE_ELEMENT(vmdef
->inputs
, idx
, vmdef
->ninputs
);
8660 case VIR_DOMAIN_DEVICE_VSOCK
:
8661 if (!vmdef
->vsock
||
8662 !virDomainVsockDefEquals(dev
->data
.vsock
, vmdef
->vsock
)) {
8663 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
8664 _("matching vsock device not found"));
8667 virDomainVsockDefFree(vmdef
->vsock
);
8668 vmdef
->vsock
= NULL
;
8671 case VIR_DOMAIN_DEVICE_SOUND
:
8672 case VIR_DOMAIN_DEVICE_VIDEO
:
8673 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8674 case VIR_DOMAIN_DEVICE_HUB
:
8675 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8676 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8677 case VIR_DOMAIN_DEVICE_NVRAM
:
8678 case VIR_DOMAIN_DEVICE_NONE
:
8679 case VIR_DOMAIN_DEVICE_TPM
:
8680 case VIR_DOMAIN_DEVICE_PANIC
:
8681 case VIR_DOMAIN_DEVICE_IOMMU
:
8682 case VIR_DOMAIN_DEVICE_LAST
:
8683 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
8684 _("persistent detach of device '%s' is not supported"),
8685 virDomainDeviceTypeToString(dev
->type
));
8689 if (virDomainDefPostParse(vmdef
, caps
, parse_flags
, xmlopt
, NULL
) < 0)
8696 qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef
,
8697 virDomainDeviceDefPtr dev
,
8699 unsigned int parse_flags
,
8700 virDomainXMLOptionPtr xmlopt
)
8702 virDomainDiskDefPtr newDisk
;
8703 virDomainGraphicsDefPtr newGraphics
;
8704 virDomainNetDefPtr net
;
8705 virDomainDeviceDef oldDev
= { .type
= dev
->type
};
8708 switch ((virDomainDeviceType
)dev
->type
) {
8709 case VIR_DOMAIN_DEVICE_DISK
:
8710 newDisk
= dev
->data
.disk
;
8711 if ((pos
= virDomainDiskIndexByName(vmdef
, newDisk
->dst
, false)) < 0) {
8712 virReportError(VIR_ERR_INVALID_ARG
,
8713 _("target %s doesn't exist."), newDisk
->dst
);
8717 oldDev
.data
.disk
= vmdef
->disks
[pos
];
8718 if (virDomainDefCompatibleDevice(vmdef
, dev
, &oldDev
,
8719 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8723 virDomainDiskDefFree(vmdef
->disks
[pos
]);
8724 vmdef
->disks
[pos
] = newDisk
;
8725 dev
->data
.disk
= NULL
;
8728 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8729 newGraphics
= dev
->data
.graphics
;
8730 pos
= qemuDomainFindGraphicsIndex(vmdef
, newGraphics
);
8732 virReportError(VIR_ERR_INVALID_ARG
,
8733 _("cannot find existing graphics type '%s' device to modify"),
8734 virDomainGraphicsTypeToString(newGraphics
->type
));
8738 oldDev
.data
.graphics
= vmdef
->graphics
[pos
];
8739 if (virDomainDefCompatibleDevice(vmdef
, dev
, &oldDev
,
8740 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8744 virDomainGraphicsDefFree(vmdef
->graphics
[pos
]);
8745 vmdef
->graphics
[pos
] = newGraphics
;
8746 dev
->data
.graphics
= NULL
;
8749 case VIR_DOMAIN_DEVICE_NET
:
8750 net
= dev
->data
.net
;
8751 if ((pos
= virDomainNetFindIdx(vmdef
, net
)) < 0)
8754 oldDev
.data
.net
= vmdef
->nets
[pos
];
8755 if (virDomainDefCompatibleDevice(vmdef
, dev
, &oldDev
,
8756 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8760 virDomainNetDefFree(vmdef
->nets
[pos
]);
8761 vmdef
->nets
[pos
] = net
;
8762 dev
->data
.net
= NULL
;
8765 case VIR_DOMAIN_DEVICE_FS
:
8766 case VIR_DOMAIN_DEVICE_INPUT
:
8767 case VIR_DOMAIN_DEVICE_SOUND
:
8768 case VIR_DOMAIN_DEVICE_VIDEO
:
8769 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8770 case VIR_DOMAIN_DEVICE_HUB
:
8771 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8772 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8773 case VIR_DOMAIN_DEVICE_NVRAM
:
8774 case VIR_DOMAIN_DEVICE_RNG
:
8775 case VIR_DOMAIN_DEVICE_SHMEM
:
8776 case VIR_DOMAIN_DEVICE_LEASE
:
8777 case VIR_DOMAIN_DEVICE_HOSTDEV
:
8778 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8779 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8780 case VIR_DOMAIN_DEVICE_CHR
:
8781 case VIR_DOMAIN_DEVICE_MEMORY
:
8782 case VIR_DOMAIN_DEVICE_NONE
:
8783 case VIR_DOMAIN_DEVICE_TPM
:
8784 case VIR_DOMAIN_DEVICE_PANIC
:
8785 case VIR_DOMAIN_DEVICE_IOMMU
:
8786 case VIR_DOMAIN_DEVICE_VSOCK
:
8787 case VIR_DOMAIN_DEVICE_LAST
:
8788 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
8789 _("persistent update of device '%s' is not supported"),
8790 virDomainDeviceTypeToString(dev
->type
));
8794 if (virDomainDefPostParse(vmdef
, caps
, parse_flags
, xmlopt
, NULL
) < 0)
8801 qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm
,
8802 virQEMUDriverPtr driver
,
8806 virDomainDefPtr vmdef
= NULL
;
8807 virQEMUDriverConfigPtr cfg
= NULL
;
8808 virDomainDeviceDefPtr devConf
= NULL
;
8809 virDomainDeviceDefPtr devLive
= NULL
;
8811 virCapsPtr caps
= NULL
;
8812 unsigned int parse_flags
= VIR_DOMAIN_DEF_PARSE_INACTIVE
|
8813 VIR_DOMAIN_DEF_PARSE_ABI_UPDATE
;
8815 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
8816 VIR_DOMAIN_AFFECT_CONFIG
, -1);
8818 cfg
= virQEMUDriverGetConfig(driver
);
8820 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
8823 /* The config and live post processing address auto-generation algorithms
8824 * rely on the correct vm->def or vm->newDef being passed, so call the
8825 * device parse based on which definition is in use */
8826 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
8827 vmdef
= virDomainObjCopyPersistentDef(vm
, caps
, driver
->xmlopt
);
8831 if (!(devConf
= virDomainDeviceDefParse(xml
, vmdef
, caps
,
8832 driver
->xmlopt
, parse_flags
)))
8835 if (virDomainDefCompatibleDevice(vmdef
, devConf
, NULL
,
8836 VIR_DOMAIN_DEVICE_ACTION_ATTACH
,
8840 if ((ret
= qemuDomainAttachDeviceConfig(vmdef
, devConf
, caps
,
8842 driver
->xmlopt
)) < 0)
8846 if (flags
& VIR_DOMAIN_AFFECT_LIVE
) {
8847 if (!(devLive
= virDomainDeviceDefParse(xml
, vm
->def
, caps
,
8848 driver
->xmlopt
, parse_flags
)))
8851 if (virDomainDeviceValidateAliasForHotplug(vm
, devLive
, flags
) < 0)
8854 if (virDomainDefCompatibleDevice(vm
->def
, devLive
, NULL
,
8855 VIR_DOMAIN_DEVICE_ACTION_ATTACH
,
8859 if ((ret
= qemuDomainAttachDeviceLive(vm
, devLive
, driver
)) < 0)
8862 * update domain status forcibly because the domain status may be
8863 * changed even if we failed to attach the device. For example,
8864 * a new controller may be created.
8866 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0) {
8872 /* Finally, if no error until here, we can save config. */
8873 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
8874 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, vmdef
);
8876 virDomainObjAssignDef(vm
, vmdef
, false, NULL
);
8882 virDomainDefFree(vmdef
);
8883 virDomainDeviceDefFree(devConf
);
8884 virDomainDeviceDefFree(devLive
);
8885 virObjectUnref(cfg
);
8886 virObjectUnref(caps
);
8892 qemuDomainAttachDeviceFlags(virDomainPtr dom
,
8896 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
8897 virDomainObjPtr vm
= NULL
;
8900 virNWFilterReadLockFilterUpdates();
8902 if (!(vm
= qemuDomObjFromDomain(dom
)))
8905 if (virDomainAttachDeviceFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
8908 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
8911 if (virDomainObjUpdateModificationImpact(vm
, &flags
) < 0)
8914 if (qemuDomainAttachDeviceLiveAndConfig(vm
, driver
, xml
, flags
) < 0)
8920 qemuDomainObjEndJob(driver
, vm
);
8923 virDomainObjEndAPI(&vm
);
8924 virNWFilterUnlockFilterUpdates();
8928 static int qemuDomainAttachDevice(virDomainPtr dom
, const char *xml
)
8930 return qemuDomainAttachDeviceFlags(dom
, xml
,
8931 VIR_DOMAIN_AFFECT_LIVE
);
8935 static int qemuDomainUpdateDeviceFlags(virDomainPtr dom
,
8939 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
8940 virDomainObjPtr vm
= NULL
;
8941 virDomainDefPtr vmdef
= NULL
;
8942 virDomainDeviceDefPtr dev
= NULL
, dev_copy
= NULL
;
8943 bool force
= (flags
& VIR_DOMAIN_DEVICE_MODIFY_FORCE
) != 0;
8945 virQEMUDriverConfigPtr cfg
= NULL
;
8946 virCapsPtr caps
= NULL
;
8947 unsigned int parse_flags
= 0;
8949 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
8950 VIR_DOMAIN_AFFECT_CONFIG
|
8951 VIR_DOMAIN_DEVICE_MODIFY_FORCE
, -1);
8953 virNWFilterReadLockFilterUpdates();
8955 cfg
= virQEMUDriverGetConfig(driver
);
8957 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
8960 if (!(vm
= qemuDomObjFromDomain(dom
)))
8963 if (virDomainUpdateDeviceFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
8966 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
8969 if (virDomainObjUpdateModificationImpact(vm
, &flags
) < 0)
8972 if ((flags
& VIR_DOMAIN_AFFECT_CONFIG
) &&
8973 !(flags
& VIR_DOMAIN_AFFECT_LIVE
))
8974 parse_flags
|= VIR_DOMAIN_DEF_PARSE_INACTIVE
;
8976 dev
= dev_copy
= virDomainDeviceDefParse(xml
, vm
->def
,
8977 caps
, driver
->xmlopt
,
8982 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
&&
8983 flags
& VIR_DOMAIN_AFFECT_LIVE
) {
8984 /* If we are affecting both CONFIG and LIVE
8985 * create a deep copy of device as adding
8986 * to CONFIG takes one instance.
8988 dev_copy
= virDomainDeviceDefCopy(dev
, vm
->def
, caps
, driver
->xmlopt
);
8993 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
8994 /* Make a copy for updated domain. */
8995 vmdef
= virDomainObjCopyPersistentDef(vm
, caps
, driver
->xmlopt
);
8999 /* virDomainDefCompatibleDevice call is delayed until we know the
9000 * device we're going to update. */
9001 if ((ret
= qemuDomainUpdateDeviceConfig(vmdef
, dev
, caps
,
9003 driver
->xmlopt
)) < 0)
9007 if (flags
& VIR_DOMAIN_AFFECT_LIVE
) {
9008 /* virDomainDefCompatibleDevice call is delayed until we know the
9009 * device we're going to update. */
9010 if ((ret
= qemuDomainUpdateDeviceLive(vm
, dev_copy
, dom
, force
)) < 0)
9013 * update domain status forcibly because the domain status may be
9014 * changed even if we failed to attach the device. For example,
9015 * a new controller may be created.
9017 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0) {
9023 /* Finally, if no error until here, we can save config. */
9024 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
9025 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, vmdef
);
9027 virDomainObjAssignDef(vm
, vmdef
, false, NULL
);
9033 qemuDomainObjEndJob(driver
, vm
);
9036 virDomainDefFree(vmdef
);
9037 if (dev
!= dev_copy
)
9038 virDomainDeviceDefFree(dev_copy
);
9039 virDomainDeviceDefFree(dev
);
9040 virDomainObjEndAPI(&vm
);
9041 virObjectUnref(caps
);
9042 virObjectUnref(cfg
);
9043 virNWFilterUnlockFilterUpdates();
9048 qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr driver
,
9053 virCapsPtr caps
= NULL
;
9054 virQEMUDriverConfigPtr cfg
= NULL
;
9055 virDomainDeviceDefPtr dev
= NULL
, dev_copy
= NULL
;
9056 unsigned int parse_flags
= VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
;
9057 virDomainDefPtr vmdef
= NULL
;
9060 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
9061 VIR_DOMAIN_AFFECT_CONFIG
, -1);
9063 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
9066 cfg
= virQEMUDriverGetConfig(driver
);
9068 if ((flags
& VIR_DOMAIN_AFFECT_CONFIG
) &&
9069 !(flags
& VIR_DOMAIN_AFFECT_LIVE
))
9070 parse_flags
|= VIR_DOMAIN_DEF_PARSE_INACTIVE
;
9072 dev
= dev_copy
= virDomainDeviceDefParse(xml
, vm
->def
,
9073 caps
, driver
->xmlopt
,
9078 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
&&
9079 flags
& VIR_DOMAIN_AFFECT_LIVE
) {
9080 /* If we are affecting both CONFIG and LIVE
9081 * create a deep copy of device as adding
9082 * to CONFIG takes one instance.
9084 dev_copy
= virDomainDeviceDefCopy(dev
, vm
->def
, caps
, driver
->xmlopt
);
9089 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
9090 /* Make a copy for updated domain. */
9091 vmdef
= virDomainObjCopyPersistentDef(vm
, caps
, driver
->xmlopt
);
9095 if (qemuDomainDetachDeviceConfig(vmdef
, dev
, caps
,
9097 driver
->xmlopt
) < 0)
9101 if (flags
& VIR_DOMAIN_AFFECT_LIVE
) {
9104 if ((rc
= qemuDomainDetachDeviceLive(vm
, dev_copy
, driver
, false)) < 0)
9107 if (rc
== 0 && qemuDomainUpdateDeviceList(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
9111 * update domain status forcibly because the domain status may be
9112 * changed even if we failed to attach the device. For example,
9113 * a new controller may be created.
9115 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, caps
) < 0)
9119 /* Finally, if no error until here, we can save config. */
9120 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
9121 if (virDomainSaveConfig(cfg
->configDir
, caps
, vmdef
) < 0)
9124 virDomainObjAssignDef(vm
, vmdef
, false, NULL
);
9131 virObjectUnref(caps
);
9132 virObjectUnref(cfg
);
9133 if (dev
!= dev_copy
)
9134 virDomainDeviceDefFree(dev_copy
);
9135 virDomainDeviceDefFree(dev
);
9136 virDomainDefFree(vmdef
);
9142 qemuDomainDetachDeviceAliasLiveAndConfig(virQEMUDriverPtr driver
,
9147 virCapsPtr caps
= NULL
;
9148 virQEMUDriverConfigPtr cfg
= NULL
;
9149 virDomainDefPtr def
= NULL
;
9150 virDomainDefPtr persistentDef
= NULL
;
9151 virDomainDefPtr vmdef
= NULL
;
9152 unsigned int parse_flags
= VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
;
9155 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
9156 VIR_DOMAIN_AFFECT_CONFIG
, -1);
9158 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
9161 cfg
= virQEMUDriverGetConfig(driver
);
9163 if ((flags
& VIR_DOMAIN_AFFECT_CONFIG
) &&
9164 !(flags
& VIR_DOMAIN_AFFECT_LIVE
))
9165 parse_flags
|= VIR_DOMAIN_DEF_PARSE_INACTIVE
;
9167 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
9170 if (persistentDef
) {
9171 virDomainDeviceDef dev
;
9173 if (!(vmdef
= virDomainObjCopyPersistentDef(vm
, caps
, driver
->xmlopt
)))
9176 if (virDomainDefFindDevice(vmdef
, alias
, &dev
, true) < 0)
9179 if (qemuDomainDetachDeviceConfig(vmdef
, &dev
, caps
,
9180 parse_flags
, driver
->xmlopt
) < 0)
9185 virDomainDeviceDef dev
;
9188 if (virDomainDefFindDevice(def
, alias
, &dev
, true) < 0)
9191 if ((rc
= qemuDomainDetachDeviceLive(vm
, &dev
, driver
, true)) < 0)
9194 if (rc
== 0 && qemuDomainUpdateDeviceList(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
9199 if (virDomainSaveConfig(cfg
->configDir
, caps
, vmdef
) < 0)
9201 virDomainObjAssignDef(vm
, vmdef
, false, NULL
);
9207 virDomainDefFree(vmdef
);
9208 virObjectUnref(cfg
);
9209 virObjectUnref(caps
);
9215 qemuDomainDetachDeviceFlags(virDomainPtr dom
,
9219 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9220 virDomainObjPtr vm
= NULL
;
9223 if (!(vm
= qemuDomObjFromDomain(dom
)))
9226 if (virDomainDetachDeviceFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
9229 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9232 if (virDomainObjUpdateModificationImpact(vm
, &flags
) < 0)
9235 if (qemuDomainDetachDeviceLiveAndConfig(driver
, vm
, xml
, flags
) < 0)
9241 qemuDomainObjEndJob(driver
, vm
);
9244 virDomainObjEndAPI(&vm
);
9250 qemuDomainDetachDeviceAlias(virDomainPtr dom
,
9254 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9255 virDomainObjPtr vm
= NULL
;
9258 if (!(vm
= qemuDomObjFromDomain(dom
)))
9261 if (virDomainDetachDeviceAliasEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
9264 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9267 if (virDomainObjUpdateModificationImpact(vm
, &flags
) < 0)
9270 if (qemuDomainDetachDeviceAliasLiveAndConfig(driver
, vm
, alias
, flags
) < 0)
9276 qemuDomainObjEndJob(driver
, vm
);
9279 virDomainObjEndAPI(&vm
);
9284 static int qemuDomainDetachDevice(virDomainPtr dom
, const char *xml
)
9286 return qemuDomainDetachDeviceFlags(dom
, xml
,
9287 VIR_DOMAIN_AFFECT_LIVE
);
9290 static int qemuDomainGetAutostart(virDomainPtr dom
,
9296 if (!(vm
= qemuDomObjFromDomain(dom
)))
9299 if (virDomainGetAutostartEnsureACL(dom
->conn
, vm
->def
) < 0)
9302 *autostart
= vm
->autostart
;
9306 virDomainObjEndAPI(&vm
);
9310 static int qemuDomainSetAutostart(virDomainPtr dom
,
9313 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9315 char *configFile
= NULL
, *autostartLink
= NULL
;
9317 virQEMUDriverConfigPtr cfg
= NULL
;
9319 if (!(vm
= qemuDomObjFromDomain(dom
)))
9322 cfg
= virQEMUDriverGetConfig(driver
);
9324 if (virDomainSetAutostartEnsureACL(dom
->conn
, vm
->def
) < 0)
9327 if (!vm
->persistent
) {
9328 virReportError(VIR_ERR_OPERATION_INVALID
,
9329 "%s", _("cannot set autostart for transient domain"));
9333 autostart
= (autostart
!= 0);
9335 if (vm
->autostart
!= autostart
) {
9336 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9339 if (!(configFile
= virDomainConfigFile(cfg
->configDir
, vm
->def
->name
)))
9342 if (!(autostartLink
= virDomainConfigFile(cfg
->autostartDir
,
9347 if (virFileMakePath(cfg
->autostartDir
) < 0) {
9348 virReportSystemError(errno
,
9349 _("cannot create autostart directory %s"),
9354 if (symlink(configFile
, autostartLink
) < 0) {
9355 virReportSystemError(errno
,
9356 _("Failed to create symlink '%s to '%s'"),
9357 autostartLink
, configFile
);
9361 if (unlink(autostartLink
) < 0 &&
9364 virReportSystemError(errno
,
9365 _("Failed to delete symlink '%s'"),
9371 vm
->autostart
= autostart
;
9374 qemuDomainObjEndJob(driver
, vm
);
9379 VIR_FREE(configFile
);
9380 VIR_FREE(autostartLink
);
9381 virDomainObjEndAPI(&vm
);
9382 virObjectUnref(cfg
);
9387 static char *qemuDomainGetSchedulerType(virDomainPtr dom
,
9391 virDomainObjPtr vm
= NULL
;
9392 qemuDomainObjPrivatePtr priv
;
9393 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9395 if (!(vm
= qemuDomObjFromDomain(dom
)))
9398 priv
= vm
->privateData
;
9400 if (virDomainGetSchedulerTypeEnsureACL(dom
->conn
, vm
->def
) < 0)
9403 if (!virQEMUDriverIsPrivileged(driver
)) {
9404 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
9405 _("CPU tuning is not available in session mode"));
9409 /* Domain not running, thus no cgroups - return defaults */
9410 if (!virDomainObjIsActive(vm
)) {
9413 ignore_value(VIR_STRDUP(ret
, "posix"));
9417 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPU
)) {
9418 virReportError(VIR_ERR_OPERATION_INVALID
,
9419 "%s", _("cgroup CPU controller is not mounted"));
9424 if (virCgroupSupportsCpuBW(priv
->cgroup
))
9430 ignore_value(VIR_STRDUP(ret
, "posix"));
9433 virDomainObjEndAPI(&vm
);
9437 /* blkioDeviceStr in the form of /device/path,weight,/device/path,weight
9438 * for example, /dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0,800
9441 qemuDomainParseBlkioDeviceStr(char *blkioDeviceStr
, const char *type
,
9442 virBlkioDevicePtr
*dev
, size_t *size
)
9448 virBlkioDevicePtr result
= NULL
;
9453 if (STREQ(blkioDeviceStr
, ""))
9456 temp
= blkioDeviceStr
;
9458 temp
= strchr(temp
, ',');
9465 /* A valid string must have even number of fields, hence an odd
9466 * number of commas. */
9470 ndevices
= (nsep
+ 1) / 2;
9472 if (VIR_ALLOC_N(result
, ndevices
) < 0)
9476 temp
= blkioDeviceStr
;
9485 if (VIR_STRNDUP(result
[i
].path
, temp
, p
- temp
) < 0)
9491 if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
)) {
9492 if (virStrToLong_uip(temp
, &p
, 10, &result
[i
].weight
) < 0)
9494 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
)) {
9495 if (virStrToLong_uip(temp
, &p
, 10, &result
[i
].riops
) < 0)
9497 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
)) {
9498 if (virStrToLong_uip(temp
, &p
, 10, &result
[i
].wiops
) < 0)
9500 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
)) {
9501 if (virStrToLong_ullp(temp
, &p
, 10, &result
[i
].rbps
) < 0)
9503 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9504 if (virStrToLong_ullp(temp
, &p
, 10, &result
[i
].wbps
) < 0)
9507 virReportError(VIR_ERR_INVALID_ARG
,
9508 _("unknown parameter '%s'"), type
);
9530 virReportError(VIR_ERR_INVALID_ARG
,
9531 _("unable to parse blkio device '%s' '%s'"),
9532 type
, blkioDeviceStr
);
9536 virReportError(VIR_ERR_INVALID_ARG
,
9537 _("invalid value '%s' for parameter '%s' of device '%s'"),
9538 temp
, type
, result
[i
].path
);
9542 virBlkioDeviceArrayClear(result
, ndevices
);
9548 /* Modify dest_array to reflect all blkio device changes described in
9551 qemuDomainMergeBlkioDevice(virBlkioDevicePtr
*dest_array
,
9553 virBlkioDevicePtr src_array
,
9558 virBlkioDevicePtr dest
, src
;
9560 for (i
= 0; i
< src_size
; i
++) {
9563 src
= &src_array
[i
];
9564 for (j
= 0; j
< *dest_size
; j
++) {
9565 dest
= &(*dest_array
)[j
];
9566 if (STREQ(src
->path
, dest
->path
)) {
9569 if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
)) {
9570 dest
->weight
= src
->weight
;
9571 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
)) {
9572 dest
->riops
= src
->riops
;
9573 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
)) {
9574 dest
->wiops
= src
->wiops
;
9575 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
)) {
9576 dest
->rbps
= src
->rbps
;
9577 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9578 dest
->wbps
= src
->wbps
;
9580 virReportError(VIR_ERR_INVALID_ARG
, _("Unknown parameter %s"),
9588 if (!src
->weight
&& !src
->riops
&& !src
->wiops
&& !src
->rbps
&& !src
->wbps
)
9590 if (VIR_EXPAND_N(*dest_array
, *dest_size
, 1) < 0)
9592 dest
= &(*dest_array
)[*dest_size
- 1];
9594 if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
)) {
9595 dest
->weight
= src
->weight
;
9596 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
)) {
9597 dest
->riops
= src
->riops
;
9598 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
)) {
9599 dest
->wiops
= src
->wiops
;
9600 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
)) {
9601 dest
->rbps
= src
->rbps
;
9602 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9603 dest
->wbps
= src
->wbps
;
9605 *dest_size
= *dest_size
- 1;
9609 dest
->path
= src
->path
;
9618 qemuDomainSetBlkioParameters(virDomainPtr dom
,
9619 virTypedParameterPtr params
,
9623 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9625 virDomainObjPtr vm
= NULL
;
9626 virDomainDefPtr def
;
9627 virDomainDefPtr persistentDef
;
9629 virQEMUDriverConfigPtr cfg
= NULL
;
9630 qemuDomainObjPrivatePtr priv
;
9632 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
9633 VIR_DOMAIN_AFFECT_CONFIG
, -1);
9634 if (virTypedParamsValidate(params
, nparams
,
9635 VIR_DOMAIN_BLKIO_WEIGHT
,
9636 VIR_TYPED_PARAM_UINT
,
9637 VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
,
9638 VIR_TYPED_PARAM_STRING
,
9639 VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
,
9640 VIR_TYPED_PARAM_STRING
,
9641 VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
,
9642 VIR_TYPED_PARAM_STRING
,
9643 VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
,
9644 VIR_TYPED_PARAM_STRING
,
9645 VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
,
9646 VIR_TYPED_PARAM_STRING
,
9650 if (!(vm
= qemuDomObjFromDomain(dom
)))
9653 priv
= vm
->privateData
;
9654 cfg
= virQEMUDriverGetConfig(driver
);
9656 if (virDomainSetBlkioParametersEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
9659 if (!virQEMUDriverIsPrivileged(driver
)) {
9660 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
9661 _("Block I/O tuning is not available in session mode"));
9665 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9668 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
9671 if (flags
& VIR_DOMAIN_AFFECT_LIVE
) {
9672 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_BLKIO
)) {
9673 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
9674 _("blkio cgroup isn't mounted"));
9681 for (i
= 0; i
< nparams
; i
++) {
9682 virTypedParameterPtr param
= ¶ms
[i
];
9684 if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_WEIGHT
)) {
9685 if (virCgroupSetBlkioWeight(priv
->cgroup
, param
->value
.ui
) < 0 ||
9686 virCgroupGetBlkioWeight(priv
->cgroup
, &def
->blkio
.weight
) < 0)
9688 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
) ||
9689 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
) ||
9690 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
) ||
9691 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
) ||
9692 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9694 virBlkioDevicePtr devices
= NULL
;
9697 if (qemuDomainParseBlkioDeviceStr(param
->value
.s
,
9705 if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
)) {
9706 for (j
= 0; j
< ndevices
; j
++) {
9707 if (virCgroupSetBlkioDeviceWeight(priv
->cgroup
,
9709 devices
[j
].weight
) < 0 ||
9710 virCgroupGetBlkioDeviceWeight(priv
->cgroup
,
9712 &devices
[j
].weight
) < 0) {
9717 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
)) {
9718 for (j
= 0; j
< ndevices
; j
++) {
9719 if (virCgroupSetBlkioDeviceReadIops(priv
->cgroup
,
9721 devices
[j
].riops
) < 0 ||
9722 virCgroupGetBlkioDeviceReadIops(priv
->cgroup
,
9724 &devices
[j
].riops
) < 0) {
9729 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
)) {
9730 for (j
= 0; j
< ndevices
; j
++) {
9731 if (virCgroupSetBlkioDeviceWriteIops(priv
->cgroup
,
9733 devices
[j
].wiops
) < 0 ||
9734 virCgroupGetBlkioDeviceWriteIops(priv
->cgroup
,
9736 &devices
[j
].wiops
) < 0) {
9741 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
)) {
9742 for (j
= 0; j
< ndevices
; j
++) {
9743 if (virCgroupSetBlkioDeviceReadBps(priv
->cgroup
,
9745 devices
[j
].rbps
) < 0 ||
9746 virCgroupGetBlkioDeviceReadBps(priv
->cgroup
,
9748 &devices
[j
].rbps
) < 0) {
9753 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9754 for (j
= 0; j
< ndevices
; j
++) {
9755 if (virCgroupSetBlkioDeviceWriteBps(priv
->cgroup
,
9757 devices
[j
].wbps
) < 0 ||
9758 virCgroupGetBlkioDeviceWriteBps(priv
->cgroup
,
9760 &devices
[j
].wbps
) < 0) {
9766 virReportError(VIR_ERR_INVALID_ARG
, _("Unknown blkio parameter %s"),
9769 virBlkioDeviceArrayClear(devices
, ndevices
);
9775 if (j
!= ndevices
||
9776 qemuDomainMergeBlkioDevice(&def
->blkio
.devices
,
9777 &def
->blkio
.ndevices
,
9778 devices
, ndevices
, param
->field
) < 0)
9780 virBlkioDeviceArrayClear(devices
, ndevices
);
9785 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
9790 if (persistentDef
) {
9791 for (i
= 0; i
< nparams
; i
++) {
9792 virTypedParameterPtr param
= ¶ms
[i
];
9794 if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_WEIGHT
)) {
9795 persistentDef
->blkio
.weight
= param
->value
.ui
;
9796 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
) ||
9797 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
) ||
9798 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
) ||
9799 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
) ||
9800 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9801 virBlkioDevicePtr devices
= NULL
;
9804 if (qemuDomainParseBlkioDeviceStr(param
->value
.s
,
9811 if (qemuDomainMergeBlkioDevice(&persistentDef
->blkio
.devices
,
9812 &persistentDef
->blkio
.ndevices
,
9813 devices
, ndevices
, param
->field
) < 0)
9815 virBlkioDeviceArrayClear(devices
, ndevices
);
9820 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
9825 qemuDomainObjEndJob(driver
, vm
);
9828 virDomainObjEndAPI(&vm
);
9829 virObjectUnref(cfg
);
9835 qemuDomainGetBlkioParameters(virDomainPtr dom
,
9836 virTypedParameterPtr params
,
9840 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9841 virDomainObjPtr vm
= NULL
;
9842 virDomainDefPtr def
= NULL
;
9843 virDomainDefPtr persistentDef
= NULL
;
9844 int maxparams
= QEMU_NB_BLKIO_PARAM
;
9847 qemuDomainObjPrivatePtr priv
;
9849 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
9850 VIR_DOMAIN_AFFECT_CONFIG
|
9851 VIR_TYPED_PARAM_STRING_OKAY
, -1);
9853 /* We blindly return a string, and let libvirt.c and
9854 * remote_driver.c do the filtering on behalf of older clients
9855 * that can't parse it. */
9856 flags
&= ~VIR_TYPED_PARAM_STRING_OKAY
;
9858 if (!(vm
= qemuDomObjFromDomain(dom
)))
9861 priv
= vm
->privateData
;
9863 if (virDomainGetBlkioParametersEnsureACL(dom
->conn
, vm
->def
) < 0)
9866 if (!virQEMUDriverIsPrivileged(driver
)) {
9867 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
9868 _("Block I/O tuning is not available in session mode"));
9872 if ((*nparams
) == 0) {
9873 /* Current number of blkio parameters supported by cgroups */
9874 *nparams
= QEMU_NB_BLKIO_PARAM
;
9877 } else if (*nparams
< maxparams
) {
9878 maxparams
= *nparams
;
9883 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
9887 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_BLKIO
)) {
9888 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
9889 _("blkio cgroup isn't mounted"));
9893 /* fill blkio weight here */
9894 if (virCgroupGetBlkioWeight(priv
->cgroup
, &val
) < 0)
9896 if (virTypedParameterAssign(&(params
[(*nparams
)++]),
9897 VIR_DOMAIN_BLKIO_WEIGHT
,
9898 VIR_TYPED_PARAM_UINT
, val
) < 0)
9901 if (virDomainGetBlkioParametersAssignFromDef(def
, params
, nparams
,
9905 } else if (persistentDef
) {
9906 /* fill blkio weight here */
9907 if (virTypedParameterAssign(&(params
[(*nparams
)++]),
9908 VIR_DOMAIN_BLKIO_WEIGHT
,
9909 VIR_TYPED_PARAM_UINT
,
9910 persistentDef
->blkio
.weight
) < 0)
9913 if (virDomainGetBlkioParametersAssignFromDef(persistentDef
, params
,
9914 nparams
, maxparams
) < 0)
9921 virDomainObjEndAPI(&vm
);
9926 qemuDomainSetMemoryParameters(virDomainPtr dom
,
9927 virTypedParameterPtr params
,
9931 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9932 virDomainDefPtr def
= NULL
;
9933 virDomainDefPtr persistentDef
= NULL
;
9934 virDomainObjPtr vm
= NULL
;
9935 unsigned long long swap_hard_limit
;
9936 unsigned long long hard_limit
= 0;
9937 unsigned long long soft_limit
= 0;
9938 bool set_swap_hard_limit
= false;
9939 bool set_hard_limit
= false;
9940 bool set_soft_limit
= false;
9941 virQEMUDriverConfigPtr cfg
= NULL
;
9944 qemuDomainObjPrivatePtr priv
;
9946 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
9947 VIR_DOMAIN_AFFECT_CONFIG
, -1);
9949 if (virTypedParamsValidate(params
, nparams
,
9950 VIR_DOMAIN_MEMORY_HARD_LIMIT
,
9951 VIR_TYPED_PARAM_ULLONG
,
9952 VIR_DOMAIN_MEMORY_SOFT_LIMIT
,
9953 VIR_TYPED_PARAM_ULLONG
,
9954 VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT
,
9955 VIR_TYPED_PARAM_ULLONG
,
9960 if (!(vm
= qemuDomObjFromDomain(dom
)))
9963 priv
= vm
->privateData
;
9964 cfg
= virQEMUDriverGetConfig(driver
);
9966 if (virDomainSetMemoryParametersEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
9969 if (!virQEMUDriverIsPrivileged(driver
)) {
9970 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
9971 _("Memory tuning is not available in session mode"));
9975 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9978 /* QEMU and LXC implementation are identical */
9979 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
9983 !virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_MEMORY
)) {
9984 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
9985 _("cgroup memory controller is not mounted"));
9989 #define VIR_GET_LIMIT_PARAMETER(PARAM, VALUE) \
9990 if ((rc = virTypedParamsGetULLong(params, nparams, PARAM, &VALUE)) < 0) \
9994 set_ ## VALUE = true;
9996 VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT
, swap_hard_limit
)
9997 VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_HARD_LIMIT
, hard_limit
)
9998 VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_SOFT_LIMIT
, soft_limit
)
10000 #undef VIR_GET_LIMIT_PARAMETER
10002 /* Swap hard limit must be greater than hard limit. */
10003 if (set_swap_hard_limit
|| set_hard_limit
) {
10004 unsigned long long mem_limit
= vm
->def
->mem
.hard_limit
;
10005 unsigned long long swap_limit
= vm
->def
->mem
.swap_hard_limit
;
10007 if (set_swap_hard_limit
)
10008 swap_limit
= swap_hard_limit
;
10010 if (set_hard_limit
)
10011 mem_limit
= hard_limit
;
10013 if (mem_limit
> swap_limit
) {
10014 virReportError(VIR_ERR_INVALID_ARG
, "%s",
10015 _("memory hard_limit tunable value must be lower "
10016 "than or equal to swap_hard_limit"));
10021 #define VIR_SET_MEM_PARAMETER(FUNC, VALUE) \
10022 if (set_ ## VALUE) { \
10024 if ((rc = FUNC(priv->cgroup, VALUE)) < 0) \
10026 def->mem.VALUE = VALUE; \
10029 if (persistentDef) \
10030 persistentDef->mem.VALUE = VALUE; \
10033 /* Soft limit doesn't clash with the others */
10034 VIR_SET_MEM_PARAMETER(virCgroupSetMemorySoftLimit
, soft_limit
);
10036 /* set hard limit before swap hard limit if decreasing it */
10037 if (def
&& def
->mem
.hard_limit
> hard_limit
) {
10038 VIR_SET_MEM_PARAMETER(virCgroupSetMemoryHardLimit
, hard_limit
);
10039 /* inhibit changing the limit a second time */
10040 set_hard_limit
= false;
10043 VIR_SET_MEM_PARAMETER(virCgroupSetMemSwapHardLimit
, swap_hard_limit
);
10045 /* otherwise increase it after swap hard limit */
10046 VIR_SET_MEM_PARAMETER(virCgroupSetMemoryHardLimit
, hard_limit
);
10048 #undef VIR_SET_MEM_PARAMETER
10051 virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
10054 if (persistentDef
&&
10055 virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
10057 /* QEMU and LXC implementations are identical */
10062 qemuDomainObjEndJob(driver
, vm
);
10065 virDomainObjEndAPI(&vm
);
10066 virObjectUnref(cfg
);
10071 #define QEMU_ASSIGN_MEM_PARAM(index, name, value) \
10072 if (index < *nparams && \
10073 virTypedParameterAssign(¶ms[index], name, VIR_TYPED_PARAM_ULLONG, \
10078 qemuDomainGetMemoryParameters(virDomainPtr dom
,
10079 virTypedParameterPtr params
,
10081 unsigned int flags
)
10083 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10084 virDomainObjPtr vm
= NULL
;
10085 virDomainDefPtr persistentDef
= NULL
;
10087 qemuDomainObjPrivatePtr priv
;
10088 unsigned long long swap_hard_limit
, mem_hard_limit
, mem_soft_limit
;
10090 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10091 VIR_DOMAIN_AFFECT_CONFIG
|
10092 VIR_TYPED_PARAM_STRING_OKAY
, -1);
10094 if (!(vm
= qemuDomObjFromDomain(dom
)))
10097 priv
= vm
->privateData
;
10099 if (virDomainGetMemoryParametersEnsureACL(dom
->conn
, vm
->def
) < 0)
10102 if (!virQEMUDriverIsPrivileged(driver
)) {
10103 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
10104 _("Memory tuning is not available in session mode"));
10108 if (virDomainObjGetDefs(vm
, flags
, NULL
, &persistentDef
) < 0)
10111 if ((*nparams
) == 0) {
10112 /* Current number of memory parameters supported by cgroups */
10113 *nparams
= QEMU_NB_MEM_PARAM
;
10118 if (persistentDef
) {
10119 mem_hard_limit
= persistentDef
->mem
.hard_limit
;
10120 mem_soft_limit
= persistentDef
->mem
.soft_limit
;
10121 swap_hard_limit
= persistentDef
->mem
.swap_hard_limit
;
10123 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_MEMORY
)) {
10124 virReportError(VIR_ERR_OPERATION_INVALID
,
10125 "%s", _("cgroup memory controller is not mounted"));
10129 if (virCgroupGetMemoryHardLimit(priv
->cgroup
, &mem_hard_limit
) < 0)
10132 if (virCgroupGetMemorySoftLimit(priv
->cgroup
, &mem_soft_limit
) < 0)
10135 if (virCgroupGetMemSwapHardLimit(priv
->cgroup
, &swap_hard_limit
) < 0) {
10136 if (!virLastErrorIsSystemErrno(ENOENT
) &&
10137 !virLastErrorIsSystemErrno(EOPNOTSUPP
))
10139 swap_hard_limit
= VIR_DOMAIN_MEMORY_PARAM_UNLIMITED
;
10143 QEMU_ASSIGN_MEM_PARAM(0, VIR_DOMAIN_MEMORY_HARD_LIMIT
, mem_hard_limit
);
10144 QEMU_ASSIGN_MEM_PARAM(1, VIR_DOMAIN_MEMORY_SOFT_LIMIT
, mem_soft_limit
);
10145 QEMU_ASSIGN_MEM_PARAM(2, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT
, swap_hard_limit
);
10147 if (QEMU_NB_MEM_PARAM
< *nparams
)
10148 *nparams
= QEMU_NB_MEM_PARAM
;
10152 virDomainObjEndAPI(&vm
);
10155 #undef QEMU_ASSIGN_MEM_PARAM
10158 qemuDomainSetNumaParamsLive(virDomainObjPtr vm
,
10159 virBitmapPtr nodeset
)
10161 virCgroupPtr cgroup_temp
= NULL
;
10162 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
10163 char *nodeset_str
= NULL
;
10164 virDomainNumatuneMemMode mode
;
10168 if (virDomainNumatuneGetMode(vm
->def
->numa
, -1, &mode
) == 0 &&
10169 mode
!= VIR_DOMAIN_NUMATUNE_MEM_STRICT
) {
10170 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
10171 _("change of nodeset for running domain "
10172 "requires strict numa mode"));
10176 if (!virNumaNodesetIsAvailable(nodeset
))
10179 /* Ensure the cpuset string is formatted before passing to cgroup */
10180 if (!(nodeset_str
= virBitmapFormat(nodeset
)))
10183 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_EMULATOR
, 0,
10184 false, &cgroup_temp
) < 0 ||
10185 virCgroupSetCpusetMems(cgroup_temp
, nodeset_str
) < 0)
10187 virCgroupFree(&cgroup_temp
);
10189 for (i
= 0; i
< virDomainDefGetVcpusMax(vm
->def
); i
++) {
10190 virDomainVcpuDefPtr vcpu
= virDomainDefGetVcpu(vm
->def
, i
);
10195 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_VCPU
, i
,
10196 false, &cgroup_temp
) < 0 ||
10197 virCgroupSetCpusetMems(cgroup_temp
, nodeset_str
) < 0)
10199 virCgroupFree(&cgroup_temp
);
10202 for (i
= 0; i
< vm
->def
->niothreadids
; i
++) {
10203 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_IOTHREAD
,
10204 vm
->def
->iothreadids
[i
]->iothread_id
,
10205 false, &cgroup_temp
) < 0 ||
10206 virCgroupSetCpusetMems(cgroup_temp
, nodeset_str
) < 0)
10208 virCgroupFree(&cgroup_temp
);
10213 VIR_FREE(nodeset_str
);
10214 virCgroupFree(&cgroup_temp
);
10220 qemuDomainSetNumaParameters(virDomainPtr dom
,
10221 virTypedParameterPtr params
,
10223 unsigned int flags
)
10225 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10227 virDomainDefPtr def
;
10228 virDomainDefPtr persistentDef
;
10229 virDomainObjPtr vm
= NULL
;
10231 virQEMUDriverConfigPtr cfg
= NULL
;
10232 qemuDomainObjPrivatePtr priv
;
10233 virBitmapPtr nodeset
= NULL
;
10234 virDomainNumatuneMemMode config_mode
;
10237 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10238 VIR_DOMAIN_AFFECT_CONFIG
, -1);
10240 if (virTypedParamsValidate(params
, nparams
,
10241 VIR_DOMAIN_NUMA_MODE
,
10242 VIR_TYPED_PARAM_INT
,
10243 VIR_DOMAIN_NUMA_NODESET
,
10244 VIR_TYPED_PARAM_STRING
,
10248 if (!(vm
= qemuDomObjFromDomain(dom
)))
10251 priv
= vm
->privateData
;
10252 cfg
= virQEMUDriverGetConfig(driver
);
10254 if (virDomainSetNumaParametersEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
10257 for (i
= 0; i
< nparams
; i
++) {
10258 virTypedParameterPtr param
= ¶ms
[i
];
10260 if (STREQ(param
->field
, VIR_DOMAIN_NUMA_MODE
)) {
10261 mode
= param
->value
.i
;
10263 if (mode
< 0 || mode
>= VIR_DOMAIN_NUMATUNE_MEM_LAST
) {
10264 virReportError(VIR_ERR_INVALID_ARG
,
10265 _("unsupported numatune mode: '%d'"), mode
);
10269 } else if (STREQ(param
->field
, VIR_DOMAIN_NUMA_NODESET
)) {
10270 if (virBitmapParse(param
->value
.s
, &nodeset
,
10271 VIR_DOMAIN_CPUMASK_LEN
) < 0)
10274 if (virBitmapIsAllClear(nodeset
)) {
10275 virReportError(VIR_ERR_OPERATION_INVALID
,
10276 _("Invalid nodeset of 'numatune': %s"),
10283 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
10286 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
10290 if (!virQEMUDriverIsPrivileged(driver
)) {
10291 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
10292 _("NUMA tuning is not available in session mode"));
10296 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPUSET
)) {
10297 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
10298 _("cgroup cpuset controller is not mounted"));
10303 virDomainNumatuneGetMode(def
->numa
, -1, &config_mode
) == 0 &&
10304 config_mode
!= mode
) {
10305 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
10306 _("can't change numatune mode for running domain"));
10311 qemuDomainSetNumaParamsLive(vm
, nodeset
) < 0)
10314 if (virDomainNumatuneSet(def
->numa
,
10315 def
->placement_mode
==
10316 VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC
,
10317 -1, mode
, nodeset
) < 0)
10320 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
10324 if (persistentDef
) {
10325 if (virDomainNumatuneSet(persistentDef
->numa
,
10326 persistentDef
->placement_mode
==
10327 VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC
,
10328 -1, mode
, nodeset
) < 0)
10331 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
10338 qemuDomainObjEndJob(driver
, vm
);
10341 virBitmapFree(nodeset
);
10342 virDomainObjEndAPI(&vm
);
10343 virObjectUnref(cfg
);
10348 qemuDomainGetNumaParameters(virDomainPtr dom
,
10349 virTypedParameterPtr params
,
10351 unsigned int flags
)
10354 virDomainObjPtr vm
= NULL
;
10355 virDomainNumatuneMemMode tmpmode
= VIR_DOMAIN_NUMATUNE_MEM_STRICT
;
10356 qemuDomainObjPrivatePtr priv
;
10357 char *nodeset
= NULL
;
10359 virDomainDefPtr def
= NULL
;
10361 virBitmapPtr autoNodeset
= NULL
;
10363 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10364 VIR_DOMAIN_AFFECT_CONFIG
|
10365 VIR_TYPED_PARAM_STRING_OKAY
, -1);
10367 if (!(vm
= qemuDomObjFromDomain(dom
)))
10369 priv
= vm
->privateData
;
10371 if (virDomainGetNumaParametersEnsureACL(dom
->conn
, vm
->def
) < 0)
10374 if (!(def
= virDomainObjGetOneDefState(vm
, flags
, &live
)))
10378 autoNodeset
= priv
->autoNodeset
;
10380 if ((*nparams
) == 0) {
10381 *nparams
= QEMU_NB_NUMA_PARAM
;
10386 for (i
= 0; i
< QEMU_NB_NUMA_PARAM
&& i
< *nparams
; i
++) {
10387 virMemoryParameterPtr param
= ¶ms
[i
];
10390 case 0: /* fill numa mode here */
10391 ignore_value(virDomainNumatuneGetMode(def
->numa
, -1, &tmpmode
));
10393 if (virTypedParameterAssign(param
, VIR_DOMAIN_NUMA_MODE
,
10394 VIR_TYPED_PARAM_INT
, tmpmode
) < 0)
10399 case 1: /* fill numa nodeset here */
10400 nodeset
= virDomainNumatuneFormatNodeset(def
->numa
, autoNodeset
, -1);
10402 virTypedParameterAssign(param
, VIR_DOMAIN_NUMA_NODESET
,
10403 VIR_TYPED_PARAM_STRING
, nodeset
) < 0)
10409 /* coverity[dead_error_begin] */
10412 /* should not hit here */
10416 if (*nparams
> QEMU_NB_NUMA_PARAM
)
10417 *nparams
= QEMU_NB_NUMA_PARAM
;
10422 virDomainObjEndAPI(&vm
);
10427 qemuSetGlobalBWLive(virCgroupPtr cgroup
, unsigned long long period
,
10430 if (period
== 0 && quota
== 0)
10433 if (qemuSetupCgroupVcpuBW(cgroup
, period
, quota
) < 0)
10440 qemuDomainSetPerfEvents(virDomainPtr dom
,
10441 virTypedParameterPtr params
,
10443 unsigned int flags
)
10445 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10447 virDomainObjPtr vm
= NULL
;
10448 virQEMUDriverConfigPtr cfg
= NULL
;
10449 qemuDomainObjPrivatePtr priv
;
10450 virDomainDefPtr def
;
10451 virDomainDefPtr persistentDef
;
10453 virPerfEventType type
;
10456 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10457 VIR_DOMAIN_AFFECT_CONFIG
, -1);
10459 if (virTypedParamsValidate(params
, nparams
,
10460 VIR_PERF_PARAM_CMT
, VIR_TYPED_PARAM_BOOLEAN
,
10461 VIR_PERF_PARAM_MBMT
, VIR_TYPED_PARAM_BOOLEAN
,
10462 VIR_PERF_PARAM_MBML
, VIR_TYPED_PARAM_BOOLEAN
,
10463 VIR_PERF_PARAM_CPU_CYCLES
, VIR_TYPED_PARAM_BOOLEAN
,
10464 VIR_PERF_PARAM_INSTRUCTIONS
, VIR_TYPED_PARAM_BOOLEAN
,
10465 VIR_PERF_PARAM_CACHE_REFERENCES
, VIR_TYPED_PARAM_BOOLEAN
,
10466 VIR_PERF_PARAM_CACHE_MISSES
, VIR_TYPED_PARAM_BOOLEAN
,
10467 VIR_PERF_PARAM_BRANCH_INSTRUCTIONS
, VIR_TYPED_PARAM_BOOLEAN
,
10468 VIR_PERF_PARAM_BRANCH_MISSES
, VIR_TYPED_PARAM_BOOLEAN
,
10469 VIR_PERF_PARAM_BUS_CYCLES
, VIR_TYPED_PARAM_BOOLEAN
,
10470 VIR_PERF_PARAM_STALLED_CYCLES_FRONTEND
, VIR_TYPED_PARAM_BOOLEAN
,
10471 VIR_PERF_PARAM_STALLED_CYCLES_BACKEND
, VIR_TYPED_PARAM_BOOLEAN
,
10472 VIR_PERF_PARAM_REF_CPU_CYCLES
, VIR_TYPED_PARAM_BOOLEAN
,
10473 VIR_PERF_PARAM_CPU_CLOCK
, VIR_TYPED_PARAM_BOOLEAN
,
10474 VIR_PERF_PARAM_TASK_CLOCK
, VIR_TYPED_PARAM_BOOLEAN
,
10475 VIR_PERF_PARAM_PAGE_FAULTS
, VIR_TYPED_PARAM_BOOLEAN
,
10476 VIR_PERF_PARAM_CONTEXT_SWITCHES
, VIR_TYPED_PARAM_BOOLEAN
,
10477 VIR_PERF_PARAM_CPU_MIGRATIONS
, VIR_TYPED_PARAM_BOOLEAN
,
10478 VIR_PERF_PARAM_PAGE_FAULTS_MIN
, VIR_TYPED_PARAM_BOOLEAN
,
10479 VIR_PERF_PARAM_PAGE_FAULTS_MAJ
, VIR_TYPED_PARAM_BOOLEAN
,
10480 VIR_PERF_PARAM_ALIGNMENT_FAULTS
, VIR_TYPED_PARAM_BOOLEAN
,
10481 VIR_PERF_PARAM_EMULATION_FAULTS
, VIR_TYPED_PARAM_BOOLEAN
,
10485 if (!(vm
= qemuDomObjFromDomain(dom
)))
10488 cfg
= virQEMUDriverGetConfig(driver
);
10489 priv
= vm
->privateData
;
10491 if (virDomainSetPerfEventsEnsureACL(dom
->conn
, vm
->def
) < 0)
10494 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
10497 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
10501 for (i
= 0; i
< nparams
; i
++) {
10502 virTypedParameterPtr param
= ¶ms
[i
];
10503 enabled
= param
->value
.b
;
10504 type
= virPerfEventTypeFromString(param
->field
);
10506 if (!enabled
&& virPerfEventDisable(priv
->perf
, type
) < 0)
10508 if (enabled
&& virPerfEventEnable(priv
->perf
, type
, vm
->pid
) < 0)
10511 def
->perf
.events
[type
] = enabled
?
10512 VIR_TRISTATE_BOOL_YES
: VIR_TRISTATE_BOOL_NO
;
10515 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
10519 if (persistentDef
) {
10520 for (i
= 0; i
< nparams
; i
++) {
10521 virTypedParameterPtr param
= ¶ms
[i
];
10522 enabled
= param
->value
.b
;
10523 type
= virPerfEventTypeFromString(param
->field
);
10525 persistentDef
->perf
.events
[type
] = enabled
?
10526 VIR_TRISTATE_BOOL_YES
: VIR_TRISTATE_BOOL_NO
;
10529 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
10536 qemuDomainObjEndJob(driver
, vm
);
10539 virDomainObjEndAPI(&vm
);
10540 virObjectUnref(cfg
);
10545 qemuDomainGetPerfEvents(virDomainPtr dom
,
10546 virTypedParameterPtr
*params
,
10548 unsigned int flags
)
10550 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10551 virDomainObjPtr vm
= NULL
;
10552 qemuDomainObjPrivatePtr priv
;
10553 virDomainDefPtr def
;
10554 virTypedParameterPtr par
= NULL
;
10560 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10561 VIR_DOMAIN_AFFECT_CONFIG
|
10562 VIR_TYPED_PARAM_STRING_OKAY
, -1);
10564 if (!(vm
= qemuDomObjFromDomain(dom
)))
10567 if (virDomainGetPerfEventsEnsureACL(dom
->conn
, vm
->def
) < 0)
10570 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
10573 if (virDomainObjUpdateModificationImpact(vm
, &flags
) < 0)
10576 if (!(def
= virDomainObjGetOneDef(vm
, flags
)))
10579 priv
= vm
->privateData
;
10581 for (i
= 0; i
< VIR_PERF_EVENT_LAST
; i
++) {
10584 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
)
10585 perf_enabled
= def
->perf
.events
[i
] == VIR_TRISTATE_BOOL_YES
;
10587 perf_enabled
= virPerfEventIsEnabled(priv
->perf
, i
);
10589 if (virTypedParamsAddBoolean(&par
, &npar
, &maxpar
,
10590 virPerfEventTypeToString(i
),
10602 qemuDomainObjEndJob(driver
, vm
);
10605 virDomainObjEndAPI(&vm
);
10606 virTypedParamsFree(par
, npar
);
10611 qemuSetVcpusBWLive(virDomainObjPtr vm
, virCgroupPtr cgroup
,
10612 unsigned long long period
, long long quota
)
10615 virCgroupPtr cgroup_vcpu
= NULL
;
10617 if (period
== 0 && quota
== 0)
10620 if (!qemuDomainHasVcpuPids(vm
))
10623 for (i
= 0; i
< virDomainDefGetVcpusMax(vm
->def
); i
++) {
10624 virDomainVcpuDefPtr vcpu
= virDomainDefGetVcpu(vm
->def
, i
);
10629 if (virCgroupNewThread(cgroup
, VIR_CGROUP_THREAD_VCPU
, i
,
10630 false, &cgroup_vcpu
) < 0)
10633 if (qemuSetupCgroupVcpuBW(cgroup_vcpu
, period
, quota
) < 0)
10636 virCgroupFree(&cgroup_vcpu
);
10642 virCgroupFree(&cgroup_vcpu
);
10647 qemuSetEmulatorBandwidthLive(virCgroupPtr cgroup
,
10648 unsigned long long period
,
10651 virCgroupPtr cgroup_emulator
= NULL
;
10653 if (period
== 0 && quota
== 0)
10656 if (virCgroupNewThread(cgroup
, VIR_CGROUP_THREAD_EMULATOR
, 0,
10657 false, &cgroup_emulator
) < 0)
10660 if (qemuSetupCgroupVcpuBW(cgroup_emulator
, period
, quota
) < 0)
10663 virCgroupFree(&cgroup_emulator
);
10667 virCgroupFree(&cgroup_emulator
);
10673 qemuSetIOThreadsBWLive(virDomainObjPtr vm
, virCgroupPtr cgroup
,
10674 unsigned long long period
, long long quota
)
10677 virCgroupPtr cgroup_iothread
= NULL
;
10679 if (period
== 0 && quota
== 0)
10682 if (!vm
->def
->niothreadids
)
10685 for (i
= 0; i
< vm
->def
->niothreadids
; i
++) {
10686 if (virCgroupNewThread(cgroup
, VIR_CGROUP_THREAD_IOTHREAD
,
10687 vm
->def
->iothreadids
[i
]->iothread_id
,
10688 false, &cgroup_iothread
) < 0)
10691 if (qemuSetupCgroupVcpuBW(cgroup_iothread
, period
, quota
) < 0)
10694 virCgroupFree(&cgroup_iothread
);
10700 virCgroupFree(&cgroup_iothread
);
10705 #define SCHED_RANGE_CHECK(VAR, NAME, MIN, MAX) \
10706 if (((VAR) > 0 && (VAR) < (MIN)) || (VAR) > (MAX)) { \
10707 virReportError(VIR_ERR_INVALID_ARG, \
10708 _("value of '%s' is out of range [%lld, %lld]"), \
10715 qemuDomainSetSchedulerParametersFlags(virDomainPtr dom
,
10716 virTypedParameterPtr params
,
10718 unsigned int flags
)
10720 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10722 virDomainObjPtr vm
= NULL
;
10723 virDomainDefPtr def
= NULL
;
10724 virDomainDefPtr persistentDef
= NULL
;
10725 virDomainDefPtr persistentDefCopy
= NULL
;
10726 unsigned long long value_ul
;
10730 virQEMUDriverConfigPtr cfg
= NULL
;
10731 virCapsPtr caps
= NULL
;
10732 qemuDomainObjPrivatePtr priv
;
10733 virObjectEventPtr event
= NULL
;
10734 virTypedParameterPtr eventParams
= NULL
;
10735 int eventNparams
= 0;
10736 int eventMaxNparams
= 0;
10738 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10739 VIR_DOMAIN_AFFECT_CONFIG
, -1);
10740 if (virTypedParamsValidate(params
, nparams
,
10741 VIR_DOMAIN_SCHEDULER_CPU_SHARES
,
10742 VIR_TYPED_PARAM_ULLONG
,
10743 VIR_DOMAIN_SCHEDULER_VCPU_PERIOD
,
10744 VIR_TYPED_PARAM_ULLONG
,
10745 VIR_DOMAIN_SCHEDULER_VCPU_QUOTA
,
10746 VIR_TYPED_PARAM_LLONG
,
10747 VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD
,
10748 VIR_TYPED_PARAM_ULLONG
,
10749 VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA
,
10750 VIR_TYPED_PARAM_LLONG
,
10751 VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD
,
10752 VIR_TYPED_PARAM_ULLONG
,
10753 VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA
,
10754 VIR_TYPED_PARAM_LLONG
,
10755 VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD
,
10756 VIR_TYPED_PARAM_ULLONG
,
10757 VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA
,
10758 VIR_TYPED_PARAM_LLONG
,
10762 if (!(vm
= qemuDomObjFromDomain(dom
)))
10765 priv
= vm
->privateData
;
10766 cfg
= virQEMUDriverGetConfig(driver
);
10768 if (virDomainSetSchedulerParametersFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
10771 if (!virQEMUDriverIsPrivileged(driver
)) {
10772 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
10773 _("CPU tuning is not available in session mode"));
10777 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
10780 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
10783 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
10786 if (persistentDef
) {
10787 /* Make a copy for updated domain. */
10788 if (!(persistentDefCopy
= virDomainObjCopyPersistentDef(vm
, caps
,
10794 !virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPU
)) {
10795 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
10796 _("cgroup CPU controller is not mounted"));
10800 for (i
= 0; i
< nparams
; i
++) {
10801 virTypedParameterPtr param
= ¶ms
[i
];
10802 value_ul
= param
->value
.ul
;
10803 value_l
= param
->value
.l
;
10805 if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_CPU_SHARES
)) {
10807 unsigned long long val
;
10808 if (virCgroupSetCpuShares(priv
->cgroup
, value_ul
) < 0)
10811 if (virCgroupGetCpuShares(priv
->cgroup
, &val
) < 0)
10814 def
->cputune
.shares
= val
;
10815 def
->cputune
.sharesSpecified
= true;
10817 if (virTypedParamsAddULLong(&eventParams
, &eventNparams
,
10819 VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES
,
10824 if (persistentDef
) {
10825 persistentDefCopy
->cputune
.shares
= value_ul
;
10826 persistentDefCopy
->cputune
.sharesSpecified
= true;
10830 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD
)) {
10831 SCHED_RANGE_CHECK(value_ul
, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD
,
10832 QEMU_SCHED_MIN_PERIOD
, QEMU_SCHED_MAX_PERIOD
);
10834 if (def
&& value_ul
) {
10835 if ((rc
= qemuSetVcpusBWLive(vm
, priv
->cgroup
, value_ul
, 0)))
10838 def
->cputune
.period
= value_ul
;
10840 if (virTypedParamsAddULLong(&eventParams
, &eventNparams
,
10842 VIR_DOMAIN_TUNABLE_CPU_VCPU_PERIOD
,
10848 persistentDefCopy
->cputune
.period
= value_ul
;
10850 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA
)) {
10851 SCHED_RANGE_CHECK(value_l
, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA
,
10852 QEMU_SCHED_MIN_QUOTA
, QEMU_SCHED_MAX_QUOTA
);
10854 if (def
&& value_l
) {
10855 if ((rc
= qemuSetVcpusBWLive(vm
, priv
->cgroup
, 0, value_l
)))
10858 def
->cputune
.quota
= value_l
;
10860 if (virTypedParamsAddLLong(&eventParams
, &eventNparams
,
10862 VIR_DOMAIN_TUNABLE_CPU_VCPU_QUOTA
,
10868 persistentDefCopy
->cputune
.quota
= value_l
;
10870 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD
)) {
10871 SCHED_RANGE_CHECK(value_ul
, VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD
,
10872 QEMU_SCHED_MIN_PERIOD
, QEMU_SCHED_MAX_PERIOD
);
10874 if (def
&& value_ul
) {
10875 if ((rc
= qemuSetGlobalBWLive(priv
->cgroup
, value_ul
, 0)))
10878 def
->cputune
.global_period
= value_ul
;
10880 if (virTypedParamsAddULLong(&eventParams
, &eventNparams
,
10882 VIR_DOMAIN_TUNABLE_CPU_GLOBAL_PERIOD
,
10888 persistentDefCopy
->cputune
.global_period
= value_ul
;
10890 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA
)) {
10891 SCHED_RANGE_CHECK(value_l
, VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA
,
10892 QEMU_SCHED_MIN_QUOTA
, QEMU_SCHED_MAX_QUOTA
);
10894 if (def
&& value_l
) {
10895 if ((rc
= qemuSetGlobalBWLive(priv
->cgroup
, 0, value_l
)))
10898 def
->cputune
.global_quota
= value_l
;
10900 if (virTypedParamsAddLLong(&eventParams
, &eventNparams
,
10902 VIR_DOMAIN_TUNABLE_CPU_GLOBAL_QUOTA
,
10908 persistentDefCopy
->cputune
.global_quota
= value_l
;
10910 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD
)) {
10911 SCHED_RANGE_CHECK(value_ul
, VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD
,
10912 QEMU_SCHED_MIN_PERIOD
, QEMU_SCHED_MAX_PERIOD
);
10914 if (def
&& value_ul
) {
10915 if ((rc
= qemuSetEmulatorBandwidthLive(priv
->cgroup
,
10919 def
->cputune
.emulator_period
= value_ul
;
10921 if (virTypedParamsAddULLong(&eventParams
, &eventNparams
,
10923 VIR_DOMAIN_TUNABLE_CPU_EMULATOR_PERIOD
,
10929 persistentDefCopy
->cputune
.emulator_period
= value_ul
;
10931 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA
)) {
10932 SCHED_RANGE_CHECK(value_l
, VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA
,
10933 QEMU_SCHED_MIN_QUOTA
, QEMU_SCHED_MAX_QUOTA
);
10935 if (def
&& value_l
) {
10936 if ((rc
= qemuSetEmulatorBandwidthLive(priv
->cgroup
,
10940 def
->cputune
.emulator_quota
= value_l
;
10942 if (virTypedParamsAddLLong(&eventParams
, &eventNparams
,
10944 VIR_DOMAIN_TUNABLE_CPU_EMULATOR_QUOTA
,
10950 persistentDefCopy
->cputune
.emulator_quota
= value_l
;
10952 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD
)) {
10953 SCHED_RANGE_CHECK(value_ul
, VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD
,
10954 QEMU_SCHED_MIN_PERIOD
, QEMU_SCHED_MAX_PERIOD
);
10956 if (def
&& value_ul
) {
10957 if ((rc
= qemuSetIOThreadsBWLive(vm
, priv
->cgroup
, value_ul
, 0)))
10960 def
->cputune
.iothread_period
= value_ul
;
10962 if (virTypedParamsAddULLong(&eventParams
, &eventNparams
,
10964 VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_PERIOD
,
10970 persistentDefCopy
->cputune
.iothread_period
= value_ul
;
10972 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA
)) {
10973 SCHED_RANGE_CHECK(value_l
, VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA
,
10974 QEMU_SCHED_MIN_QUOTA
, QEMU_SCHED_MAX_QUOTA
);
10976 if (def
&& value_l
) {
10977 if ((rc
= qemuSetIOThreadsBWLive(vm
, priv
->cgroup
, 0, value_l
)))
10980 def
->cputune
.iothread_quota
= value_l
;
10982 if (virTypedParamsAddLLong(&eventParams
, &eventNparams
,
10984 VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_QUOTA
,
10990 persistentDefCopy
->cputune
.iothread_quota
= value_l
;
10994 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
10997 if (eventNparams
) {
10998 event
= virDomainEventTunableNewFromDom(dom
, eventParams
, eventNparams
);
11000 virObjectEventStateQueue(driver
->domainEventState
, event
);
11003 if (persistentDef
) {
11004 rc
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDefCopy
);
11008 virDomainObjAssignDef(vm
, persistentDefCopy
, false, NULL
);
11009 persistentDefCopy
= NULL
;
11015 qemuDomainObjEndJob(driver
, vm
);
11018 virDomainDefFree(persistentDefCopy
);
11019 virDomainObjEndAPI(&vm
);
11021 virTypedParamsFree(eventParams
, eventNparams
);
11022 virObjectUnref(caps
);
11023 virObjectUnref(cfg
);
11026 #undef SCHED_RANGE_CHECK
11029 qemuDomainSetSchedulerParameters(virDomainPtr dom
,
11030 virTypedParameterPtr params
,
11033 return qemuDomainSetSchedulerParametersFlags(dom
,
11036 VIR_DOMAIN_AFFECT_CURRENT
);
11040 qemuGetVcpuBWLive(virCgroupPtr cgroup
, unsigned long long *period
,
11043 if (virCgroupGetCpuCfsPeriod(cgroup
, period
) < 0)
11046 if (virCgroupGetCpuCfsQuota(cgroup
, quota
) < 0)
11053 qemuGetVcpusBWLive(virDomainObjPtr vm
,
11054 unsigned long long *period
, long long *quota
)
11056 virCgroupPtr cgroup_vcpu
= NULL
;
11057 qemuDomainObjPrivatePtr priv
= NULL
;
11061 priv
= vm
->privateData
;
11062 if (!qemuDomainHasVcpuPids(vm
)) {
11063 /* We do not create sub dir for each vcpu */
11064 rc
= qemuGetVcpuBWLive(priv
->cgroup
, period
, quota
);
11069 *quota
/= virDomainDefGetVcpus(vm
->def
);
11073 /* get period and quota for vcpu0 */
11074 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_VCPU
, 0,
11075 false, &cgroup_vcpu
) < 0)
11078 rc
= qemuGetVcpuBWLive(cgroup_vcpu
, period
, quota
);
11086 virCgroupFree(&cgroup_vcpu
);
11091 qemuGetEmulatorBandwidthLive(virCgroupPtr cgroup
,
11092 unsigned long long *period
,
11095 virCgroupPtr cgroup_emulator
= NULL
;
11098 /* get period and quota for emulator */
11099 if (virCgroupNewThread(cgroup
, VIR_CGROUP_THREAD_EMULATOR
, 0,
11100 false, &cgroup_emulator
) < 0)
11103 if (qemuGetVcpuBWLive(cgroup_emulator
, period
, quota
) < 0)
11109 virCgroupFree(&cgroup_emulator
);
11114 qemuGetIOThreadsBWLive(virDomainObjPtr vm
,
11115 unsigned long long *period
, long long *quota
)
11117 virCgroupPtr cgroup_iothread
= NULL
;
11118 qemuDomainObjPrivatePtr priv
= NULL
;
11122 priv
= vm
->privateData
;
11123 if (!vm
->def
->niothreadids
) {
11124 /* We do not create sub dir for each iothread */
11125 if ((rc
= qemuGetVcpuBWLive(priv
->cgroup
, period
, quota
)) < 0)
11131 /* get period and quota for the "first" IOThread */
11132 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_IOTHREAD
,
11133 vm
->def
->iothreadids
[0]->iothread_id
,
11134 false, &cgroup_iothread
) < 0)
11137 rc
= qemuGetVcpuBWLive(cgroup_iothread
, period
, quota
);
11145 virCgroupFree(&cgroup_iothread
);
11151 qemuGetGlobalBWLive(virCgroupPtr cgroup
, unsigned long long *period
,
11154 if (qemuGetVcpuBWLive(cgroup
, period
, quota
) < 0)
11161 qemuDomainGetSchedulerParametersFlags(virDomainPtr dom
,
11162 virTypedParameterPtr params
,
11164 unsigned int flags
)
11166 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
11167 virDomainObjPtr vm
= NULL
;
11168 virDomainCputune data
= {0};
11170 bool cpu_bw_status
= true;
11171 virDomainDefPtr persistentDef
;
11172 virDomainDefPtr def
;
11173 qemuDomainObjPrivatePtr priv
;
11174 int maxparams
= *nparams
;
11178 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
11179 VIR_DOMAIN_AFFECT_CONFIG
|
11180 VIR_TYPED_PARAM_STRING_OKAY
, -1);
11182 if (!(vm
= qemuDomObjFromDomain(dom
)))
11185 priv
= vm
->privateData
;
11187 if (virDomainGetSchedulerParametersFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
11190 if (!virQEMUDriverIsPrivileged(driver
)) {
11191 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
11192 _("CPU tuning is not available in session mode"));
11196 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
11199 if (persistentDef
) {
11200 data
= persistentDef
->cputune
;
11202 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPU
)) {
11203 virReportError(VIR_ERR_OPERATION_INVALID
,
11204 "%s", _("cgroup CPU controller is not mounted"));
11208 if (virCgroupGetCpuShares(priv
->cgroup
, &data
.shares
) < 0)
11211 if (virCgroupSupportsCpuBW(priv
->cgroup
)) {
11212 if (maxparams
> 1 &&
11213 qemuGetVcpusBWLive(vm
, &data
.period
, &data
.quota
) < 0)
11216 if (maxparams
> 3 &&
11217 qemuGetEmulatorBandwidthLive(priv
->cgroup
, &data
.emulator_period
,
11218 &data
.emulator_quota
) < 0)
11221 if (maxparams
> 5 &&
11222 qemuGetGlobalBWLive(priv
->cgroup
, &data
.global_period
,
11223 &data
.global_quota
) < 0)
11226 if (maxparams
> 7 &&
11227 qemuGetIOThreadsBWLive(vm
, &data
.iothread_period
,
11228 &data
.iothread_quota
) < 0)
11231 cpu_bw_status
= false;
11235 #define QEMU_SCHED_ASSIGN(param, name, type) \
11236 if (*nparams < maxparams && \
11237 virTypedParameterAssign(&(params[(*nparams)++]), \
11238 VIR_DOMAIN_SCHEDULER_ ## name, \
11239 VIR_TYPED_PARAM_ ## type, \
11243 QEMU_SCHED_ASSIGN(shares
, CPU_SHARES
, ULLONG
);
11245 if (cpu_bw_status
) {
11246 QEMU_SCHED_ASSIGN(period
, VCPU_PERIOD
, ULLONG
);
11247 QEMU_SCHED_ASSIGN(quota
, VCPU_QUOTA
, LLONG
);
11249 QEMU_SCHED_ASSIGN(emulator_period
, EMULATOR_PERIOD
, ULLONG
);
11250 QEMU_SCHED_ASSIGN(emulator_quota
, EMULATOR_QUOTA
, LLONG
);
11252 QEMU_SCHED_ASSIGN(global_period
, GLOBAL_PERIOD
, ULLONG
);
11253 QEMU_SCHED_ASSIGN(global_quota
, GLOBAL_QUOTA
, LLONG
);
11255 QEMU_SCHED_ASSIGN(iothread_period
, IOTHREAD_PERIOD
, ULLONG
);
11256 QEMU_SCHED_ASSIGN(iothread_quota
, IOTHREAD_QUOTA
, LLONG
);
11259 #undef QEMU_SCHED_ASSIGN
11264 virDomainObjEndAPI(&vm
);
11269 qemuDomainGetSchedulerParameters(virDomainPtr dom
,
11270 virTypedParameterPtr params
,
11273 return qemuDomainGetSchedulerParametersFlags(dom
, params
, nparams
,
11274 VIR_DOMAIN_AFFECT_CURRENT
);
11278 * Resize a block device while a guest is running. Resize to a lower size
11279 * is supported, but should be used with extreme caution. Note that it
11280 * only supports to resize image files, it can't resize block devices
11281 * like LVM volumes.
11284 qemuDomainBlockResize(virDomainPtr dom
,
11286 unsigned long long size
,
11287 unsigned int flags
)
11289 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
11290 virDomainObjPtr vm
;
11291 qemuDomainObjPrivatePtr priv
;
11293 char *device
= NULL
;
11294 const char *nodename
= NULL
;
11295 virDomainDiskDefPtr disk
= NULL
;
11297 virCheckFlags(VIR_DOMAIN_BLOCK_RESIZE_BYTES
, -1);
11299 /* We prefer operating on bytes. */
11300 if ((flags
& VIR_DOMAIN_BLOCK_RESIZE_BYTES
) == 0) {
11301 if (size
> ULLONG_MAX
/ 1024) {
11302 virReportError(VIR_ERR_OVERFLOW
,
11303 _("size must be less than %llu"),
11304 ULLONG_MAX
/ 1024);
11310 if (!(vm
= qemuDomObjFromDomain(dom
)))
11313 priv
= vm
->privateData
;
11315 if (virDomainBlockResizeEnsureACL(dom
->conn
, vm
->def
) < 0)
11318 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
11321 if (virDomainObjCheckActive(vm
) < 0)
11324 if (!(disk
= virDomainDiskByName(vm
->def
, path
, false))) {
11325 virReportError(VIR_ERR_INVALID_ARG
,
11326 _("disk '%s' was not found in the domain config"), path
);
11330 /* qcow2 and qed must be sized on 512 byte blocks/sectors,
11331 * so adjust size if necessary to round up.
11333 if (disk
->src
->format
== VIR_STORAGE_FILE_QCOW2
||
11334 disk
->src
->format
== VIR_STORAGE_FILE_QED
)
11335 size
= VIR_ROUND_UP(size
, 512);
11337 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
)) {
11338 if (virStorageSourceIsEmpty(disk
->src
) || disk
->src
->readonly
) {
11339 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
11340 _("can't resize empty or readonly disk '%s'"),
11345 nodename
= disk
->src
->nodeformat
;
11347 if (!(device
= qemuAliasDiskDriveFromDisk(disk
)))
11351 qemuDomainObjEnterMonitor(driver
, vm
);
11352 if (qemuMonitorBlockResize(priv
->mon
, device
, nodename
, size
) < 0) {
11353 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
11356 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
11362 qemuDomainObjEndJob(driver
, vm
);
11366 virDomainObjEndAPI(&vm
);
11372 qemuDomainBlockStatsGatherTotals(qemuBlockStatsPtr data
,
11373 qemuBlockStatsPtr total
)
11375 #define QEMU_BLOCK_STAT_TOTAL(NAME) \
11376 if (data->NAME > 0) \
11377 total->NAME += data->NAME
11379 QEMU_BLOCK_STAT_TOTAL(wr_bytes
);
11380 QEMU_BLOCK_STAT_TOTAL(wr_req
);
11381 QEMU_BLOCK_STAT_TOTAL(rd_bytes
);
11382 QEMU_BLOCK_STAT_TOTAL(rd_req
);
11383 QEMU_BLOCK_STAT_TOTAL(flush_req
);
11384 QEMU_BLOCK_STAT_TOTAL(wr_total_times
);
11385 QEMU_BLOCK_STAT_TOTAL(rd_total_times
);
11386 QEMU_BLOCK_STAT_TOTAL(flush_total_times
);
11387 #undef QEMU_BLOCK_STAT_TOTAL
11393 * qemuDomainBlocksStatsGather:
11394 * @driver: driver object
11395 * @vm: domain object
11396 * @path: to gather the statistics for
11397 * @capacity: refresh capacity of the backing image
11398 * @retstats: returns pointer to structure holding the stats
11400 * Gathers the block statistics for use in qemuDomainBlockStats* APIs.
11402 * Returns -1 on error; number of filled block statistics on success.
11405 qemuDomainBlocksStatsGather(virQEMUDriverPtr driver
,
11406 virDomainObjPtr vm
,
11409 qemuBlockStatsPtr
*retstats
)
11411 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
11412 bool blockdev
= virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
);
11413 virDomainDiskDefPtr disk
= NULL
;
11414 virHashTablePtr blockstats
= NULL
;
11415 qemuBlockStatsPtr stats
;
11419 const char *entryname
= NULL
;
11423 if (!(disk
= virDomainDiskByName(vm
->def
, path
, false))) {
11424 virReportError(VIR_ERR_INVALID_ARG
, _("invalid path: %s"), path
);
11429 entryname
= QEMU_DOMAIN_DISK_PRIVATE(disk
)->qomName
;
11431 if (!disk
->info
.alias
) {
11432 virReportError(VIR_ERR_INTERNAL_ERROR
,
11433 _("missing disk device alias name for %s"), disk
->dst
);
11437 entryname
= disk
->info
.alias
;
11441 qemuDomainObjEnterMonitor(driver
, vm
);
11442 nstats
= qemuMonitorGetAllBlockStatsInfo(priv
->mon
, &blockstats
, false);
11444 if (capacity
&& nstats
>= 0) {
11446 rc
= qemuMonitorBlockStatsUpdateCapacityBlockdev(priv
->mon
, blockstats
);
11448 rc
= qemuMonitorBlockStatsUpdateCapacity(priv
->mon
, blockstats
, false);
11451 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || nstats
< 0 || rc
< 0)
11454 if (VIR_ALLOC(*retstats
) < 0)
11458 if (!(stats
= virHashLookup(blockstats
, entryname
))) {
11459 virReportError(VIR_ERR_INTERNAL_ERROR
,
11460 _("cannot find statistics for device '%s'"), entryname
);
11464 **retstats
= *stats
;
11467 /* capacity are reported only per node-name so we need to transfer them */
11468 qemuBlockStatsPtr capstats
;
11470 if (disk
&& disk
->src
&&
11471 (capstats
= virHashLookup(blockstats
, disk
->src
->nodeformat
))) {
11472 (*retstats
)->capacity
= capstats
->capacity
;
11473 (*retstats
)->physical
= capstats
->physical
;
11474 (*retstats
)->wr_highest_offset
= capstats
->wr_highest_offset
;
11475 (*retstats
)->wr_highest_offset_valid
= capstats
->wr_highest_offset_valid
;
11476 (*retstats
)->write_threshold
= capstats
->write_threshold
;
11480 for (i
= 0; i
< vm
->def
->ndisks
; i
++) {
11481 disk
= vm
->def
->disks
[i
];
11482 entryname
= disk
->info
.alias
;
11485 entryname
= QEMU_DOMAIN_DISK_PRIVATE(disk
)->qomName
;
11490 if (!(stats
= virHashLookup(blockstats
, entryname
))) {
11491 virReportError(VIR_ERR_INTERNAL_ERROR
,
11492 _("cannot find statistics for device '%s'"), entryname
);
11496 qemuDomainBlockStatsGatherTotals(stats
, *retstats
);
11503 virHashFree(blockstats
);
11508 /* This uses the 'info blockstats' monitor command which was
11509 * integrated into both qemu & kvm in late 2007. If the command is
11510 * not supported we detect this and return the appropriate error.
11513 qemuDomainBlockStats(virDomainPtr dom
,
11515 virDomainBlockStatsPtr stats
)
11517 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
11518 qemuBlockStatsPtr blockstats
= NULL
;
11520 virDomainObjPtr vm
;
11522 if (!(vm
= qemuDomObjFromDomain(dom
)))
11525 if (virDomainBlockStatsEnsureACL(dom
->conn
, vm
->def
) < 0)
11528 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
11531 if (virDomainObjCheckActive(vm
) < 0)
11534 if (qemuDomainBlocksStatsGather(driver
, vm
, path
, false, &blockstats
) < 0)
11537 stats
->rd_req
= blockstats
->rd_req
;
11538 stats
->rd_bytes
= blockstats
->rd_bytes
;
11539 stats
->wr_req
= blockstats
->wr_req
;
11540 stats
->wr_bytes
= blockstats
->wr_bytes
;
11541 /* qemu doesn't report the error count */
11547 qemuDomainObjEndJob(driver
, vm
);
11550 virDomainObjEndAPI(&vm
);
11551 VIR_FREE(blockstats
);
11557 qemuDomainBlockStatsFlags(virDomainPtr dom
,
11559 virTypedParameterPtr params
,
11561 unsigned int flags
)
11563 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
11564 virDomainObjPtr vm
;
11565 qemuBlockStatsPtr blockstats
= NULL
;
11569 VIR_DEBUG("params=%p, flags=0x%x", params
, flags
);
11571 virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY
, -1);
11573 /* We don't return strings, and thus trivially support this flag. */
11574 flags
&= ~VIR_TYPED_PARAM_STRING_OKAY
;
11576 if (!(vm
= qemuDomObjFromDomain(dom
)))
11579 if (virDomainBlockStatsFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
11582 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
11585 if (virDomainObjCheckActive(vm
) < 0)
11588 if ((nstats
= qemuDomainBlocksStatsGather(driver
, vm
, path
, false,
11592 /* return count of supported stats */
11593 if (*nparams
== 0) {
11601 #define QEMU_BLOCK_STATS_ASSIGN_PARAM(VAR, NAME) \
11602 if (nstats < *nparams && (blockstats->VAR) != -1) { \
11603 if (virTypedParameterAssign(params + nstats, NAME, \
11604 VIR_TYPED_PARAM_LLONG, (blockstats->VAR)) < 0) \
11609 QEMU_BLOCK_STATS_ASSIGN_PARAM(wr_bytes
, VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES
);
11610 QEMU_BLOCK_STATS_ASSIGN_PARAM(wr_req
, VIR_DOMAIN_BLOCK_STATS_WRITE_REQ
);
11612 QEMU_BLOCK_STATS_ASSIGN_PARAM(rd_bytes
, VIR_DOMAIN_BLOCK_STATS_READ_BYTES
);
11613 QEMU_BLOCK_STATS_ASSIGN_PARAM(rd_req
, VIR_DOMAIN_BLOCK_STATS_READ_REQ
);
11615 QEMU_BLOCK_STATS_ASSIGN_PARAM(flush_req
, VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ
);
11617 QEMU_BLOCK_STATS_ASSIGN_PARAM(wr_total_times
,
11618 VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES
);
11619 QEMU_BLOCK_STATS_ASSIGN_PARAM(rd_total_times
,
11620 VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES
);
11621 QEMU_BLOCK_STATS_ASSIGN_PARAM(flush_total_times
,
11622 VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES
);
11623 #undef QEMU_BLOCK_STATS_ASSIGN_PARAM
11629 qemuDomainObjEndJob(driver
, vm
);
11632 VIR_FREE(blockstats
);
11633 virDomainObjEndAPI(&vm
);
11638 qemuDomainInterfaceStats(virDomainPtr dom
,
11639 const char *device
,
11640 virDomainInterfaceStatsPtr stats
)
11642 virDomainObjPtr vm
;
11643 virDomainNetDefPtr net
= NULL
;
11646 if (!(vm
= qemuDomObjFromDomain(dom
)))
11649 if (virDomainInterfaceStatsEnsureACL(dom
->conn
, vm
->def
) < 0)
11652 if (virDomainObjCheckActive(vm
) < 0)
11655 if (!(net
= virDomainNetFind(vm
->def
, device
)))
11658 if (virDomainNetGetActualType(net
) == VIR_DOMAIN_NET_TYPE_VHOSTUSER
) {
11659 if (virNetDevOpenvswitchInterfaceStats(net
->ifname
, stats
) < 0)
11662 if (virNetDevTapInterfaceStats(net
->ifname
, stats
,
11663 !virDomainNetTypeSharesHostView(net
)) < 0)
11669 virDomainObjEndAPI(&vm
);
11674 qemuDomainSetInterfaceParameters(virDomainPtr dom
,
11675 const char *device
,
11676 virTypedParameterPtr params
,
11678 unsigned int flags
)
11680 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
11682 virDomainObjPtr vm
= NULL
;
11683 virDomainDefPtr def
;
11684 virDomainDefPtr persistentDef
;
11686 virDomainNetDefPtr net
= NULL
, persistentNet
= NULL
;
11687 virNetDevBandwidthPtr bandwidth
= NULL
, newBandwidth
= NULL
;
11688 virQEMUDriverConfigPtr cfg
= NULL
;
11689 bool inboundSpecified
= false, outboundSpecified
= false;
11691 bool qosSupported
= true;
11693 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
11694 VIR_DOMAIN_AFFECT_CONFIG
, -1);
11695 if (virTypedParamsValidate(params
, nparams
,
11696 VIR_DOMAIN_BANDWIDTH_IN_AVERAGE
,
11697 VIR_TYPED_PARAM_UINT
,
11698 VIR_DOMAIN_BANDWIDTH_IN_PEAK
,
11699 VIR_TYPED_PARAM_UINT
,
11700 VIR_DOMAIN_BANDWIDTH_IN_BURST
,
11701 VIR_TYPED_PARAM_UINT
,
11702 VIR_DOMAIN_BANDWIDTH_IN_FLOOR
,
11703 VIR_TYPED_PARAM_UINT
,
11704 VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE
,
11705 VIR_TYPED_PARAM_UINT
,
11706 VIR_DOMAIN_BANDWIDTH_OUT_PEAK
,
11707 VIR_TYPED_PARAM_UINT
,
11708 VIR_DOMAIN_BANDWIDTH_OUT_BURST
,
11709 VIR_TYPED_PARAM_UINT
,
11713 if (!(vm
= qemuDomObjFromDomain(dom
)))
11716 cfg
= virQEMUDriverGetConfig(driver
);
11718 if (virDomainSetInterfaceParametersEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
11721 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
11724 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
11728 !(net
= virDomainNetFind(vm
->def
, device
)))
11731 if (persistentDef
&&
11732 !(persistentNet
= virDomainNetFind(persistentDef
, device
)))
11736 actualType
= virDomainNetGetActualType(net
);
11737 qosSupported
= virNetDevSupportBandwidth(actualType
);
11740 if (qosSupported
&& persistentNet
) {
11741 actualType
= virDomainNetGetActualType(persistentNet
);
11742 qosSupported
= virNetDevSupportBandwidth(actualType
);
11745 if (!qosSupported
) {
11746 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
11747 _("setting bandwidth on interfaces of "
11748 "type '%s' is not implemented yet"),
11749 virDomainNetTypeToString(actualType
));
11753 if ((VIR_ALLOC(bandwidth
) < 0) ||
11754 (VIR_ALLOC(bandwidth
->in
) < 0) ||
11755 (VIR_ALLOC(bandwidth
->out
) < 0))
11758 for (i
= 0; i
< nparams
; i
++) {
11759 virTypedParameterPtr param
= ¶ms
[i
];
11761 if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_IN_AVERAGE
)) {
11762 bandwidth
->in
->average
= param
->value
.ui
;
11763 inboundSpecified
= true;
11764 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_IN_PEAK
)) {
11765 bandwidth
->in
->peak
= param
->value
.ui
;
11766 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_IN_BURST
)) {
11767 bandwidth
->in
->burst
= param
->value
.ui
;
11768 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_IN_FLOOR
)) {
11769 bandwidth
->in
->floor
= param
->value
.ui
;
11770 inboundSpecified
= true;
11771 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE
)) {
11772 bandwidth
->out
->average
= param
->value
.ui
;
11773 outboundSpecified
= true;
11774 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_OUT_PEAK
)) {
11775 bandwidth
->out
->peak
= param
->value
.ui
;
11776 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_OUT_BURST
)) {
11777 bandwidth
->out
->burst
= param
->value
.ui
;
11781 /* average or floor are mandatory, peak and burst are optional.
11782 * So if no average or floor is given, we free inbound/outbound
11783 * here which causes inbound/outbound to not be set. */
11784 if (!bandwidth
->in
->average
&& !bandwidth
->in
->floor
)
11785 VIR_FREE(bandwidth
->in
);
11786 if (!bandwidth
->out
->average
)
11787 VIR_FREE(bandwidth
->out
);
11790 if (VIR_ALLOC(newBandwidth
) < 0)
11793 /* virNetDevBandwidthSet() will clear any previous value of
11794 * bandwidth parameters, so merge with old bandwidth parameters
11795 * here to prevent them from being lost. */
11796 if (bandwidth
->in
||
11797 (!inboundSpecified
&& net
->bandwidth
&& net
->bandwidth
->in
)) {
11798 if (VIR_ALLOC(newBandwidth
->in
) < 0)
11801 memcpy(newBandwidth
->in
,
11802 bandwidth
->in
? bandwidth
->in
: net
->bandwidth
->in
,
11803 sizeof(*newBandwidth
->in
));
11805 if (bandwidth
->out
||
11806 (!outboundSpecified
&& net
->bandwidth
&& net
->bandwidth
->out
)) {
11807 if (VIR_ALLOC(newBandwidth
->out
) < 0)
11810 memcpy(newBandwidth
->out
,
11811 bandwidth
->out
? bandwidth
->out
: net
->bandwidth
->out
,
11812 sizeof(*newBandwidth
->out
));
11815 if (!virDomainNetBandwidthChangeAllowed(net
, newBandwidth
))
11818 if (virNetDevBandwidthSet(net
->ifname
, newBandwidth
, false,
11819 !virDomainNetTypeSharesHostView(net
)) < 0 ||
11820 virDomainNetBandwidthUpdate(net
, newBandwidth
) < 0) {
11821 ignore_value(virNetDevBandwidthSet(net
->ifname
,
11824 !virDomainNetTypeSharesHostView(net
)));
11828 virNetDevBandwidthFree(net
->bandwidth
);
11829 if (newBandwidth
->in
|| newBandwidth
->out
) {
11830 net
->bandwidth
= newBandwidth
;
11831 newBandwidth
= NULL
;
11833 net
->bandwidth
= NULL
;
11836 if (net
->type
== VIR_DOMAIN_NET_TYPE_NETWORK
) {
11837 virNetDevBandwidthFree(net
->data
.network
.actual
->bandwidth
);
11838 if (virNetDevBandwidthCopy(&net
->data
.network
.actual
->bandwidth
,
11839 net
->bandwidth
) < 0)
11843 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
11847 if (persistentNet
) {
11848 if (!persistentNet
->bandwidth
) {
11849 persistentNet
->bandwidth
= bandwidth
;
11852 if (bandwidth
->in
) {
11853 VIR_FREE(persistentNet
->bandwidth
->in
);
11854 persistentNet
->bandwidth
->in
= bandwidth
->in
;
11855 bandwidth
->in
= NULL
;
11856 } else if (inboundSpecified
) {
11857 VIR_FREE(persistentNet
->bandwidth
->in
);
11859 if (bandwidth
->out
) {
11860 VIR_FREE(persistentNet
->bandwidth
->out
);
11861 persistentNet
->bandwidth
->out
= bandwidth
->out
;
11862 bandwidth
->out
= NULL
;
11863 } else if (outboundSpecified
) {
11864 VIR_FREE(persistentNet
->bandwidth
->out
);
11868 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
11875 qemuDomainObjEndJob(driver
, vm
);
11878 virNetDevBandwidthFree(bandwidth
);
11879 virNetDevBandwidthFree(newBandwidth
);
11880 virDomainObjEndAPI(&vm
);
11881 virObjectUnref(cfg
);
11886 qemuDomainGetInterfaceParameters(virDomainPtr dom
,
11887 const char *device
,
11888 virTypedParameterPtr params
,
11890 unsigned int flags
)
11893 virDomainObjPtr vm
= NULL
;
11894 virDomainDefPtr def
= NULL
;
11895 virDomainNetDefPtr net
= NULL
;
11898 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
11899 VIR_DOMAIN_AFFECT_CONFIG
|
11900 VIR_TYPED_PARAM_STRING_OKAY
, -1);
11902 if (!(vm
= qemuDomObjFromDomain(dom
)))
11905 if (virDomainGetInterfaceParametersEnsureACL(dom
->conn
, vm
->def
) < 0)
11908 if (!(def
= virDomainObjGetOneDef(vm
, flags
)))
11911 if ((*nparams
) == 0) {
11912 *nparams
= QEMU_NB_BANDWIDTH_PARAM
;
11917 if (!(net
= virDomainNetFind(def
, device
)))
11920 for (i
= 0; i
< *nparams
&& i
< QEMU_NB_BANDWIDTH_PARAM
; i
++) {
11922 case 0: /* inbound.average */
11923 if (virTypedParameterAssign(¶ms
[i
],
11924 VIR_DOMAIN_BANDWIDTH_IN_AVERAGE
,
11925 VIR_TYPED_PARAM_UINT
, 0) < 0)
11927 if (net
->bandwidth
&& net
->bandwidth
->in
)
11928 params
[i
].value
.ui
= net
->bandwidth
->in
->average
;
11930 case 1: /* inbound.peak */
11931 if (virTypedParameterAssign(¶ms
[i
],
11932 VIR_DOMAIN_BANDWIDTH_IN_PEAK
,
11933 VIR_TYPED_PARAM_UINT
, 0) < 0)
11935 if (net
->bandwidth
&& net
->bandwidth
->in
)
11936 params
[i
].value
.ui
= net
->bandwidth
->in
->peak
;
11938 case 2: /* inbound.burst */
11939 if (virTypedParameterAssign(¶ms
[i
],
11940 VIR_DOMAIN_BANDWIDTH_IN_BURST
,
11941 VIR_TYPED_PARAM_UINT
, 0) < 0)
11943 if (net
->bandwidth
&& net
->bandwidth
->in
)
11944 params
[i
].value
.ui
= net
->bandwidth
->in
->burst
;
11946 case 3: /* inbound.floor */
11947 if (virTypedParameterAssign(¶ms
[i
],
11948 VIR_DOMAIN_BANDWIDTH_IN_FLOOR
,
11949 VIR_TYPED_PARAM_UINT
, 0) < 0)
11951 if (net
->bandwidth
&& net
->bandwidth
->in
)
11952 params
[i
].value
.ui
= net
->bandwidth
->in
->floor
;
11954 case 4: /* outbound.average */
11955 if (virTypedParameterAssign(¶ms
[i
],
11956 VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE
,
11957 VIR_TYPED_PARAM_UINT
, 0) < 0)
11959 if (net
->bandwidth
&& net
->bandwidth
->out
)
11960 params
[i
].value
.ui
= net
->bandwidth
->out
->average
;
11962 case 5: /* outbound.peak */
11963 if (virTypedParameterAssign(¶ms
[i
],
11964 VIR_DOMAIN_BANDWIDTH_OUT_PEAK
,
11965 VIR_TYPED_PARAM_UINT
, 0) < 0)
11967 if (net
->bandwidth
&& net
->bandwidth
->out
)
11968 params
[i
].value
.ui
= net
->bandwidth
->out
->peak
;
11970 case 6: /* outbound.burst */
11971 if (virTypedParameterAssign(¶ms
[i
],
11972 VIR_DOMAIN_BANDWIDTH_OUT_BURST
,
11973 VIR_TYPED_PARAM_UINT
, 0) < 0)
11975 if (net
->bandwidth
&& net
->bandwidth
->out
)
11976 params
[i
].value
.ui
= net
->bandwidth
->out
->burst
;
11978 /* coverity[dead_error_begin] */
11981 /* should not hit here */
11985 if (*nparams
> QEMU_NB_BANDWIDTH_PARAM
)
11986 *nparams
= QEMU_NB_BANDWIDTH_PARAM
;
11990 virDomainObjEndAPI(&vm
);
11994 /* This functions assumes that job QEMU_JOB_QUERY is started by a caller */
11996 qemuDomainMemoryStatsInternal(virQEMUDriverPtr driver
,
11997 virDomainObjPtr vm
,
11998 virDomainMemoryStatPtr stats
,
11999 unsigned int nr_stats
)
12005 if (virDomainObjCheckActive(vm
) < 0)
12008 if (virDomainDefHasMemballoon(vm
->def
)) {
12009 qemuDomainObjEnterMonitor(driver
, vm
);
12010 ret
= qemuMonitorGetMemoryStats(qemuDomainGetMonitor(vm
),
12011 vm
->def
->memballoon
, stats
, nr_stats
);
12012 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
12015 if (ret
< 0 || ret
>= nr_stats
)
12021 if (qemuGetProcessInfo(NULL
, NULL
, &rss
, vm
->pid
, 0) < 0) {
12022 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
12023 _("cannot get RSS for domain"));
12025 stats
[ret
].tag
= VIR_DOMAIN_MEMORY_STAT_RSS
;
12026 stats
[ret
].val
= rss
;
12034 qemuDomainMemoryStats(virDomainPtr dom
,
12035 virDomainMemoryStatPtr stats
,
12036 unsigned int nr_stats
,
12037 unsigned int flags
)
12039 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
12040 virDomainObjPtr vm
;
12043 virCheckFlags(0, -1);
12045 if (!(vm
= qemuDomObjFromDomain(dom
)))
12048 if (virDomainMemoryStatsEnsureACL(dom
->conn
, vm
->def
) < 0)
12051 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
12054 ret
= qemuDomainMemoryStatsInternal(driver
, vm
, stats
, nr_stats
);
12056 qemuDomainObjEndJob(driver
, vm
);
12059 virDomainObjEndAPI(&vm
);
12064 qemuDomainBlockPeek(virDomainPtr dom
,
12066 unsigned long long offset
, size_t size
,
12068 unsigned int flags
)
12070 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
12071 virDomainDiskDefPtr disk
= NULL
;
12072 virDomainObjPtr vm
;
12073 char *tmpbuf
= NULL
;
12077 virCheckFlags(0, -1);
12079 if (!(vm
= qemuDomObjFromDomain(dom
)))
12082 if (virDomainBlockPeekEnsureACL(dom
->conn
, vm
->def
) < 0)
12085 /* Check the path belongs to this domain. */
12086 if (!(disk
= virDomainDiskByName(vm
->def
, path
, true))) {
12087 virReportError(VIR_ERR_INVALID_ARG
,
12088 _("invalid disk or path '%s'"), path
);
12092 if (disk
->src
->format
!= VIR_STORAGE_FILE_RAW
) {
12093 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
12094 _("peeking is only supported for disk with 'raw' format not '%s'"),
12095 virStorageFileFormatTypeToString(disk
->src
->format
));
12099 if (qemuDomainStorageFileInit(driver
, vm
, disk
->src
, NULL
) < 0)
12102 if ((nread
= virStorageFileRead(disk
->src
, offset
, size
, &tmpbuf
)) < 0) {
12104 virReportError(VIR_ERR_INTERNAL_ERROR
,
12105 _("storage file reading is not supported for "
12106 "storage type %s (protocol: %s)"),
12107 virStorageTypeToString(disk
->src
->type
),
12108 virStorageNetProtocolTypeToString(disk
->src
->protocol
));
12113 if (nread
< size
) {
12114 virReportError(VIR_ERR_INVALID_ARG
,
12115 _("'%s' starting from %llu has only %zd bytes available"),
12116 path
, offset
, nread
);
12120 memcpy(buffer
, tmpbuf
, size
);
12126 virStorageFileDeinit(disk
->src
);
12127 virDomainObjEndAPI(&vm
);
12133 qemuDomainMemoryPeek(virDomainPtr dom
,
12134 unsigned long long offset
, size_t size
,
12136 unsigned int flags
)
12138 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
12139 virDomainObjPtr vm
;
12141 int fd
= -1, ret
= -1;
12142 qemuDomainObjPrivatePtr priv
;
12143 virQEMUDriverConfigPtr cfg
= NULL
;
12145 virCheckFlags(VIR_MEMORY_VIRTUAL
| VIR_MEMORY_PHYSICAL
, -1);
12147 if (!(vm
= qemuDomObjFromDomain(dom
)))
12150 cfg
= virQEMUDriverGetConfig(driver
);
12152 if (virDomainMemoryPeekEnsureACL(dom
->conn
, vm
->def
) < 0)
12155 if (flags
!= VIR_MEMORY_VIRTUAL
&& flags
!= VIR_MEMORY_PHYSICAL
) {
12156 virReportError(VIR_ERR_INVALID_ARG
,
12157 "%s", _("flags parameter must be VIR_MEMORY_VIRTUAL or VIR_MEMORY_PHYSICAL"));
12161 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
12164 if (virDomainObjCheckActive(vm
) < 0)
12167 if (virAsprintf(&tmp
, "%s/qemu.mem.XXXXXX", cfg
->cacheDir
) < 0)
12170 /* Create a temporary filename. */
12171 if ((fd
= mkostemp(tmp
, O_CLOEXEC
)) == -1) {
12172 virReportSystemError(errno
,
12173 _("mkostemp(\"%s\") failed"), tmp
);
12177 qemuSecuritySetSavedStateLabel(driver
, vm
, tmp
);
12179 priv
= vm
->privateData
;
12180 qemuDomainObjEnterMonitor(driver
, vm
);
12181 if (flags
== VIR_MEMORY_VIRTUAL
) {
12182 if (qemuMonitorSaveVirtualMemory(priv
->mon
, offset
, size
, tmp
) < 0) {
12183 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
12187 if (qemuMonitorSavePhysicalMemory(priv
->mon
, offset
, size
, tmp
) < 0) {
12188 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
12192 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
12195 /* Read the memory file into buffer. */
12196 if (saferead(fd
, buffer
, size
) == (ssize_t
)-1) {
12197 virReportSystemError(errno
,
12198 _("failed to read temporary file "
12199 "created with template %s"), tmp
);
12206 qemuDomainObjEndJob(driver
, vm
);
12209 VIR_FORCE_CLOSE(fd
);
12213 virDomainObjEndAPI(&vm
);
12214 virObjectUnref(cfg
);
12220 * @driver: qemu driver data
12221 * @cfg: driver configuration data
12222 * @vm: domain object
12223 * @src: storage source data
12224 * @ret_fd: pointer to return open'd file descriptor
12225 * @ret_sb: pointer to return stat buffer (local or remote)
12227 * For local storage, open the file using qemuOpenFile and then use
12228 * fstat() to grab the stat struct data for the caller.
12230 * For remote storage, attempt to access the file and grab the stat
12231 * struct data if the remote connection supports it.
12233 * Returns 0 on success with @ret_fd and @ret_sb populated, -1 on failure
12236 qemuDomainStorageOpenStat(virQEMUDriverPtr driver
,
12237 virQEMUDriverConfigPtr cfg
,
12238 virDomainObjPtr vm
,
12239 virStorageSourcePtr src
,
12241 struct stat
*ret_sb
)
12243 if (virStorageSourceIsLocalStorage(src
)) {
12244 if ((*ret_fd
= qemuOpenFile(driver
, vm
, src
->path
, O_RDONLY
,
12248 if (fstat(*ret_fd
, ret_sb
) < 0) {
12249 virReportSystemError(errno
, _("cannot stat file '%s'"), src
->path
);
12250 VIR_FORCE_CLOSE(*ret_fd
);
12254 if (virStorageFileInitAs(src
, cfg
->user
, cfg
->group
) < 0)
12257 if (virStorageFileStat(src
, ret_sb
) < 0) {
12258 virStorageFileDeinit(src
);
12259 virReportSystemError(errno
, _("failed to stat remote file '%s'"),
12260 NULLSTR(src
->path
));
12270 * @src: storage source data
12271 * @fd: file descriptor to close for local
12273 * If local, then just close the file descriptor.
12274 * else remote, then tear down the storage driver backend connection.
12277 qemuDomainStorageCloseStat(virStorageSourcePtr src
,
12280 if (virStorageSourceIsLocalStorage(src
))
12281 VIR_FORCE_CLOSE(*fd
);
12283 virStorageFileDeinit(src
);
12288 qemuDomainStorageUpdatePhysical(virQEMUDriverPtr driver
,
12289 virQEMUDriverConfigPtr cfg
,
12290 virDomainObjPtr vm
,
12291 virStorageSourcePtr src
)
12297 if (virStorageSourceIsEmpty(src
))
12300 if (qemuDomainStorageOpenStat(driver
, cfg
, vm
, src
, &fd
, &sb
) < 0)
12303 ret
= virStorageSourceUpdatePhysicalSize(src
, fd
, &sb
);
12305 qemuDomainStorageCloseStat(src
, &fd
);
12312 * @driver: qemu driver data
12313 * @cfg: driver configuration data
12314 * @vm: domain object
12315 * @src: storage source data
12317 * Refresh the capacity and allocation limits of a given storage source.
12319 * Assumes that the caller has already obtained a domain job and only
12320 * called for an offline domain. Being offline is particularly important
12321 * since reading a file while qemu is writing it risks the reader seeing
12322 * bogus data or avoiding opening a file in order to get stat data.
12324 * We always want to check current on-disk statistics (as users have been
12325 * known to change offline images behind our backs).
12327 * For read-only disks, nothing should be changing unless the user has
12328 * requested a block-commit action. For read-write disks, we know some
12329 * special cases: capacity should not change without a block-resize (where
12330 * capacity is the only stat that requires reading a file, and even then,
12331 * only for non-raw files); and physical size of a raw image or of a
12332 * block device should likewise not be changing without block-resize.
12333 * On the other hand, allocation of a raw file can change (if the file
12334 * is sparse, but the amount of sparseness changes due to writes or
12335 * punching holes), and physical size of a non-raw file can change.
12337 * Returns 0 on success, -1 on failure
12340 qemuStorageLimitsRefresh(virQEMUDriverPtr driver
,
12341 virQEMUDriverConfigPtr cfg
,
12342 virDomainObjPtr vm
,
12343 virStorageSourcePtr src
)
12351 if (qemuDomainStorageOpenStat(driver
, cfg
, vm
, src
, &fd
, &sb
) < 0)
12354 if (virStorageSourceIsLocalStorage(src
)) {
12355 if ((len
= virFileReadHeaderFD(fd
, VIR_STORAGE_MAX_HEADER
, &buf
)) < 0) {
12356 virReportSystemError(errno
, _("cannot read header '%s'"),
12361 if ((len
= virStorageFileRead(src
, 0, VIR_STORAGE_MAX_HEADER
, &buf
)) < 0)
12365 if (virStorageSourceUpdateBackingSizes(src
, fd
, &sb
) < 0)
12368 if (virStorageSourceUpdateCapacity(src
, buf
, len
, false) < 0)
12371 /* If guest is not using raw disk format and is on a host block
12372 * device, then leave the value unspecified, so caller knows to
12373 * query the highest allocated extent from QEMU
12375 if (virStorageSourceGetActualType(src
) == VIR_STORAGE_TYPE_BLOCK
&&
12376 src
->format
!= VIR_STORAGE_FILE_RAW
&&
12377 S_ISBLK(sb
.st_mode
))
12378 src
->allocation
= 0;
12384 qemuDomainStorageCloseStat(src
, &fd
);
12390 qemuDomainGetBlockInfo(virDomainPtr dom
,
12392 virDomainBlockInfoPtr info
,
12393 unsigned int flags
)
12395 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
12396 virDomainObjPtr vm
;
12398 virDomainDiskDefPtr disk
;
12399 virQEMUDriverConfigPtr cfg
= NULL
;
12400 qemuBlockStatsPtr entry
= NULL
;
12402 virCheckFlags(0, -1);
12404 if (!(vm
= qemuDomObjFromDomain(dom
)))
12407 cfg
= virQEMUDriverGetConfig(driver
);
12409 if (virDomainGetBlockInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
12412 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
12415 if (!(disk
= virDomainDiskByName(vm
->def
, path
, false))) {
12416 virReportError(VIR_ERR_INVALID_ARG
,
12417 _("invalid path %s not assigned to domain"), path
);
12421 if (virStorageSourceIsEmpty(disk
->src
)) {
12422 virReportError(VIR_ERR_INVALID_ARG
,
12423 _("disk '%s' does not currently have a source assigned"),
12428 /* for inactive domains we have to peek into the files */
12429 if (!virDomainObjIsActive(vm
)) {
12430 if ((qemuStorageLimitsRefresh(driver
, cfg
, vm
, disk
->src
)) < 0)
12433 info
->capacity
= disk
->src
->capacity
;
12434 info
->allocation
= disk
->src
->allocation
;
12435 info
->physical
= disk
->src
->physical
;
12441 if (qemuDomainBlocksStatsGather(driver
, vm
, path
, true, &entry
) < 0)
12444 if (!entry
->wr_highest_offset_valid
) {
12445 info
->allocation
= entry
->physical
;
12447 if (virStorageSourceGetActualType(disk
->src
) == VIR_STORAGE_TYPE_FILE
&&
12448 disk
->src
->format
== VIR_STORAGE_FILE_QCOW2
)
12449 info
->allocation
= entry
->physical
;
12451 info
->allocation
= entry
->wr_highest_offset
;
12454 /* Unlike GetStatsBlock, this API has defined the expected return values
12455 * for allocation and physical slightly differently.
12457 * Having a zero for either or if they're the same is an indication that
12458 * there's a sparse file backing this device. In this case, we'll force
12459 * the setting of physical based on the on disk file size.
12461 * Additionally, if qemu hasn't written to the file yet, then set the
12462 * allocation to whatever qemu returned for physical (e.g. the "actual-
12463 * size" from the json query) as that will match the expected allocation
12464 * value for this API. NB: May still be 0 for block. */
12465 if (entry
->physical
== 0 || info
->allocation
== 0 ||
12466 info
->allocation
== entry
->physical
) {
12467 if (info
->allocation
== 0)
12468 info
->allocation
= entry
->physical
;
12470 if (qemuDomainStorageUpdatePhysical(driver
, cfg
, vm
, disk
->src
) == 0) {
12471 info
->physical
= disk
->src
->physical
;
12473 virResetLastError();
12474 info
->physical
= entry
->physical
;
12477 info
->physical
= entry
->physical
;
12480 info
->capacity
= entry
->capacity
;
12485 qemuDomainObjEndJob(driver
, vm
);
12488 virDomainObjEndAPI(&vm
);
12489 virObjectUnref(cfg
);
12495 qemuConnectDomainEventRegister(virConnectPtr conn
,
12496 virConnectDomainEventCallback callback
,
12498 virFreeCallback freecb
)
12500 virQEMUDriverPtr driver
= conn
->privateData
;
12503 if (virConnectDomainEventRegisterEnsureACL(conn
) < 0)
12506 if (virDomainEventStateRegister(conn
,
12507 driver
->domainEventState
,
12508 callback
, opaque
, freecb
) < 0)
12519 qemuConnectDomainEventDeregister(virConnectPtr conn
,
12520 virConnectDomainEventCallback callback
)
12522 virQEMUDriverPtr driver
= conn
->privateData
;
12525 if (virConnectDomainEventDeregisterEnsureACL(conn
) < 0)
12528 if (virDomainEventStateDeregister(conn
,
12529 driver
->domainEventState
,
12541 qemuConnectDomainEventRegisterAny(virConnectPtr conn
,
12544 virConnectDomainEventGenericCallback callback
,
12546 virFreeCallback freecb
)
12548 virQEMUDriverPtr driver
= conn
->privateData
;
12551 if (virConnectDomainEventRegisterAnyEnsureACL(conn
) < 0)
12554 if (virDomainEventStateRegisterID(conn
,
12555 driver
->domainEventState
,
12557 callback
, opaque
, freecb
, &ret
) < 0)
12566 qemuConnectDomainEventDeregisterAny(virConnectPtr conn
,
12569 virQEMUDriverPtr driver
= conn
->privateData
;
12572 if (virConnectDomainEventDeregisterAnyEnsureACL(conn
) < 0)
12575 if (virObjectEventStateDeregisterID(conn
,
12576 driver
->domainEventState
,
12577 callbackID
, true) < 0)
12587 /*******************************************************************
12588 * Migration Protocol Version 2
12589 *******************************************************************/
12591 /* Prepare is the first step, and it runs on the destination host.
12593 * This version starts an empty VM listening on a localhost TCP port, and
12594 * sets up the corresponding virStream to handle the incoming data.
12597 qemuDomainMigratePrepareTunnel(virConnectPtr dconn
,
12599 unsigned long flags
,
12601 unsigned long resource ATTRIBUTE_UNUSED
,
12602 const char *dom_xml
)
12604 virQEMUDriverPtr driver
= dconn
->privateData
;
12605 virDomainDefPtr def
= NULL
;
12606 char *origname
= NULL
;
12607 qemuMigrationParamsPtr migParams
= NULL
;
12610 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
12612 if (!(flags
& VIR_MIGRATE_TUNNELLED
)) {
12613 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
12614 _("PrepareTunnel called but no TUNNELLED flag set"));
12618 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
12619 QEMU_MIGRATION_DESTINATION
)))
12622 if (virLockManagerPluginUsesState(driver
->lockManager
)) {
12623 virReportError(VIR_ERR_INTERNAL_ERROR
,
12624 _("Cannot use migrate v2 protocol with lock manager %s"),
12625 virLockManagerPluginGetName(driver
->lockManager
));
12629 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
12632 if (virDomainMigratePrepareTunnelEnsureACL(dconn
, def
) < 0)
12635 ret
= qemuMigrationDstPrepareTunnel(driver
, dconn
,
12636 NULL
, 0, NULL
, NULL
, /* No cookies in v2 */
12637 st
, &def
, origname
, migParams
, flags
);
12640 qemuMigrationParamsFree(migParams
);
12641 VIR_FREE(origname
);
12642 virDomainDefFree(def
);
12646 /* Prepare is the first step, and it runs on the destination host.
12648 * This starts an empty VM listening on a TCP port.
12650 static int ATTRIBUTE_NONNULL(5)
12651 qemuDomainMigratePrepare2(virConnectPtr dconn
,
12652 char **cookie ATTRIBUTE_UNUSED
,
12653 int *cookielen ATTRIBUTE_UNUSED
,
12654 const char *uri_in
,
12656 unsigned long flags
,
12658 unsigned long resource ATTRIBUTE_UNUSED
,
12659 const char *dom_xml
)
12661 virQEMUDriverPtr driver
= dconn
->privateData
;
12662 virDomainDefPtr def
= NULL
;
12663 char *origname
= NULL
;
12664 qemuMigrationParamsPtr migParams
= NULL
;
12667 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
12669 if (flags
& VIR_MIGRATE_TUNNELLED
) {
12670 /* this is a logical error; we never should have gotten here with
12671 * VIR_MIGRATE_TUNNELLED set
12673 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
12674 _("Tunnelled migration requested but invalid "
12675 "RPC method called"));
12679 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
12680 QEMU_MIGRATION_DESTINATION
)))
12683 if (virLockManagerPluginUsesState(driver
->lockManager
)) {
12684 virReportError(VIR_ERR_INTERNAL_ERROR
,
12685 _("Cannot use migrate v2 protocol with lock manager %s"),
12686 virLockManagerPluginGetName(driver
->lockManager
));
12690 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
12693 if (virDomainMigratePrepare2EnsureACL(dconn
, def
) < 0)
12696 /* Do not use cookies in v2 protocol, since the cookie
12697 * length was not sufficiently large, causing failures
12698 * migrating between old & new libvirtd
12700 ret
= qemuMigrationDstPrepareDirect(driver
, dconn
,
12701 NULL
, 0, NULL
, NULL
, /* No cookies */
12703 &def
, origname
, NULL
, 0, NULL
, 0,
12707 qemuMigrationParamsFree(migParams
);
12708 VIR_FREE(origname
);
12709 virDomainDefFree(def
);
12714 /* Perform is the second step, and it runs on the source host. */
12716 qemuDomainMigratePerform(virDomainPtr dom
,
12717 const char *cookie
,
12720 unsigned long flags
,
12722 unsigned long resource
)
12724 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
12725 virDomainObjPtr vm
;
12727 const char *dconnuri
= NULL
;
12728 qemuMigrationParamsPtr migParams
= NULL
;
12730 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
12732 if (virLockManagerPluginUsesState(driver
->lockManager
)) {
12733 virReportError(VIR_ERR_INTERNAL_ERROR
,
12734 _("Cannot use migrate v2 protocol with lock manager %s"),
12735 virLockManagerPluginGetName(driver
->lockManager
));
12739 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
12740 QEMU_MIGRATION_SOURCE
)))
12743 if (!(vm
= qemuDomObjFromDomain(dom
)))
12746 if (virDomainMigratePerformEnsureACL(dom
->conn
, vm
->def
) < 0) {
12747 virDomainObjEndAPI(&vm
);
12751 if (flags
& VIR_MIGRATE_PEER2PEER
)
12752 VIR_STEAL_PTR(dconnuri
, uri
);
12754 /* Do not output cookies in v2 protocol, since the cookie
12755 * length was not sufficiently large, causing failures
12756 * migrating between old & new libvirtd.
12758 * Consume any cookie we were able to decode though
12760 ret
= qemuMigrationSrcPerform(driver
, dom
->conn
, vm
, NULL
,
12761 NULL
, dconnuri
, uri
, NULL
, NULL
, 0, NULL
, 0,
12762 migParams
, cookie
, cookielen
,
12763 NULL
, NULL
, /* No output cookies in v2 */
12764 flags
, dname
, resource
, false);
12767 qemuMigrationParamsFree(migParams
);
12772 /* Finish is the third and final step, and it runs on the destination host. */
12773 static virDomainPtr
12774 qemuDomainMigrateFinish2(virConnectPtr dconn
,
12776 const char *cookie ATTRIBUTE_UNUSED
,
12777 int cookielen ATTRIBUTE_UNUSED
,
12778 const char *uri ATTRIBUTE_UNUSED
,
12779 unsigned long flags
,
12782 virQEMUDriverPtr driver
= dconn
->privateData
;
12783 virDomainObjPtr vm
;
12784 virDomainPtr dom
= NULL
;
12786 virCheckFlags(QEMU_MIGRATION_FLAGS
, NULL
);
12788 vm
= virDomainObjListFindByName(driver
->domains
, dname
);
12790 virReportError(VIR_ERR_NO_DOMAIN
,
12791 _("no domain with matching name '%s'"), dname
);
12792 qemuMigrationDstErrorReport(driver
, dname
);
12796 if (virDomainMigrateFinish2EnsureACL(dconn
, vm
->def
) < 0) {
12797 virDomainObjEndAPI(&vm
);
12801 /* Do not use cookies in v2 protocol, since the cookie
12802 * length was not sufficiently large, causing failures
12803 * migrating between old & new libvirtd
12805 dom
= qemuMigrationDstFinish(driver
, dconn
, vm
,
12806 NULL
, 0, NULL
, NULL
, /* No cookies */
12807 flags
, retcode
, false);
12814 /*******************************************************************
12815 * Migration Protocol Version 3
12816 *******************************************************************/
12819 qemuDomainMigrateBegin3(virDomainPtr domain
,
12823 unsigned long flags
,
12825 unsigned long resource ATTRIBUTE_UNUSED
)
12827 virDomainObjPtr vm
;
12829 virCheckFlags(QEMU_MIGRATION_FLAGS
, NULL
);
12831 if (!(vm
= qemuDomObjFromDomain(domain
)))
12834 if (virDomainMigrateBegin3EnsureACL(domain
->conn
, vm
->def
) < 0) {
12835 virDomainObjEndAPI(&vm
);
12839 return qemuMigrationSrcBegin(domain
->conn
, vm
, xmlin
, dname
,
12840 cookieout
, cookieoutlen
, 0, NULL
, flags
);
12844 qemuDomainMigrateBegin3Params(virDomainPtr domain
,
12845 virTypedParameterPtr params
,
12849 unsigned int flags
)
12851 const char *xmlin
= NULL
;
12852 const char *dname
= NULL
;
12853 const char **migrate_disks
= NULL
;
12854 int nmigrate_disks
;
12856 virDomainObjPtr vm
;
12858 virCheckFlags(QEMU_MIGRATION_FLAGS
, NULL
);
12859 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
12862 if (virTypedParamsGetString(params
, nparams
,
12863 VIR_MIGRATE_PARAM_DEST_XML
,
12865 virTypedParamsGetString(params
, nparams
,
12866 VIR_MIGRATE_PARAM_DEST_NAME
,
12870 nmigrate_disks
= virTypedParamsGetStringList(params
, nparams
,
12871 VIR_MIGRATE_PARAM_MIGRATE_DISKS
,
12874 if (nmigrate_disks
< 0)
12877 if (!(vm
= qemuDomObjFromDomain(domain
)))
12880 if (virDomainMigrateBegin3ParamsEnsureACL(domain
->conn
, vm
->def
) < 0) {
12881 virDomainObjEndAPI(&vm
);
12885 ret
= qemuMigrationSrcBegin(domain
->conn
, vm
, xmlin
, dname
,
12886 cookieout
, cookieoutlen
,
12887 nmigrate_disks
, migrate_disks
, flags
);
12890 VIR_FREE(migrate_disks
);
12896 qemuDomainMigratePrepare3(virConnectPtr dconn
,
12897 const char *cookiein
,
12901 const char *uri_in
,
12903 unsigned long flags
,
12905 unsigned long resource ATTRIBUTE_UNUSED
,
12906 const char *dom_xml
)
12908 virQEMUDriverPtr driver
= dconn
->privateData
;
12909 virDomainDefPtr def
= NULL
;
12910 char *origname
= NULL
;
12911 qemuMigrationParamsPtr migParams
= NULL
;
12914 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
12916 if (flags
& VIR_MIGRATE_TUNNELLED
) {
12917 /* this is a logical error; we never should have gotten here with
12918 * VIR_MIGRATE_TUNNELLED set
12920 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
12921 _("Tunnelled migration requested but invalid "
12922 "RPC method called"));
12926 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
12927 QEMU_MIGRATION_DESTINATION
)))
12930 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
12933 if (virDomainMigratePrepare3EnsureACL(dconn
, def
) < 0)
12936 ret
= qemuMigrationDstPrepareDirect(driver
, dconn
,
12937 cookiein
, cookieinlen
,
12938 cookieout
, cookieoutlen
,
12940 &def
, origname
, NULL
, 0, NULL
, 0,
12944 qemuMigrationParamsFree(migParams
);
12945 VIR_FREE(origname
);
12946 virDomainDefFree(def
);
12951 qemuDomainMigratePrepare3Params(virConnectPtr dconn
,
12952 virTypedParameterPtr params
,
12954 const char *cookiein
,
12959 unsigned int flags
)
12961 virQEMUDriverPtr driver
= dconn
->privateData
;
12962 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
12963 virDomainDefPtr def
= NULL
;
12964 const char *dom_xml
= NULL
;
12965 const char *dname
= NULL
;
12966 const char *uri_in
= NULL
;
12967 const char *listenAddress
= cfg
->migrationAddress
;
12969 int nmigrate_disks
;
12970 const char **migrate_disks
= NULL
;
12971 char *origname
= NULL
;
12972 qemuMigrationParamsPtr migParams
= NULL
;
12975 virCheckFlagsGoto(QEMU_MIGRATION_FLAGS
, cleanup
);
12976 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
12979 if (virTypedParamsGetString(params
, nparams
,
12980 VIR_MIGRATE_PARAM_DEST_XML
,
12982 virTypedParamsGetString(params
, nparams
,
12983 VIR_MIGRATE_PARAM_DEST_NAME
,
12985 virTypedParamsGetString(params
, nparams
,
12986 VIR_MIGRATE_PARAM_URI
,
12988 virTypedParamsGetString(params
, nparams
,
12989 VIR_MIGRATE_PARAM_LISTEN_ADDRESS
,
12990 &listenAddress
) < 0 ||
12991 virTypedParamsGetInt(params
, nparams
,
12992 VIR_MIGRATE_PARAM_DISKS_PORT
,
12996 nmigrate_disks
= virTypedParamsGetStringList(params
, nparams
,
12997 VIR_MIGRATE_PARAM_MIGRATE_DISKS
,
13000 if (nmigrate_disks
< 0)
13003 if (!(migParams
= qemuMigrationParamsFromFlags(params
, nparams
, flags
,
13004 QEMU_MIGRATION_DESTINATION
)))
13007 if (flags
& VIR_MIGRATE_TUNNELLED
) {
13008 /* this is a logical error; we never should have gotten here with
13009 * VIR_MIGRATE_TUNNELLED set
13011 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
13012 _("Tunnelled migration requested but invalid "
13013 "RPC method called"));
13017 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
13020 if (virDomainMigratePrepare3ParamsEnsureACL(dconn
, def
) < 0)
13023 ret
= qemuMigrationDstPrepareDirect(driver
, dconn
,
13024 cookiein
, cookieinlen
,
13025 cookieout
, cookieoutlen
,
13027 &def
, origname
, listenAddress
,
13028 nmigrate_disks
, migrate_disks
, nbdPort
,
13032 qemuMigrationParamsFree(migParams
);
13033 VIR_FREE(migrate_disks
);
13034 VIR_FREE(origname
);
13035 virDomainDefFree(def
);
13036 virObjectUnref(cfg
);
13042 qemuDomainMigratePrepareTunnel3(virConnectPtr dconn
,
13044 const char *cookiein
,
13048 unsigned long flags
,
13050 unsigned long resource ATTRIBUTE_UNUSED
,
13051 const char *dom_xml
)
13053 virQEMUDriverPtr driver
= dconn
->privateData
;
13054 virDomainDefPtr def
= NULL
;
13055 char *origname
= NULL
;
13056 qemuMigrationParamsPtr migParams
= NULL
;
13059 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13061 if (!(flags
& VIR_MIGRATE_TUNNELLED
)) {
13062 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
13063 _("PrepareTunnel called but no TUNNELLED flag set"));
13067 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
13068 QEMU_MIGRATION_DESTINATION
)))
13071 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
13074 if (virDomainMigratePrepareTunnel3EnsureACL(dconn
, def
) < 0)
13077 ret
= qemuMigrationDstPrepareTunnel(driver
, dconn
,
13078 cookiein
, cookieinlen
,
13079 cookieout
, cookieoutlen
,
13080 st
, &def
, origname
, migParams
, flags
);
13083 qemuMigrationParamsFree(migParams
);
13084 VIR_FREE(origname
);
13085 virDomainDefFree(def
);
13090 qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn
,
13092 virTypedParameterPtr params
,
13094 const char *cookiein
,
13098 unsigned int flags
)
13100 virQEMUDriverPtr driver
= dconn
->privateData
;
13101 virDomainDefPtr def
= NULL
;
13102 const char *dom_xml
= NULL
;
13103 const char *dname
= NULL
;
13104 char *origname
= NULL
;
13105 qemuMigrationParamsPtr migParams
= NULL
;
13108 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13109 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
13112 if (virTypedParamsGetString(params
, nparams
,
13113 VIR_MIGRATE_PARAM_DEST_XML
,
13115 virTypedParamsGetString(params
, nparams
,
13116 VIR_MIGRATE_PARAM_DEST_NAME
,
13120 if (!(flags
& VIR_MIGRATE_TUNNELLED
)) {
13121 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
13122 _("PrepareTunnel called but no TUNNELLED flag set"));
13126 if (!(migParams
= qemuMigrationParamsFromFlags(params
, nparams
, flags
,
13127 QEMU_MIGRATION_DESTINATION
)))
13130 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
13133 if (virDomainMigratePrepareTunnel3ParamsEnsureACL(dconn
, def
) < 0)
13136 ret
= qemuMigrationDstPrepareTunnel(driver
, dconn
,
13137 cookiein
, cookieinlen
,
13138 cookieout
, cookieoutlen
,
13139 st
, &def
, origname
, migParams
, flags
);
13142 qemuMigrationParamsFree(migParams
);
13143 VIR_FREE(origname
);
13144 virDomainDefFree(def
);
13150 qemuDomainMigratePerform3(virDomainPtr dom
,
13152 const char *cookiein
,
13156 const char *dconnuri
,
13158 unsigned long flags
,
13160 unsigned long resource
)
13162 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
13163 virDomainObjPtr vm
;
13164 qemuMigrationParamsPtr migParams
= NULL
;
13167 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13169 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
13170 QEMU_MIGRATION_SOURCE
)))
13173 if (!(vm
= qemuDomObjFromDomain(dom
)))
13176 if (virDomainMigratePerform3EnsureACL(dom
->conn
, vm
->def
) < 0) {
13177 virDomainObjEndAPI(&vm
);
13181 ret
= qemuMigrationSrcPerform(driver
, dom
->conn
, vm
, xmlin
, NULL
,
13182 dconnuri
, uri
, NULL
, NULL
, 0, NULL
, 0,
13184 cookiein
, cookieinlen
,
13185 cookieout
, cookieoutlen
,
13186 flags
, dname
, resource
, true);
13189 qemuMigrationParamsFree(migParams
);
13194 qemuDomainMigratePerform3Params(virDomainPtr dom
,
13195 const char *dconnuri
,
13196 virTypedParameterPtr params
,
13198 const char *cookiein
,
13202 unsigned int flags
)
13204 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
13205 virDomainObjPtr vm
;
13206 const char *dom_xml
= NULL
;
13207 const char *persist_xml
= NULL
;
13208 const char *dname
= NULL
;
13209 const char *uri
= NULL
;
13210 const char *graphicsuri
= NULL
;
13211 const char *listenAddress
= NULL
;
13212 int nmigrate_disks
;
13213 const char **migrate_disks
= NULL
;
13214 unsigned long long bandwidth
= 0;
13216 qemuMigrationParamsPtr migParams
= NULL
;
13219 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13220 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
13223 if (virTypedParamsGetString(params
, nparams
,
13224 VIR_MIGRATE_PARAM_DEST_XML
,
13226 virTypedParamsGetString(params
, nparams
,
13227 VIR_MIGRATE_PARAM_DEST_NAME
,
13229 virTypedParamsGetString(params
, nparams
,
13230 VIR_MIGRATE_PARAM_URI
,
13232 virTypedParamsGetULLong(params
, nparams
,
13233 VIR_MIGRATE_PARAM_BANDWIDTH
,
13235 virTypedParamsGetString(params
, nparams
,
13236 VIR_MIGRATE_PARAM_GRAPHICS_URI
,
13237 &graphicsuri
) < 0 ||
13238 virTypedParamsGetString(params
, nparams
,
13239 VIR_MIGRATE_PARAM_LISTEN_ADDRESS
,
13240 &listenAddress
) < 0 ||
13241 virTypedParamsGetInt(params
, nparams
,
13242 VIR_MIGRATE_PARAM_DISKS_PORT
,
13244 virTypedParamsGetString(params
, nparams
,
13245 VIR_MIGRATE_PARAM_PERSIST_XML
,
13249 nmigrate_disks
= virTypedParamsGetStringList(params
, nparams
,
13250 VIR_MIGRATE_PARAM_MIGRATE_DISKS
,
13253 if (nmigrate_disks
< 0)
13256 if (!(migParams
= qemuMigrationParamsFromFlags(params
, nparams
, flags
,
13257 QEMU_MIGRATION_SOURCE
)))
13260 if (!(vm
= qemuDomObjFromDomain(dom
)))
13263 if (virDomainMigratePerform3ParamsEnsureACL(dom
->conn
, vm
->def
) < 0) {
13264 virDomainObjEndAPI(&vm
);
13268 ret
= qemuMigrationSrcPerform(driver
, dom
->conn
, vm
, dom_xml
, persist_xml
,
13269 dconnuri
, uri
, graphicsuri
, listenAddress
,
13270 nmigrate_disks
, migrate_disks
, nbdPort
,
13272 cookiein
, cookieinlen
, cookieout
, cookieoutlen
,
13273 flags
, dname
, bandwidth
, true);
13275 qemuMigrationParamsFree(migParams
);
13276 VIR_FREE(migrate_disks
);
13281 static virDomainPtr
13282 qemuDomainMigrateFinish3(virConnectPtr dconn
,
13284 const char *cookiein
,
13288 const char *dconnuri ATTRIBUTE_UNUSED
,
13289 const char *uri ATTRIBUTE_UNUSED
,
13290 unsigned long flags
,
13293 virQEMUDriverPtr driver
= dconn
->privateData
;
13294 virDomainObjPtr vm
;
13296 virCheckFlags(QEMU_MIGRATION_FLAGS
, NULL
);
13299 virReportError(VIR_ERR_NO_DOMAIN
, "%s", _("missing domain name"));
13303 vm
= virDomainObjListFindByName(driver
->domains
, dname
);
13305 virReportError(VIR_ERR_NO_DOMAIN
,
13306 _("no domain with matching name '%s'"), dname
);
13307 qemuMigrationDstErrorReport(driver
, dname
);
13311 if (virDomainMigrateFinish3EnsureACL(dconn
, vm
->def
) < 0) {
13312 virDomainObjEndAPI(&vm
);
13316 return qemuMigrationDstFinish(driver
, dconn
, vm
,
13317 cookiein
, cookieinlen
,
13318 cookieout
, cookieoutlen
,
13319 flags
, cancelled
, true);
13322 static virDomainPtr
13323 qemuDomainMigrateFinish3Params(virConnectPtr dconn
,
13324 virTypedParameterPtr params
,
13326 const char *cookiein
,
13330 unsigned int flags
,
13333 virQEMUDriverPtr driver
= dconn
->privateData
;
13334 virDomainObjPtr vm
;
13335 const char *dname
= NULL
;
13337 virCheckFlags(QEMU_MIGRATION_FLAGS
, NULL
);
13338 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
13341 if (virTypedParamsGetString(params
, nparams
,
13342 VIR_MIGRATE_PARAM_DEST_NAME
,
13347 virReportError(VIR_ERR_NO_DOMAIN
, "%s", _("missing domain name"));
13351 vm
= virDomainObjListFindByName(driver
->domains
, dname
);
13353 virReportError(VIR_ERR_NO_DOMAIN
,
13354 _("no domain with matching name '%s'"), dname
);
13355 qemuMigrationDstErrorReport(driver
, dname
);
13359 if (virDomainMigrateFinish3ParamsEnsureACL(dconn
, vm
->def
) < 0) {
13360 virDomainObjEndAPI(&vm
);
13364 return qemuMigrationDstFinish(driver
, dconn
, vm
,
13365 cookiein
, cookieinlen
,
13366 cookieout
, cookieoutlen
,
13367 flags
, cancelled
, true);
13372 qemuDomainMigrateConfirm3(virDomainPtr domain
,
13373 const char *cookiein
,
13375 unsigned long flags
,
13378 virDomainObjPtr vm
;
13380 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13382 if (!(vm
= qemuDomObjFromDomain(domain
)))
13385 if (virDomainMigrateConfirm3EnsureACL(domain
->conn
, vm
->def
) < 0) {
13386 virDomainObjEndAPI(&vm
);
13390 return qemuMigrationSrcConfirm(domain
->conn
->privateData
, vm
, cookiein
, cookieinlen
,
13395 qemuDomainMigrateConfirm3Params(virDomainPtr domain
,
13396 virTypedParameterPtr params
,
13398 const char *cookiein
,
13400 unsigned int flags
,
13403 virDomainObjPtr vm
;
13405 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13407 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
13410 if (!(vm
= qemuDomObjFromDomain(domain
)))
13413 if (virDomainMigrateConfirm3ParamsEnsureACL(domain
->conn
, vm
->def
) < 0) {
13414 virDomainObjEndAPI(&vm
);
13418 return qemuMigrationSrcConfirm(domain
->conn
->privateData
, vm
, cookiein
, cookieinlen
,
13424 qemuNodeDeviceGetPCIInfo(virNodeDeviceDefPtr def
,
13428 unsigned *function
)
13430 virNodeDevCapsDefPtr cap
;
13435 if (cap
->data
.type
== VIR_NODE_DEV_CAP_PCI_DEV
) {
13436 *domain
= cap
->data
.pci_dev
.domain
;
13437 *bus
= cap
->data
.pci_dev
.bus
;
13438 *slot
= cap
->data
.pci_dev
.slot
;
13439 *function
= cap
->data
.pci_dev
.function
;
13447 virReportError(VIR_ERR_INVALID_ARG
,
13448 _("device %s is not a PCI device"), def
->name
);
13458 qemuNodeDeviceDetachFlags(virNodeDevicePtr dev
,
13459 const char *driverName
,
13460 unsigned int flags
)
13462 virQEMUDriverPtr driver
= dev
->conn
->privateData
;
13463 virPCIDevicePtr pci
= NULL
;
13464 unsigned domain
= 0, bus
= 0, slot
= 0, function
= 0;
13466 virNodeDeviceDefPtr def
= NULL
;
13468 bool legacy
= qemuHostdevHostSupportsPassthroughLegacy();
13469 bool vfio
= qemuHostdevHostSupportsPassthroughVFIO();
13470 virHostdevManagerPtr hostdev_mgr
= driver
->hostdevMgr
;
13472 virCheckFlags(0, -1);
13474 xml
= virNodeDeviceGetXMLDesc(dev
, 0);
13478 def
= virNodeDeviceDefParseString(xml
, EXISTING_DEVICE
, NULL
);
13482 if (virNodeDeviceDetachFlagsEnsureACL(dev
->conn
, def
) < 0)
13485 if (qemuNodeDeviceGetPCIInfo(def
, &domain
, &bus
, &slot
, &function
) < 0)
13488 pci
= virPCIDeviceNew(domain
, bus
, slot
, function
);
13494 driverName
= "vfio";
13495 } else if (legacy
) {
13496 driverName
= "kvm";
13498 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
13499 _("neither VFIO nor KVM device assignment is "
13500 "currently supported on this system"));
13505 if (STREQ(driverName
, "vfio")) {
13507 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
13508 _("VFIO device assignment is currently not "
13509 "supported on this system"));
13512 virPCIDeviceSetStubDriver(pci
, VIR_PCI_STUB_DRIVER_VFIO
);
13513 } else if (STREQ(driverName
, "kvm")) {
13515 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
13516 _("KVM device assignment is currently not "
13517 "supported on this system"));
13520 virPCIDeviceSetStubDriver(pci
, VIR_PCI_STUB_DRIVER_KVM
);
13522 virReportError(VIR_ERR_INVALID_ARG
,
13523 _("unknown driver name '%s'"), driverName
);
13527 ret
= virHostdevPCINodeDeviceDetach(hostdev_mgr
, pci
);
13529 virPCIDeviceFree(pci
);
13530 virNodeDeviceDefFree(def
);
13536 qemuNodeDeviceDettach(virNodeDevicePtr dev
)
13538 return qemuNodeDeviceDetachFlags(dev
, NULL
, 0);
13542 qemuNodeDeviceReAttach(virNodeDevicePtr dev
)
13544 virQEMUDriverPtr driver
= dev
->conn
->privateData
;
13545 virPCIDevicePtr pci
= NULL
;
13546 unsigned domain
= 0, bus
= 0, slot
= 0, function
= 0;
13548 virNodeDeviceDefPtr def
= NULL
;
13550 virHostdevManagerPtr hostdev_mgr
= driver
->hostdevMgr
;
13552 xml
= virNodeDeviceGetXMLDesc(dev
, 0);
13556 def
= virNodeDeviceDefParseString(xml
, EXISTING_DEVICE
, NULL
);
13560 if (virNodeDeviceReAttachEnsureACL(dev
->conn
, def
) < 0)
13563 if (qemuNodeDeviceGetPCIInfo(def
, &domain
, &bus
, &slot
, &function
) < 0)
13566 pci
= virPCIDeviceNew(domain
, bus
, slot
, function
);
13570 ret
= virHostdevPCINodeDeviceReAttach(hostdev_mgr
, pci
);
13572 virPCIDeviceFree(pci
);
13574 virNodeDeviceDefFree(def
);
13580 qemuNodeDeviceReset(virNodeDevicePtr dev
)
13582 virQEMUDriverPtr driver
= dev
->conn
->privateData
;
13583 virPCIDevicePtr pci
;
13584 unsigned domain
= 0, bus
= 0, slot
= 0, function
= 0;
13586 virNodeDeviceDefPtr def
= NULL
;
13588 virHostdevManagerPtr hostdev_mgr
= driver
->hostdevMgr
;
13590 xml
= virNodeDeviceGetXMLDesc(dev
, 0);
13594 def
= virNodeDeviceDefParseString(xml
, EXISTING_DEVICE
, NULL
);
13598 if (virNodeDeviceResetEnsureACL(dev
->conn
, def
) < 0)
13601 if (qemuNodeDeviceGetPCIInfo(def
, &domain
, &bus
, &slot
, &function
) < 0)
13604 pci
= virPCIDeviceNew(domain
, bus
, slot
, function
);
13608 ret
= virHostdevPCINodeDeviceReset(hostdev_mgr
, pci
);
13610 virPCIDeviceFree(pci
);
13612 virNodeDeviceDefFree(def
);
13618 qemuConnectCompareCPU(virConnectPtr conn
,
13619 const char *xmlDesc
,
13620 unsigned int flags
)
13622 virQEMUDriverPtr driver
= conn
->privateData
;
13623 int ret
= VIR_CPU_COMPARE_ERROR
;
13624 virCapsPtr caps
= NULL
;
13625 bool failIncompatible
;
13627 virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE
,
13628 VIR_CPU_COMPARE_ERROR
);
13630 if (virConnectCompareCPUEnsureACL(conn
) < 0)
13633 failIncompatible
= !!(flags
& VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE
);
13635 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
13638 ret
= virCPUCompareXML(caps
->host
.arch
, caps
->host
.cpu
,
13639 xmlDesc
, failIncompatible
);
13642 virObjectUnref(caps
);
13648 qemuConnectCompareHypervisorCPU(virConnectPtr conn
,
13649 const char *emulator
,
13650 const char *archStr
,
13651 const char *machine
,
13652 const char *virttypeStr
,
13653 const char *xmlCPU
,
13654 unsigned int flags
)
13656 int ret
= VIR_CPU_COMPARE_ERROR
;
13657 virQEMUDriverPtr driver
= conn
->privateData
;
13658 virQEMUCapsPtr qemuCaps
= NULL
;
13659 bool failIncompatible
;
13660 virCPUDefPtr hvCPU
;
13662 virDomainVirtType virttype
;
13664 virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE
,
13665 VIR_CPU_COMPARE_ERROR
);
13667 if (virConnectCompareHypervisorCPUEnsureACL(conn
) < 0)
13670 failIncompatible
= !!(flags
& VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE
);
13672 qemuCaps
= virQEMUCapsCacheLookupDefault(driver
->qemuCapsCache
,
13677 &arch
, &virttype
, NULL
);
13681 hvCPU
= virQEMUCapsGetHostModel(qemuCaps
, virttype
,
13682 VIR_QEMU_CAPS_HOST_CPU_REPORTED
);
13684 if (!hvCPU
|| hvCPU
->fallback
!= VIR_CPU_FALLBACK_FORBID
) {
13685 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
13686 _("QEMU '%s' does not support reporting CPU model for "
13688 virQEMUCapsGetBinary(qemuCaps
),
13689 virDomainVirtTypeToString(virttype
));
13693 if (ARCH_IS_X86(arch
)) {
13694 ret
= virCPUCompareXML(arch
, hvCPU
, xmlCPU
, failIncompatible
);
13696 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
13697 _("comparing with the hypervisor CPU is not supported "
13698 "for arch %s"), virArchToString(arch
));
13702 virObjectUnref(qemuCaps
);
13708 qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED
,
13709 const char **xmlCPUs
,
13710 unsigned int ncpus
,
13711 unsigned int flags
)
13713 virCPUDefPtr
*cpus
= NULL
;
13714 virCPUDefPtr baseline
= NULL
;
13715 virCPUDefPtr cpu
= NULL
;
13716 char *cpustr
= NULL
;
13718 virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES
|
13719 VIR_CONNECT_BASELINE_CPU_MIGRATABLE
, NULL
);
13721 if (virConnectBaselineCPUEnsureACL(conn
) < 0)
13724 if (!(cpus
= virCPUDefListParse(xmlCPUs
, ncpus
, VIR_CPU_TYPE_HOST
)))
13727 if (!(baseline
= virCPUBaseline(VIR_ARCH_NONE
, cpus
, ncpus
, NULL
, NULL
,
13728 !!(flags
& VIR_CONNECT_BASELINE_CPU_MIGRATABLE
))))
13731 if (!(cpu
= virCPUDefCopyWithoutModel(baseline
)))
13734 if (virCPUDefCopyModelFilter(cpu
, baseline
, false,
13735 virQEMUCapsCPUFilterFeatures
,
13736 &cpus
[0]->arch
) < 0)
13739 if ((flags
& VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES
) &&
13740 virCPUExpandFeatures(cpus
[0]->arch
, cpu
) < 0)
13743 cpustr
= virCPUDefFormat(cpu
, NULL
);
13746 virCPUDefListFree(cpus
);
13747 virCPUDefFree(baseline
);
13748 virCPUDefFree(cpu
);
13755 qemuConnectBaselineHypervisorCPU(virConnectPtr conn
,
13756 const char *emulator
,
13757 const char *archStr
,
13758 const char *machine
,
13759 const char *virttypeStr
,
13760 const char **xmlCPUs
,
13761 unsigned int ncpus
,
13762 unsigned int flags
)
13764 virQEMUDriverPtr driver
= conn
->privateData
;
13765 virCPUDefPtr
*cpus
= NULL
;
13766 virQEMUCapsPtr qemuCaps
= NULL
;
13768 virDomainVirtType virttype
;
13769 virDomainCapsCPUModelsPtr cpuModels
;
13771 virCPUDefPtr cpu
= NULL
;
13772 char *cpustr
= NULL
;
13773 char **features
= NULL
;
13775 virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES
|
13776 VIR_CONNECT_BASELINE_CPU_MIGRATABLE
, NULL
);
13778 if (virConnectBaselineHypervisorCPUEnsureACL(conn
) < 0)
13781 migratable
= !!(flags
& VIR_CONNECT_BASELINE_CPU_MIGRATABLE
);
13783 if (!(cpus
= virCPUDefListParse(xmlCPUs
, ncpus
, VIR_CPU_TYPE_AUTO
)))
13786 qemuCaps
= virQEMUCapsCacheLookupDefault(driver
->qemuCapsCache
,
13791 &arch
, &virttype
, NULL
);
13795 if (!(cpuModels
= virQEMUCapsGetCPUDefinitions(qemuCaps
, virttype
)) ||
13796 cpuModels
->nmodels
== 0) {
13797 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
13798 _("QEMU '%s' does not support any CPU models for "
13800 virQEMUCapsGetBinary(qemuCaps
),
13801 virDomainVirtTypeToString(virttype
));
13805 if (ARCH_IS_X86(arch
)) {
13806 int rc
= virQEMUCapsGetCPUFeatures(qemuCaps
, virttype
,
13807 migratable
, &features
);
13810 if (features
&& rc
== 0) {
13811 /* We got only migratable features from QEMU if we asked for them,
13812 * no further filtering in virCPUBaseline is desired. */
13813 migratable
= false;
13816 if (!(cpu
= virCPUBaseline(arch
, cpus
, ncpus
, cpuModels
,
13817 (const char **)features
, migratable
)))
13820 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
13821 _("computing baseline hypervisor CPU is not supported "
13822 "for arch %s"), virArchToString(arch
));
13826 cpu
->fallback
= VIR_CPU_FALLBACK_FORBID
;
13828 if ((flags
& VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES
) &&
13829 virCPUExpandFeatures(arch
, cpu
) < 0)
13832 cpustr
= virCPUDefFormat(cpu
, NULL
);
13835 virCPUDefListFree(cpus
);
13836 virCPUDefFree(cpu
);
13837 virObjectUnref(qemuCaps
);
13838 virStringListFree(features
);
13845 qemuDomainGetJobInfoMigrationStats(virQEMUDriverPtr driver
,
13846 virDomainObjPtr vm
,
13847 qemuDomainJobInfoPtr jobInfo
)
13849 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
13850 bool events
= virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_MIGRATION_EVENT
);
13852 if (jobInfo
->status
== QEMU_DOMAIN_JOB_STATUS_ACTIVE
||
13853 jobInfo
->status
== QEMU_DOMAIN_JOB_STATUS_MIGRATING
||
13854 jobInfo
->status
== QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED
||
13855 jobInfo
->status
== QEMU_DOMAIN_JOB_STATUS_POSTCOPY
) {
13857 jobInfo
->status
!= QEMU_DOMAIN_JOB_STATUS_ACTIVE
&&
13858 qemuMigrationAnyFetchStats(driver
, vm
, QEMU_ASYNC_JOB_NONE
,
13859 jobInfo
, NULL
) < 0)
13862 if (jobInfo
->status
== QEMU_DOMAIN_JOB_STATUS_ACTIVE
&&
13863 jobInfo
->statsType
== QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION
&&
13864 qemuMigrationSrcFetchMirrorStats(driver
, vm
, QEMU_ASYNC_JOB_NONE
,
13868 if (qemuDomainJobInfoUpdateTime(jobInfo
) < 0)
13877 qemuDomainGetJobInfoDumpStats(virQEMUDriverPtr driver
,
13878 virDomainObjPtr vm
,
13879 qemuDomainJobInfoPtr jobInfo
)
13881 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
13882 qemuMonitorDumpStats stats
= { 0 };
13885 if (qemuDomainObjEnterMonitorAsync(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
13888 rc
= qemuMonitorQueryDump(priv
->mon
, &stats
);
13890 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || rc
< 0)
13893 jobInfo
->stats
.dump
= stats
;
13895 if (qemuDomainJobInfoUpdateTime(jobInfo
) < 0)
13898 switch (jobInfo
->stats
.dump
.status
) {
13899 case QEMU_MONITOR_DUMP_STATUS_NONE
:
13900 case QEMU_MONITOR_DUMP_STATUS_FAILED
:
13901 case QEMU_MONITOR_DUMP_STATUS_LAST
:
13902 virReportError(VIR_ERR_OPERATION_FAILED
,
13903 _("dump query failed, status=%d"),
13904 jobInfo
->stats
.dump
.status
);
13908 case QEMU_MONITOR_DUMP_STATUS_ACTIVE
:
13909 jobInfo
->status
= QEMU_DOMAIN_JOB_STATUS_ACTIVE
;
13910 VIR_DEBUG("dump active, bytes written='%llu' remaining='%llu'",
13911 jobInfo
->stats
.dump
.completed
,
13912 jobInfo
->stats
.dump
.total
-
13913 jobInfo
->stats
.dump
.completed
);
13916 case QEMU_MONITOR_DUMP_STATUS_COMPLETED
:
13917 jobInfo
->status
= QEMU_DOMAIN_JOB_STATUS_COMPLETED
;
13918 VIR_DEBUG("dump completed, bytes written='%llu'",
13919 jobInfo
->stats
.dump
.completed
);
13928 qemuDomainGetJobStatsInternal(virQEMUDriverPtr driver
,
13929 virDomainObjPtr vm
,
13931 qemuDomainJobInfoPtr jobInfo
)
13933 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
13937 if (priv
->job
.completed
&& !priv
->job
.current
)
13938 *jobInfo
= *priv
->job
.completed
;
13940 jobInfo
->status
= QEMU_DOMAIN_JOB_STATUS_NONE
;
13945 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_IN
) {
13946 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
13947 _("migration statistics are available only on "
13948 "the source host"));
13952 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
13955 if (virDomainObjCheckActive(vm
) < 0)
13958 if (!priv
->job
.current
) {
13959 jobInfo
->status
= QEMU_DOMAIN_JOB_STATUS_NONE
;
13963 *jobInfo
= *priv
->job
.current
;
13965 switch (jobInfo
->statsType
) {
13966 case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION
:
13967 case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP
:
13968 if (qemuDomainGetJobInfoMigrationStats(driver
, vm
, jobInfo
) < 0)
13972 case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP
:
13973 if (qemuDomainGetJobInfoDumpStats(driver
, vm
, jobInfo
) < 0)
13977 case QEMU_DOMAIN_JOB_STATS_TYPE_NONE
:
13984 qemuDomainObjEndJob(driver
, vm
);
13990 qemuDomainGetJobInfo(virDomainPtr dom
,
13991 virDomainJobInfoPtr info
)
13993 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
13994 qemuDomainJobInfo jobInfo
;
13995 virDomainObjPtr vm
;
13998 if (!(vm
= qemuDomObjFromDomain(dom
)))
14001 if (virDomainGetJobInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
14004 if (qemuDomainGetJobStatsInternal(driver
, vm
, false, &jobInfo
) < 0)
14007 if (jobInfo
.status
== QEMU_DOMAIN_JOB_STATUS_NONE
) {
14008 memset(info
, 0, sizeof(*info
));
14009 info
->type
= VIR_DOMAIN_JOB_NONE
;
14014 ret
= qemuDomainJobInfoToInfo(&jobInfo
, info
);
14017 virDomainObjEndAPI(&vm
);
14023 qemuDomainGetJobStats(virDomainPtr dom
,
14025 virTypedParameterPtr
*params
,
14027 unsigned int flags
)
14029 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14030 virDomainObjPtr vm
;
14031 qemuDomainObjPrivatePtr priv
;
14032 qemuDomainJobInfo jobInfo
;
14033 bool completed
= !!(flags
& VIR_DOMAIN_JOB_STATS_COMPLETED
);
14036 virCheckFlags(VIR_DOMAIN_JOB_STATS_COMPLETED
, -1);
14038 if (!(vm
= qemuDomObjFromDomain(dom
)))
14041 if (virDomainGetJobStatsEnsureACL(dom
->conn
, vm
->def
) < 0)
14044 priv
= vm
->privateData
;
14045 if (qemuDomainGetJobStatsInternal(driver
, vm
, completed
, &jobInfo
) < 0)
14048 if (jobInfo
.status
== QEMU_DOMAIN_JOB_STATUS_NONE
) {
14049 *type
= VIR_DOMAIN_JOB_NONE
;
14056 ret
= qemuDomainJobInfoToParams(&jobInfo
, type
, params
, nparams
);
14058 if (completed
&& ret
== 0)
14059 VIR_FREE(priv
->job
.completed
);
14062 virDomainObjEndAPI(&vm
);
14067 static int qemuDomainAbortJob(virDomainPtr dom
)
14069 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14070 virDomainObjPtr vm
;
14072 qemuDomainObjPrivatePtr priv
;
14075 if (!(vm
= qemuDomObjFromDomain(dom
)))
14078 if (virDomainAbortJobEnsureACL(dom
->conn
, vm
->def
) < 0)
14081 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_ABORT
) < 0)
14084 if (virDomainObjCheckActive(vm
) < 0)
14087 priv
= vm
->privateData
;
14089 if (!priv
->job
.asyncJob
) {
14090 virReportError(VIR_ERR_OPERATION_INVALID
,
14091 "%s", _("no job is active on the domain"));
14095 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_IN
) {
14096 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14097 _("cannot abort incoming migration;"
14098 " use virDomainDestroy instead"));
14102 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_DUMP
&&
14103 priv
->job
.apiFlags
& VIR_DUMP_MEMORY_ONLY
) {
14104 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14105 _("cannot abort memory-only dump"));
14109 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_OUT
&&
14110 (priv
->job
.current
->status
== QEMU_DOMAIN_JOB_STATUS_POSTCOPY
||
14111 (virDomainObjGetState(vm
, &reason
) == VIR_DOMAIN_PAUSED
&&
14112 reason
== VIR_DOMAIN_PAUSED_POSTCOPY
))) {
14113 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14114 _("cannot abort migration in post-copy mode"));
14118 VIR_DEBUG("Cancelling job at client request");
14119 qemuDomainObjAbortAsyncJob(vm
);
14120 qemuDomainObjEnterMonitor(driver
, vm
);
14121 ret
= qemuMonitorMigrateCancel(priv
->mon
);
14122 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14126 qemuDomainObjEndJob(driver
, vm
);
14129 virDomainObjEndAPI(&vm
);
14135 qemuDomainMigrateSetMaxDowntime(virDomainPtr dom
,
14136 unsigned long long downtime
,
14137 unsigned int flags
)
14139 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14140 virDomainObjPtr vm
;
14141 qemuDomainObjPrivatePtr priv
;
14144 virCheckFlags(0, -1);
14146 if (!(vm
= qemuDomObjFromDomain(dom
)))
14149 if (virDomainMigrateSetMaxDowntimeEnsureACL(dom
->conn
, vm
->def
) < 0)
14152 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MIGRATION_OP
) < 0)
14155 if (virDomainObjCheckActive(vm
) < 0)
14158 priv
= vm
->privateData
;
14160 VIR_DEBUG("Setting migration downtime to %llums", downtime
);
14161 qemuDomainObjEnterMonitor(driver
, vm
);
14162 ret
= qemuMonitorSetMigrationDowntime(priv
->mon
, downtime
);
14163 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14167 qemuDomainObjEndJob(driver
, vm
);
14170 virDomainObjEndAPI(&vm
);
14176 qemuDomainMigrateGetMaxDowntime(virDomainPtr dom
,
14177 unsigned long long *downtime
,
14178 unsigned int flags
)
14180 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14181 virDomainObjPtr vm
;
14182 qemuMigrationParamsPtr migParams
= NULL
;
14186 virCheckFlags(0, -1);
14188 if (!(vm
= qemuDomObjFromDomain(dom
)))
14191 if (virDomainMigrateGetMaxDowntimeEnsureACL(dom
->conn
, vm
->def
) < 0)
14194 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
14197 if (virDomainObjCheckActive(vm
) < 0)
14200 if (qemuMigrationParamsFetch(driver
, vm
, QEMU_ASYNC_JOB_NONE
,
14204 if ((rc
= qemuMigrationParamsGetULL(migParams
,
14205 QEMU_MIGRATION_PARAM_DOWNTIME_LIMIT
,
14211 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14212 _("Querying migration downtime is not supported by "
14220 qemuDomainObjEndJob(driver
, vm
);
14223 qemuMigrationParamsFree(migParams
);
14224 virDomainObjEndAPI(&vm
);
14230 qemuDomainMigrateGetCompressionCache(virDomainPtr dom
,
14231 unsigned long long *cacheSize
,
14232 unsigned int flags
)
14234 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14235 virDomainObjPtr vm
;
14236 qemuDomainObjPrivatePtr priv
;
14239 virCheckFlags(0, -1);
14241 if (!(vm
= qemuDomObjFromDomain(dom
)))
14244 if (virDomainMigrateGetCompressionCacheEnsureACL(dom
->conn
, vm
->def
) < 0)
14247 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
14250 if (virDomainObjCheckActive(vm
) < 0)
14253 priv
= vm
->privateData
;
14255 if (!qemuMigrationCapsGet(vm
, QEMU_MIGRATION_CAP_XBZRLE
)) {
14256 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
14257 _("Compressed migration is not supported by "
14262 qemuDomainObjEnterMonitor(driver
, vm
);
14264 ret
= qemuMonitorGetMigrationCacheSize(priv
->mon
, cacheSize
);
14266 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14270 qemuDomainObjEndJob(driver
, vm
);
14273 virDomainObjEndAPI(&vm
);
14278 qemuDomainMigrateSetCompressionCache(virDomainPtr dom
,
14279 unsigned long long cacheSize
,
14280 unsigned int flags
)
14282 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14283 virDomainObjPtr vm
;
14284 qemuDomainObjPrivatePtr priv
;
14287 virCheckFlags(0, -1);
14289 if (!(vm
= qemuDomObjFromDomain(dom
)))
14292 if (virDomainMigrateSetCompressionCacheEnsureACL(dom
->conn
, vm
->def
) < 0)
14295 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MIGRATION_OP
) < 0)
14298 if (virDomainObjCheckActive(vm
) < 0)
14301 priv
= vm
->privateData
;
14303 if (!qemuMigrationCapsGet(vm
, QEMU_MIGRATION_CAP_XBZRLE
)) {
14304 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
14305 _("Compressed migration is not supported by "
14310 qemuDomainObjEnterMonitor(driver
, vm
);
14312 VIR_DEBUG("Setting compression cache to %llu B", cacheSize
);
14313 ret
= qemuMonitorSetMigrationCacheSize(priv
->mon
, cacheSize
);
14315 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14319 qemuDomainObjEndJob(driver
, vm
);
14322 virDomainObjEndAPI(&vm
);
14327 qemuDomainMigrateSetMaxSpeed(virDomainPtr dom
,
14328 unsigned long bandwidth
,
14329 unsigned int flags
)
14331 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14332 virDomainObjPtr vm
;
14333 qemuDomainObjPrivatePtr priv
;
14334 bool postcopy
= !!(flags
& VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY
);
14335 VIR_AUTOPTR(qemuMigrationParams
) migParams
= NULL
;
14336 unsigned long long max
;
14339 virCheckFlags(VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY
, -1);
14341 if (!(vm
= qemuDomObjFromDomain(dom
)))
14344 priv
= vm
->privateData
;
14346 if (virDomainMigrateSetMaxSpeedEnsureACL(dom
->conn
, vm
->def
) < 0)
14350 max
= ULLONG_MAX
/ 1024 / 1024;
14352 max
= QEMU_DOMAIN_MIG_BANDWIDTH_MAX
;
14354 if (bandwidth
> max
) {
14355 virReportError(VIR_ERR_OVERFLOW
,
14356 _("bandwidth must be less than %llu"), max
+ 1);
14360 if (!postcopy
&& !virDomainObjIsActive(vm
)) {
14361 priv
->migMaxBandwidth
= bandwidth
;
14366 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MIGRATION_OP
) < 0)
14369 if (virDomainObjCheckActive(vm
) < 0)
14372 VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth
);
14375 if (!(migParams
= qemuMigrationParamsNew()))
14378 if (qemuMigrationParamsSetULL(migParams
,
14379 QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH
,
14380 bandwidth
* 1024 * 1024) < 0)
14383 if (qemuMigrationParamsApply(driver
, vm
, QEMU_ASYNC_JOB_NONE
,
14389 qemuDomainObjEnterMonitor(driver
, vm
);
14390 rc
= qemuMonitorSetMigrationSpeed(priv
->mon
, bandwidth
);
14391 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || rc
< 0)
14394 priv
->migMaxBandwidth
= bandwidth
;
14400 qemuDomainObjEndJob(driver
, vm
);
14403 virDomainObjEndAPI(&vm
);
14409 qemuDomainMigrationGetPostcopyBandwidth(virQEMUDriverPtr driver
,
14410 virDomainObjPtr vm
,
14411 unsigned long *bandwidth
)
14413 VIR_AUTOPTR(qemuMigrationParams
) migParams
= NULL
;
14414 unsigned long long bw
;
14418 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
14421 if (virDomainObjCheckActive(vm
) < 0)
14424 if (qemuMigrationParamsFetch(driver
, vm
, QEMU_ASYNC_JOB_NONE
,
14428 if ((rc
= qemuMigrationParamsGetULL(migParams
,
14429 QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH
,
14434 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14435 _("querying maximum post-copy migration speed is "
14436 "not supported by QEMU binary"));
14440 /* QEMU reports B/s while we use MiB/s */
14443 if (bw
> ULONG_MAX
) {
14444 virReportError(VIR_ERR_OVERFLOW
,
14445 _("bandwidth %llu is greater than %lu which is the "
14446 "maximum value supported by this API"),
14455 qemuDomainObjEndJob(driver
, vm
);
14461 qemuDomainMigrateGetMaxSpeed(virDomainPtr dom
,
14462 unsigned long *bandwidth
,
14463 unsigned int flags
)
14465 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14466 virDomainObjPtr vm
;
14467 qemuDomainObjPrivatePtr priv
;
14468 bool postcopy
= !!(flags
& VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY
);
14471 virCheckFlags(VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY
, -1);
14473 if (!(vm
= qemuDomObjFromDomain(dom
)))
14476 priv
= vm
->privateData
;
14478 if (virDomainMigrateGetMaxSpeedEnsureACL(dom
->conn
, vm
->def
) < 0)
14482 if (qemuDomainMigrationGetPostcopyBandwidth(driver
, vm
, bandwidth
) < 0)
14485 *bandwidth
= priv
->migMaxBandwidth
;
14491 virDomainObjEndAPI(&vm
);
14497 qemuDomainMigrateStartPostCopy(virDomainPtr dom
,
14498 unsigned int flags
)
14500 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14501 virDomainObjPtr vm
;
14502 qemuDomainObjPrivatePtr priv
;
14505 virCheckFlags(0, -1);
14507 if (!(vm
= qemuDomObjFromDomain(dom
)))
14510 if (virDomainMigrateStartPostCopyEnsureACL(dom
->conn
, vm
->def
) < 0)
14513 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MIGRATION_OP
) < 0)
14516 if (virDomainObjCheckActive(vm
) < 0)
14519 priv
= vm
->privateData
;
14521 if (priv
->job
.asyncJob
!= QEMU_ASYNC_JOB_MIGRATION_OUT
) {
14522 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14523 _("post-copy can only be started while "
14524 "outgoing migration is in progress"));
14528 if (!(priv
->job
.apiFlags
& VIR_MIGRATE_POSTCOPY
)) {
14529 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14530 _("switching to post-copy requires migration to be "
14531 "started with VIR_MIGRATE_POSTCOPY flag"));
14535 VIR_DEBUG("Starting post-copy");
14536 qemuDomainObjEnterMonitor(driver
, vm
);
14537 ret
= qemuMonitorMigrateStartPostCopy(priv
->mon
);
14538 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14542 qemuDomainObjEndJob(driver
, vm
);
14545 virDomainObjEndAPI(&vm
);
14550 /* Return -1 if request is not sent to agent due to misconfig, -2 if request
14551 * is sent but failed, and number of frozen filesystems on success. If -2 is
14552 * returned, FSThaw should be called revert the quiesced status. */
14554 qemuDomainSnapshotFSFreeze(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
14555 virDomainObjPtr vm
,
14556 const char **mountpoints
,
14557 unsigned int nmountpoints
)
14559 qemuAgentPtr agent
;
14562 if (!qemuDomainAgentAvailable(vm
, true))
14565 agent
= qemuDomainObjEnterAgent(vm
);
14566 frozen
= qemuAgentFSFreeze(agent
, mountpoints
, nmountpoints
);
14567 qemuDomainObjExitAgent(vm
, agent
);
14568 return frozen
< 0 ? -2 : frozen
;
14572 /* Return -1 on error, otherwise number of thawed filesystems. */
14574 qemuDomainSnapshotFSThaw(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
14575 virDomainObjPtr vm
,
14578 qemuAgentPtr agent
;
14580 virErrorPtr err
= NULL
;
14582 if (!qemuDomainAgentAvailable(vm
, report
))
14585 agent
= qemuDomainObjEnterAgent(vm
);
14587 err
= virSaveLastError();
14588 thawed
= qemuAgentFSThaw(agent
);
14591 qemuDomainObjExitAgent(vm
, agent
);
14599 /* The domain is expected to be locked and inactive. */
14601 qemuDomainSnapshotCreateInactiveInternal(virQEMUDriverPtr driver
,
14602 virDomainObjPtr vm
,
14603 virDomainMomentObjPtr snap
)
14605 return qemuDomainSnapshotForEachQcow2(driver
, vm
, snap
, "-c", false);
14609 /* The domain is expected to be locked and inactive. */
14611 qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver
,
14612 virDomainObjPtr vm
,
14613 virDomainMomentObjPtr snap
,
14617 virDomainSnapshotDiskDefPtr snapdisk
;
14618 virDomainDiskDefPtr defdisk
;
14619 virCommandPtr cmd
= NULL
;
14620 const char *qemuImgPath
;
14621 virBitmapPtr created
= NULL
;
14622 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
14624 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
14625 virDomainSnapshotDefPtr snapdef
= virDomainSnapshotObjGetDef(snap
);
14627 if (!(qemuImgPath
= qemuFindQemuImgBinary(driver
)))
14630 if (!(created
= virBitmapNew(snapdef
->ndisks
)))
14633 /* If reuse is true, then qemuDomainSnapshotPrepare already
14634 * ensured that the new files exist, and it was up to the user to
14635 * create them correctly. */
14636 for (i
= 0; i
< snapdef
->ndisks
&& !reuse
; i
++) {
14637 snapdisk
= &(snapdef
->disks
[i
]);
14638 defdisk
= snapdef
->common
.dom
->disks
[snapdisk
->idx
];
14639 if (snapdisk
->snapshot
!= VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
)
14642 if (!snapdisk
->src
->format
)
14643 snapdisk
->src
->format
= VIR_STORAGE_FILE_QCOW2
;
14645 /* creates cmd line args: qemu-img create -f qcow2 -o */
14646 if (!(cmd
= virCommandNewArgList(qemuImgPath
,
14649 virStorageFileFormatTypeToString(snapdisk
->src
->format
),
14654 /* adds cmd line arg: backing_fmt=format,backing_file=/path/to/backing/file */
14655 virBufferAsprintf(&buf
, "backing_fmt=%s,backing_file=",
14656 virStorageFileFormatTypeToString(defdisk
->src
->format
));
14657 virQEMUBuildBufferEscapeComma(&buf
, defdisk
->src
->path
);
14658 virCommandAddArgBuffer(cmd
, &buf
);
14660 /* adds cmd line args: /path/to/target/file */
14661 virQEMUBuildBufferEscapeComma(&buf
, snapdisk
->src
->path
);
14662 virCommandAddArgBuffer(cmd
, &buf
);
14664 /* If the target does not exist, we're going to create it possibly */
14665 if (!virFileExists(snapdisk
->src
->path
))
14666 ignore_value(virBitmapSetBit(created
, i
));
14668 if (virCommandRun(cmd
, NULL
) < 0)
14671 virCommandFree(cmd
);
14675 /* update disk definitions */
14676 for (i
= 0; i
< snapdef
->ndisks
; i
++) {
14677 snapdisk
= &(snapdef
->disks
[i
]);
14678 defdisk
= vm
->def
->disks
[snapdisk
->idx
];
14680 if (snapdisk
->snapshot
== VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
) {
14681 VIR_FREE(defdisk
->src
->path
);
14682 if (VIR_STRDUP(defdisk
->src
->path
, snapdisk
->src
->path
) < 0) {
14683 /* we cannot rollback here in a sane way */
14686 defdisk
->src
->format
= snapdisk
->src
->format
;
14688 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, vm
->def
) < 0)
14696 virBufferFreeAndReset(&buf
);
14697 virCommandFree(cmd
);
14699 /* unlink images if creation has failed */
14700 if (ret
< 0 && created
) {
14702 while ((bit
= virBitmapNextSetBit(created
, bit
)) >= 0) {
14703 snapdisk
= &(snapdef
->disks
[bit
]);
14704 if (unlink(snapdisk
->src
->path
) < 0)
14705 VIR_WARN("Failed to remove snapshot image '%s'",
14706 snapdisk
->src
->path
);
14709 virBitmapFree(created
);
14710 virObjectUnref(cfg
);
14716 /* The domain is expected to be locked and active. */
14718 qemuDomainSnapshotCreateActiveInternal(virQEMUDriverPtr driver
,
14719 virDomainObjPtr vm
,
14720 virDomainMomentObjPtr snap
,
14721 unsigned int flags
)
14723 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
14724 virObjectEventPtr event
= NULL
;
14725 bool resume
= false;
14726 virDomainSnapshotDefPtr snapdef
= virDomainSnapshotObjGetDef(snap
);
14729 if (!qemuMigrationSrcIsAllowed(driver
, vm
, false, 0))
14732 if (virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
) {
14733 /* savevm monitor command pauses the domain emitting an event which
14734 * confuses libvirt since it's not notified when qemu resumes the
14735 * domain. Thus we stop and start CPUs ourselves.
14737 if (qemuProcessStopCPUs(driver
, vm
, VIR_DOMAIN_PAUSED_SAVE
,
14738 QEMU_ASYNC_JOB_SNAPSHOT
) < 0)
14742 if (!virDomainObjIsActive(vm
)) {
14743 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
14744 _("guest unexpectedly quit"));
14749 if (qemuDomainObjEnterMonitorAsync(driver
, vm
,
14750 QEMU_ASYNC_JOB_SNAPSHOT
) < 0) {
14755 ret
= qemuMonitorCreateSnapshot(priv
->mon
, snap
->def
->name
);
14756 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14761 if (!(snapdef
->cookie
= (virObjectPtr
) qemuDomainSaveCookieNew(vm
)))
14764 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_HALT
) {
14765 event
= virDomainEventLifecycleNewFromObj(vm
, VIR_DOMAIN_EVENT_STOPPED
,
14766 VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT
);
14767 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT
,
14768 QEMU_ASYNC_JOB_SNAPSHOT
, 0);
14769 virDomainAuditStop(vm
, "from-snapshot");
14774 if (resume
&& virDomainObjIsActive(vm
) &&
14775 qemuProcessStartCPUs(driver
, vm
,
14776 VIR_DOMAIN_RUNNING_UNPAUSED
,
14777 QEMU_ASYNC_JOB_SNAPSHOT
) < 0) {
14778 event
= virDomainEventLifecycleNewFromObj(vm
,
14779 VIR_DOMAIN_EVENT_SUSPENDED
,
14780 VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR
);
14781 if (virGetLastErrorCode() == VIR_ERR_OK
) {
14782 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
14783 _("resuming after snapshot failed"));
14787 virObjectEventStateQueue(driver
->domainEventState
, event
);
14794 qemuDomainSnapshotPrepareDiskShared(virDomainSnapshotDiskDefPtr snapdisk
,
14795 virDomainDiskDefPtr domdisk
)
14797 if (!domdisk
->src
->shared
|| domdisk
->src
->readonly
)
14800 if (!qemuBlockStorageSourceSupportsConcurrentAccess(snapdisk
->src
)) {
14801 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
14802 _("shared access for disk '%s' requires use of "
14803 "supported storage format"), domdisk
->dst
);
14812 qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdisk
,
14813 virDomainDiskDefPtr domdisk
)
14815 int domDiskType
= virStorageSourceGetActualType(domdisk
->src
);
14816 int snapDiskType
= virStorageSourceGetActualType(snapdisk
->src
);
14818 switch ((virStorageType
)domDiskType
) {
14819 case VIR_STORAGE_TYPE_BLOCK
:
14820 case VIR_STORAGE_TYPE_FILE
:
14823 case VIR_STORAGE_TYPE_NETWORK
:
14824 switch ((virStorageNetProtocol
) domdisk
->src
->protocol
) {
14825 case VIR_STORAGE_NET_PROTOCOL_NONE
:
14826 case VIR_STORAGE_NET_PROTOCOL_NBD
:
14827 case VIR_STORAGE_NET_PROTOCOL_RBD
:
14828 case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG
:
14829 case VIR_STORAGE_NET_PROTOCOL_GLUSTER
:
14830 case VIR_STORAGE_NET_PROTOCOL_ISCSI
:
14831 case VIR_STORAGE_NET_PROTOCOL_HTTP
:
14832 case VIR_STORAGE_NET_PROTOCOL_HTTPS
:
14833 case VIR_STORAGE_NET_PROTOCOL_FTP
:
14834 case VIR_STORAGE_NET_PROTOCOL_FTPS
:
14835 case VIR_STORAGE_NET_PROTOCOL_TFTP
:
14836 case VIR_STORAGE_NET_PROTOCOL_SSH
:
14837 case VIR_STORAGE_NET_PROTOCOL_VXHS
:
14838 case VIR_STORAGE_NET_PROTOCOL_LAST
:
14839 virReportError(VIR_ERR_INTERNAL_ERROR
,
14840 _("external inactive snapshots are not supported on "
14841 "'network' disks using '%s' protocol"),
14842 virStorageNetProtocolTypeToString(domdisk
->src
->protocol
));
14847 case VIR_STORAGE_TYPE_DIR
:
14848 case VIR_STORAGE_TYPE_VOLUME
:
14849 case VIR_STORAGE_TYPE_NONE
:
14850 case VIR_STORAGE_TYPE_LAST
:
14851 virReportError(VIR_ERR_INTERNAL_ERROR
,
14852 _("external inactive snapshots are not supported on "
14853 "'%s' disks"), virStorageTypeToString(domDiskType
));
14857 switch ((virStorageType
)snapDiskType
) {
14858 case VIR_STORAGE_TYPE_BLOCK
:
14859 case VIR_STORAGE_TYPE_FILE
:
14862 case VIR_STORAGE_TYPE_NETWORK
:
14863 case VIR_STORAGE_TYPE_DIR
:
14864 case VIR_STORAGE_TYPE_VOLUME
:
14865 case VIR_STORAGE_TYPE_NONE
:
14866 case VIR_STORAGE_TYPE_LAST
:
14867 virReportError(VIR_ERR_INTERNAL_ERROR
,
14868 _("external inactive snapshots are not supported on "
14869 "'%s' disks"), virStorageTypeToString(snapDiskType
));
14873 if (qemuDomainSnapshotPrepareDiskShared(snapdisk
, domdisk
) < 0)
14881 qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk
,
14882 virDomainDiskDefPtr domdisk
)
14884 int actualType
= virStorageSourceGetActualType(snapdisk
->src
);
14886 if (domdisk
->device
== VIR_DOMAIN_DISK_DEVICE_LUN
) {
14887 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
14888 _("external active snapshots are not supported on scsi "
14889 "passthrough devices"));
14893 switch ((virStorageType
)actualType
) {
14894 case VIR_STORAGE_TYPE_BLOCK
:
14895 case VIR_STORAGE_TYPE_FILE
:
14898 case VIR_STORAGE_TYPE_NETWORK
:
14899 switch ((virStorageNetProtocol
) snapdisk
->src
->protocol
) {
14900 case VIR_STORAGE_NET_PROTOCOL_GLUSTER
:
14903 case VIR_STORAGE_NET_PROTOCOL_NONE
:
14904 case VIR_STORAGE_NET_PROTOCOL_NBD
:
14905 case VIR_STORAGE_NET_PROTOCOL_RBD
:
14906 case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG
:
14907 case VIR_STORAGE_NET_PROTOCOL_ISCSI
:
14908 case VIR_STORAGE_NET_PROTOCOL_HTTP
:
14909 case VIR_STORAGE_NET_PROTOCOL_HTTPS
:
14910 case VIR_STORAGE_NET_PROTOCOL_FTP
:
14911 case VIR_STORAGE_NET_PROTOCOL_FTPS
:
14912 case VIR_STORAGE_NET_PROTOCOL_TFTP
:
14913 case VIR_STORAGE_NET_PROTOCOL_SSH
:
14914 case VIR_STORAGE_NET_PROTOCOL_VXHS
:
14915 case VIR_STORAGE_NET_PROTOCOL_LAST
:
14916 virReportError(VIR_ERR_INTERNAL_ERROR
,
14917 _("external active snapshots are not supported on "
14918 "'network' disks using '%s' protocol"),
14919 virStorageNetProtocolTypeToString(snapdisk
->src
->protocol
));
14925 case VIR_STORAGE_TYPE_DIR
:
14926 case VIR_STORAGE_TYPE_VOLUME
:
14927 case VIR_STORAGE_TYPE_NONE
:
14928 case VIR_STORAGE_TYPE_LAST
:
14929 virReportError(VIR_ERR_INTERNAL_ERROR
,
14930 _("external active snapshots are not supported on "
14931 "'%s' disks"), virStorageTypeToString(actualType
));
14935 if (qemuDomainSnapshotPrepareDiskShared(snapdisk
, domdisk
) < 0)
14943 qemuDomainSnapshotPrepareDiskExternal(virDomainDiskDefPtr disk
,
14944 virDomainSnapshotDiskDefPtr snapdisk
,
14951 if (disk
->src
->readonly
) {
14952 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
14953 _("external snapshot for readonly disk %s "
14954 "is not supported"), disk
->dst
);
14958 if (qemuTranslateSnapshotDiskSourcePool(snapdisk
) < 0)
14962 if (virDomainDiskTranslateSourcePool(disk
) < 0)
14965 if (qemuDomainSnapshotPrepareDiskExternalInactive(snapdisk
, disk
) < 0)
14968 if (qemuDomainSnapshotPrepareDiskExternalActive(snapdisk
, disk
) < 0)
14972 if (virStorageFileInit(snapdisk
->src
) < 0)
14975 if (virStorageFileStat(snapdisk
->src
, &st
) < 0) {
14976 if (errno
!= ENOENT
) {
14977 virReportSystemError(errno
,
14978 _("unable to stat for disk %s: %s"),
14979 snapdisk
->name
, snapdisk
->src
->path
);
14981 } else if (reuse
) {
14982 virReportSystemError(errno
,
14983 _("missing existing file for disk %s: %s"),
14984 snapdisk
->name
, snapdisk
->src
->path
);
14987 } else if (!S_ISBLK(st
.st_mode
) && st
.st_size
&& !reuse
) {
14988 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
14989 _("external snapshot file for disk %s already "
14990 "exists and is not a block device: %s"),
14991 snapdisk
->name
, snapdisk
->src
->path
);
14998 virStorageFileDeinit(snapdisk
->src
);
15004 qemuDomainSnapshotPrepareDiskInternal(virDomainDiskDefPtr disk
,
15009 /* active disks are handled by qemu itself so no need to worry about those */
15013 if (virDomainDiskTranslateSourcePool(disk
) < 0)
15016 actualType
= virStorageSourceGetActualType(disk
->src
);
15018 switch ((virStorageType
)actualType
) {
15019 case VIR_STORAGE_TYPE_BLOCK
:
15020 case VIR_STORAGE_TYPE_FILE
:
15023 case VIR_STORAGE_TYPE_NETWORK
:
15024 switch ((virStorageNetProtocol
) disk
->src
->protocol
) {
15025 case VIR_STORAGE_NET_PROTOCOL_NONE
:
15026 case VIR_STORAGE_NET_PROTOCOL_NBD
:
15027 case VIR_STORAGE_NET_PROTOCOL_RBD
:
15028 case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG
:
15029 case VIR_STORAGE_NET_PROTOCOL_GLUSTER
:
15030 case VIR_STORAGE_NET_PROTOCOL_ISCSI
:
15031 case VIR_STORAGE_NET_PROTOCOL_HTTP
:
15032 case VIR_STORAGE_NET_PROTOCOL_HTTPS
:
15033 case VIR_STORAGE_NET_PROTOCOL_FTP
:
15034 case VIR_STORAGE_NET_PROTOCOL_FTPS
:
15035 case VIR_STORAGE_NET_PROTOCOL_TFTP
:
15036 case VIR_STORAGE_NET_PROTOCOL_SSH
:
15037 case VIR_STORAGE_NET_PROTOCOL_VXHS
:
15038 case VIR_STORAGE_NET_PROTOCOL_LAST
:
15039 virReportError(VIR_ERR_INTERNAL_ERROR
,
15040 _("internal inactive snapshots are not supported on "
15041 "'network' disks using '%s' protocol"),
15042 virStorageNetProtocolTypeToString(disk
->src
->protocol
));
15047 case VIR_STORAGE_TYPE_DIR
:
15048 case VIR_STORAGE_TYPE_VOLUME
:
15049 case VIR_STORAGE_TYPE_NONE
:
15050 case VIR_STORAGE_TYPE_LAST
:
15051 virReportError(VIR_ERR_INTERNAL_ERROR
,
15052 _("internal inactive snapshots are not supported on "
15053 "'%s' disks"), virStorageTypeToString(actualType
));
15062 qemuDomainSnapshotPrepare(virDomainObjPtr vm
,
15063 virDomainSnapshotDefPtr def
,
15064 unsigned int *flags
)
15068 bool active
= virDomainObjIsActive(vm
);
15069 bool reuse
= (*flags
& VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT
) != 0;
15070 bool found_internal
= false;
15071 bool forbid_internal
= false;
15074 for (i
= 0; i
< def
->ndisks
; i
++) {
15075 virDomainSnapshotDiskDefPtr disk
= &def
->disks
[i
];
15076 virDomainDiskDefPtr dom_disk
= vm
->def
->disks
[i
];
15078 if (disk
->snapshot
!= VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
&&
15079 qemuDomainDiskBlockJobIsActive(dom_disk
))
15082 switch ((virDomainSnapshotLocation
) disk
->snapshot
) {
15083 case VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL
:
15084 found_internal
= true;
15086 if (def
->state
== VIR_DOMAIN_SNAPSHOT_DISK_SNAPSHOT
&& active
) {
15087 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
15088 _("active qemu domains require external disk "
15089 "snapshots; disk %s requested internal"),
15094 if (qemuDomainSnapshotPrepareDiskInternal(dom_disk
,
15098 if (vm
->def
->disks
[i
]->src
->format
> 0 &&
15099 vm
->def
->disks
[i
]->src
->format
!= VIR_STORAGE_FILE_QCOW2
) {
15100 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
15101 _("internal snapshot for disk %s unsupported "
15102 "for storage type %s"),
15104 virStorageFileFormatTypeToString(
15105 vm
->def
->disks
[i
]->src
->format
));
15110 case VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
:
15111 if (!disk
->src
->format
) {
15112 disk
->src
->format
= VIR_STORAGE_FILE_QCOW2
;
15113 } else if (disk
->src
->format
!= VIR_STORAGE_FILE_QCOW2
&&
15114 disk
->src
->format
!= VIR_STORAGE_FILE_QED
) {
15115 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
15116 _("external snapshot format for disk %s "
15117 "is unsupported: %s"),
15119 virStorageFileFormatTypeToString(disk
->src
->format
));
15123 if (qemuDomainSnapshotPrepareDiskExternal(dom_disk
, disk
,
15124 active
, reuse
) < 0)
15130 case VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
:
15131 /* Remember seeing a disk that has snapshot disabled */
15132 if (!virStorageSourceIsEmpty(dom_disk
->src
) &&
15133 !dom_disk
->src
->readonly
)
15134 forbid_internal
= true;
15137 case VIR_DOMAIN_SNAPSHOT_LOCATION_DEFAULT
:
15138 case VIR_DOMAIN_SNAPSHOT_LOCATION_LAST
:
15139 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
15140 _("unexpected code path"));
15145 if (!found_internal
&& !external
&&
15146 def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
) {
15147 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
15148 _("nothing selected for snapshot"));
15152 /* internal snapshot requires a disk image to store the memory image to, and
15153 * also disks can't be excluded from an internal snapshot*/
15154 if ((def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL
&& !found_internal
) ||
15155 (found_internal
&& forbid_internal
)) {
15156 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
15157 _("internal and full system snapshots require all "
15158 "disks to be selected for snapshot"));
15162 /* disk snapshot requires at least one disk */
15163 if (def
->state
== VIR_DOMAIN_SNAPSHOT_DISK_SNAPSHOT
&& !external
) {
15164 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
15165 _("disk-only snapshots require at least "
15166 "one disk to be selected for snapshot"));
15170 /* For now, we don't allow mixing internal and external disks.
15171 * XXX technically, we could mix internal and external disks for
15172 * offline snapshots */
15173 if ((found_internal
&& external
) ||
15174 (def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL
&& external
) ||
15175 (def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
&& found_internal
)) {
15176 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
15177 _("mixing internal and external targets for a snapshot "
15178 "is not yet supported"));
15182 /* internal snapshots + pflash based loader have the following problems:
15183 * - if the variable store is raw, the snapshot fails
15184 * - allowing a qcow2 image as the varstore would make it eligible to receive
15185 * the vmstate dump, which would make it huge
15186 * - offline snapshot would not snapshot the varstore at all
15188 * Avoid the issues by forbidding internal snapshot with pflash completely.
15190 if (found_internal
&&
15191 vm
->def
->os
.loader
&&
15192 vm
->def
->os
.loader
->type
== VIR_DOMAIN_LOADER_TYPE_PFLASH
) {
15193 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
15194 _("internal snapshots of a VM with pflash based "
15195 "firmware are not supported"));
15199 /* Alter flags to let later users know what we learned. */
15200 if (external
&& !active
)
15201 *flags
|= VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
;
15210 struct _qemuDomainSnapshotDiskData
{
15211 virStorageSourcePtr src
;
15212 bool initialized
; /* @src was initialized in the storage driver */
15213 bool created
; /* @src was created by the snapshot code */
15214 bool prepared
; /* @src was prepared using qemuDomainDiskChainElementPrepare */
15215 virDomainDiskDefPtr disk
;
15216 char *relPath
; /* relative path component to fill into original disk */
15218 virStorageSourcePtr persistsrc
;
15219 virDomainDiskDefPtr persistdisk
;
15222 typedef struct _qemuDomainSnapshotDiskData qemuDomainSnapshotDiskData
;
15223 typedef qemuDomainSnapshotDiskData
*qemuDomainSnapshotDiskDataPtr
;
15227 qemuDomainSnapshotDiskDataFree(qemuDomainSnapshotDiskDataPtr data
,
15229 virQEMUDriverPtr driver
,
15230 virDomainObjPtr vm
)
15237 for (i
= 0; i
< ndata
; i
++) {
15238 /* on success of the snapshot the 'src' and 'persistsrc' properties will
15239 * be set to NULL by qemuDomainSnapshotUpdateDiskSources */
15241 if (data
[i
].initialized
)
15242 virStorageFileDeinit(data
[i
].src
);
15244 if (data
[i
].prepared
)
15245 qemuDomainDiskChainElementRevoke(driver
, vm
, data
[i
].src
);
15247 virObjectUnref(data
[i
].src
);
15249 virObjectUnref(data
[i
].persistsrc
);
15250 VIR_FREE(data
[i
].relPath
);
15258 * qemuDomainSnapshotDiskDataCollect:
15260 * Collects and prepares a list of structures that hold information about disks
15261 * that are selected for the snapshot.
15263 static qemuDomainSnapshotDiskDataPtr
15264 qemuDomainSnapshotDiskDataCollect(virQEMUDriverPtr driver
,
15265 virDomainObjPtr vm
,
15266 virDomainMomentObjPtr snap
,
15270 qemuDomainSnapshotDiskDataPtr ret
;
15271 qemuDomainSnapshotDiskDataPtr dd
;
15272 char *backingStoreStr
;
15273 virDomainSnapshotDefPtr snapdef
= virDomainSnapshotObjGetDef(snap
);
15275 if (VIR_ALLOC_N(ret
, snapdef
->ndisks
) < 0)
15278 for (i
= 0; i
< snapdef
->ndisks
; i
++) {
15279 if (snapdef
->disks
[i
].snapshot
== VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
)
15284 dd
->disk
= vm
->def
->disks
[i
];
15286 if (!(dd
->src
= virStorageSourceCopy(snapdef
->disks
[i
].src
, false)))
15289 if (virStorageSourceInitChainElement(dd
->src
, dd
->disk
->src
, false) < 0)
15292 if (qemuDomainStorageFileInit(driver
, vm
, dd
->src
, NULL
) < 0)
15295 dd
->initialized
= true;
15297 /* relative backing store paths need to be updated so that relative
15298 * block commit still works */
15300 if (virStorageFileGetBackingStoreStr(dd
->src
, &backingStoreStr
) < 0)
15302 if (backingStoreStr
!= NULL
) {
15303 if (virStorageIsRelative(backingStoreStr
))
15304 VIR_STEAL_PTR(dd
->relPath
, backingStoreStr
);
15306 VIR_FREE(backingStoreStr
);
15310 /* Note that it's unsafe to assume that the disks in the persistent
15311 * definition match up with the disks in the live definition just by
15312 * checking that the target name is the same. We've done that
15313 * historically this way though. */
15315 (dd
->persistdisk
= virDomainDiskByName(vm
->newDef
, dd
->disk
->dst
,
15318 if (!(dd
->persistsrc
= virStorageSourceCopy(dd
->src
, false)))
15321 if (virStorageSourceInitChainElement(dd
->persistsrc
,
15322 dd
->persistdisk
->src
, false) < 0)
15330 qemuDomainSnapshotDiskDataFree(ret
, snapdef
->ndisks
, driver
, vm
);
15336 qemuDomainSnapshotUpdateDiskSourcesRenumber(virStorageSourcePtr src
)
15338 virStorageSourcePtr next
;
15339 unsigned int idx
= 1;
15341 for (next
= src
->backingStore
; virStorageSourceIsBacking(next
); next
= next
->backingStore
)
15347 * qemuDomainSnapshotUpdateDiskSources:
15348 * @dd: snapshot disk data object
15349 * @persist: set to true if persistent config of the VM was changed
15351 * Updates disk definition after a successful snapshot.
15354 qemuDomainSnapshotUpdateDiskSources(qemuDomainSnapshotDiskDataPtr dd
,
15360 /* storage driver access won'd be needed */
15361 if (dd
->initialized
)
15362 virStorageFileDeinit(dd
->src
);
15364 /* the old disk image is now readonly */
15365 dd
->disk
->src
->readonly
= true;
15367 VIR_STEAL_PTR(dd
->disk
->src
->relPath
, dd
->relPath
);
15368 VIR_STEAL_PTR(dd
->src
->backingStore
, dd
->disk
->src
);
15369 VIR_STEAL_PTR(dd
->disk
->src
, dd
->src
);
15371 /* fix numbering of disks */
15372 qemuDomainSnapshotUpdateDiskSourcesRenumber(dd
->disk
->src
);
15374 if (dd
->persistdisk
) {
15375 VIR_STEAL_PTR(dd
->persistsrc
->backingStore
, dd
->persistdisk
->src
);
15376 VIR_STEAL_PTR(dd
->persistdisk
->src
, dd
->persistsrc
);
15383 qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver
,
15384 virDomainObjPtr vm
,
15385 qemuDomainSnapshotDiskDataPtr dd
,
15386 virJSONValuePtr actions
,
15391 if (qemuBlockSnapshotAddLegacy(actions
, dd
->disk
, dd
->src
, reuse
) < 0)
15394 /* pre-create the image file so that we can label it before handing it to qemu */
15395 if (!reuse
&& dd
->src
->type
!= VIR_STORAGE_TYPE_BLOCK
) {
15396 if (virStorageFileCreate(dd
->src
) < 0) {
15397 virReportSystemError(errno
, _("failed to create image file '%s'"),
15398 NULLSTR(dd
->src
->path
));
15401 dd
->created
= true;
15404 /* set correct security, cgroup and locking options on the new image */
15405 if (qemuDomainDiskChainElementPrepare(driver
, vm
, dd
->src
, false, true) < 0) {
15406 qemuDomainDiskChainElementRevoke(driver
, vm
, dd
->src
);
15410 dd
->prepared
= true;
15419 /* The domain is expected to be locked and active. */
15421 qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver
,
15422 virDomainObjPtr vm
,
15423 virDomainMomentObjPtr snap
,
15424 unsigned int flags
,
15425 qemuDomainAsyncJob asyncJob
)
15427 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
15428 virJSONValuePtr actions
= NULL
;
15429 bool do_transaction
= false;
15432 bool persist
= false;
15433 bool reuse
= (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT
) != 0;
15434 virQEMUDriverConfigPtr cfg
= NULL
;
15435 qemuDomainSnapshotDiskDataPtr diskdata
= NULL
;
15436 virErrorPtr orig_err
= NULL
;
15437 virDomainSnapshotDefPtr snapdef
= virDomainSnapshotObjGetDef(snap
);
15439 if (virDomainObjCheckActive(vm
) < 0)
15442 if (!(actions
= virJSONValueNewArray()))
15445 /* prepare a list of objects to use in the vm definition so that we don't
15446 * have to roll back later */
15447 if (!(diskdata
= qemuDomainSnapshotDiskDataCollect(driver
, vm
, snap
, reuse
)))
15450 cfg
= virQEMUDriverGetConfig(driver
);
15452 /* Based on earlier qemuDomainSnapshotPrepare, all disks in this list are
15453 * now either VIR_DOMAIN_SNAPSHOT_LOCATION_NONE, or
15454 * VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL with a valid file name and
15456 for (i
= 0; i
< snapdef
->ndisks
; i
++) {
15457 if (!diskdata
[i
].src
)
15460 ret
= qemuDomainSnapshotCreateSingleDiskActive(driver
, vm
,
15467 do_transaction
= true;
15470 if (do_transaction
) {
15471 if (qemuDomainObjEnterMonitorAsync(driver
, vm
, asyncJob
) < 0)
15474 ret
= qemuMonitorTransaction(priv
->mon
, &actions
);
15476 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
15479 for (i
= 0; i
< snapdef
->ndisks
; i
++) {
15480 qemuDomainSnapshotDiskDataPtr dd
= &diskdata
[i
];
15485 virDomainAuditDisk(vm
, dd
->disk
->src
, dd
->src
, "snapshot", ret
>= 0);
15488 qemuDomainSnapshotUpdateDiskSources(dd
, &persist
);
15497 orig_err
= virSaveLastError();
15498 for (i
= 0; i
< snapdef
->ndisks
; i
++) {
15499 if (!diskdata
[i
].src
)
15502 if (diskdata
[i
].prepared
)
15503 qemuDomainDiskChainElementRevoke(driver
, vm
, diskdata
[i
].src
);
15505 if (diskdata
[i
].created
&&
15506 virStorageFileUnlink(diskdata
[i
].src
) < 0)
15507 VIR_WARN("Unable to remove just-created %s", diskdata
[i
].src
->path
);
15510 /* on successful snapshot we need to remove locks from the now-old
15511 * disks and if the VM is paused release locks on the images since qemu
15512 * stopped using them*/
15513 bool paused
= virDomainObjGetState(vm
, NULL
) != VIR_DOMAIN_RUNNING
;
15515 for (i
= 0; i
< snapdef
->ndisks
; i
++) {
15516 if (!diskdata
[i
].disk
)
15520 virDomainLockImageDetach(driver
->lockManager
, vm
,
15521 diskdata
[i
].disk
->src
);
15523 virDomainLockImageDetach(driver
->lockManager
, vm
,
15524 diskdata
[i
].disk
->src
->backingStore
);
15528 if (ret
== 0 || !do_transaction
) {
15529 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0 ||
15530 (persist
&& virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
15536 qemuDomainSnapshotDiskDataFree(diskdata
, snapdef
->ndisks
, driver
, vm
);
15537 virJSONValueFree(actions
);
15538 virObjectUnref(cfg
);
15541 virSetError(orig_err
);
15542 virFreeError(orig_err
);
15550 qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr driver
,
15551 virDomainObjPtr vm
,
15552 virDomainMomentObjPtr snap
,
15553 unsigned int flags
)
15555 virObjectEventPtr event
;
15556 bool resume
= false;
15558 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
15560 virDomainSnapshotDefPtr snapdef
= virDomainSnapshotObjGetDef(snap
);
15561 bool memory
= snapdef
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
;
15562 bool memory_unlink
= false;
15563 int thaw
= 0; /* 1 if freeze succeeded, -1 if freeze failed */
15564 bool pmsuspended
= false;
15565 virQEMUDriverConfigPtr cfg
= NULL
;
15567 char *compressedpath
= NULL
;
15568 virQEMUSaveDataPtr data
= NULL
;
15570 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DISK_SNAPSHOT
) ||
15571 !virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_TRANSACTION
)) {
15572 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
15573 _("live disk snapshot not supported with this "
15578 /* If quiesce was requested, then issue a freeze command, and a
15579 * counterpart thaw command when it is actually sent to agent.
15580 * The command will fail if the guest is paused or the guest agent
15581 * is not running, or is already quiesced. */
15582 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE
) {
15585 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
15588 if (virDomainObjCheckActive(vm
) < 0) {
15589 qemuDomainObjEndAgentJob(vm
);
15593 freeze
= qemuDomainSnapshotFSFreeze(driver
, vm
, NULL
, 0);
15594 qemuDomainObjEndAgentJob(vm
);
15597 /* the helper reported the error */
15599 thaw
= -1; /* the command is sent but agent failed */
15605 /* We need to track what state the guest is in, since taking the
15606 * snapshot may alter that state and we must restore it later. */
15607 if (virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_PMSUSPENDED
) {
15608 pmsuspended
= true;
15609 } else if (virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
) {
15610 /* For full system external snapshots (those with memory), the guest
15611 * must pause (either by libvirt up front, or by qemu after
15612 * _LIVE converges). */
15616 if (memory
&& !(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_LIVE
)) {
15617 if (qemuProcessStopCPUs(driver
, vm
, VIR_DOMAIN_PAUSED_SNAPSHOT
,
15618 QEMU_ASYNC_JOB_SNAPSHOT
) < 0)
15621 if (!virDomainObjIsActive(vm
)) {
15622 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
15623 _("guest unexpectedly quit"));
15631 /* do the memory snapshot if necessary */
15633 /* check if migration is possible */
15634 if (!qemuMigrationSrcIsAllowed(driver
, vm
, false, 0))
15637 priv
->job
.current
->statsType
= QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP
;
15639 /* allow the migration job to be cancelled or the domain to be paused */
15640 qemuDomainObjSetAsyncJobMask(vm
, (QEMU_JOB_DEFAULT_MASK
|
15641 JOB_MASK(QEMU_JOB_SUSPEND
) |
15642 JOB_MASK(QEMU_JOB_MIGRATION_OP
)));
15644 cfg
= virQEMUDriverGetConfig(driver
);
15645 if ((compressed
= qemuGetCompressionProgram(cfg
->snapshotImageFormat
,
15647 "snapshot", false)) < 0)
15650 if (!(xml
= qemuDomainDefFormatLive(driver
, vm
->def
, priv
->origCPU
,
15652 !(snapdef
->cookie
= (virObjectPtr
) qemuDomainSaveCookieNew(vm
)))
15655 if (!(data
= virQEMUSaveDataNew(xml
,
15656 (qemuDomainSaveCookiePtr
) snapdef
->cookie
,
15657 resume
, compressed
, driver
->xmlopt
)))
15661 if ((ret
= qemuDomainSaveMemory(driver
, vm
, snapdef
->file
, data
,
15663 QEMU_ASYNC_JOB_SNAPSHOT
)) < 0)
15666 /* the memory image was created, remove it on errors */
15667 memory_unlink
= true;
15669 /* forbid any further manipulation */
15670 qemuDomainObjSetAsyncJobMask(vm
, QEMU_JOB_DEFAULT_MASK
);
15673 /* the domain is now paused if a memory snapshot was requested */
15675 if ((ret
= qemuDomainSnapshotCreateDiskActive(driver
, vm
, snap
, flags
,
15676 QEMU_ASYNC_JOB_SNAPSHOT
)) < 0)
15679 /* the snapshot is complete now */
15680 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_HALT
) {
15681 event
= virDomainEventLifecycleNewFromObj(vm
, VIR_DOMAIN_EVENT_STOPPED
,
15682 VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT
);
15683 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT
,
15684 QEMU_ASYNC_JOB_SNAPSHOT
, 0);
15685 virDomainAuditStop(vm
, "from-snapshot");
15688 virObjectEventStateQueue(driver
->domainEventState
, event
);
15689 } else if (memory
&& pmsuspended
) {
15690 /* qemu 1.3 is unable to save a domain in pm-suspended (S3)
15691 * state; so we must emit an event stating that it was
15692 * converted to paused. */
15693 virDomainObjSetState(vm
, VIR_DOMAIN_PAUSED
,
15694 VIR_DOMAIN_PAUSED_FROM_SNAPSHOT
);
15695 event
= virDomainEventLifecycleNewFromObj(vm
, VIR_DOMAIN_EVENT_SUSPENDED
,
15696 VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT
);
15697 virObjectEventStateQueue(driver
->domainEventState
, event
);
15703 if (resume
&& virDomainObjIsActive(vm
) &&
15704 qemuProcessStartCPUs(driver
, vm
,
15705 VIR_DOMAIN_RUNNING_UNPAUSED
,
15706 QEMU_ASYNC_JOB_SNAPSHOT
) < 0) {
15707 event
= virDomainEventLifecycleNewFromObj(vm
,
15708 VIR_DOMAIN_EVENT_SUSPENDED
,
15709 VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR
);
15710 virObjectEventStateQueue(driver
->domainEventState
, event
);
15711 if (virGetLastErrorCode() == VIR_ERR_OK
) {
15712 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
15713 _("resuming after snapshot failed"));
15720 qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) >= 0 &&
15721 virDomainObjIsActive(vm
)) {
15722 if (qemuDomainSnapshotFSThaw(driver
, vm
, ret
== 0 && thaw
> 0) < 0) {
15723 /* helper reported the error, if it was needed */
15728 qemuDomainObjEndAgentJob(vm
);
15731 virQEMUSaveDataFree(data
);
15733 VIR_FREE(compressedpath
);
15734 virObjectUnref(cfg
);
15735 if (memory_unlink
&& ret
< 0)
15736 unlink(snapdef
->file
);
15742 static virDomainSnapshotPtr
15743 qemuDomainSnapshotCreateXML(virDomainPtr domain
,
15744 const char *xmlDesc
,
15745 unsigned int flags
)
15747 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
15748 virDomainObjPtr vm
= NULL
;
15750 virDomainMomentObjPtr snap
= NULL
;
15751 virDomainSnapshotPtr snapshot
= NULL
;
15752 virDomainSnapshotDefPtr def
= NULL
;
15753 virDomainMomentObjPtr current
= NULL
;
15754 bool update_current
= true;
15755 bool redefine
= flags
& VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
;
15756 unsigned int parse_flags
= VIR_DOMAIN_SNAPSHOT_PARSE_DISKS
;
15757 virDomainMomentObjPtr other
= NULL
;
15758 int align_location
= VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL
;
15759 bool align_match
= true;
15760 virQEMUDriverConfigPtr cfg
= NULL
;
15761 virCapsPtr caps
= NULL
;
15762 qemuDomainObjPrivatePtr priv
;
15763 virDomainSnapshotState state
;
15765 virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
|
15766 VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
|
15767 VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA
|
15768 VIR_DOMAIN_SNAPSHOT_CREATE_HALT
|
15769 VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
|
15770 VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT
|
15771 VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE
|
15772 VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC
|
15773 VIR_DOMAIN_SNAPSHOT_CREATE_LIVE
, NULL
);
15775 VIR_REQUIRE_FLAG_RET(VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE
,
15776 VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
,
15778 VIR_EXCLUSIVE_FLAGS_RET(VIR_DOMAIN_SNAPSHOT_CREATE_LIVE
,
15779 VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
,
15782 if ((redefine
&& !(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
)) ||
15783 (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA
))
15784 update_current
= false;
15786 parse_flags
|= VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE
;
15788 if (!(vm
= qemuDomObjFromDomain(domain
)))
15791 cfg
= virQEMUDriverGetConfig(driver
);
15793 if (virDomainSnapshotCreateXMLEnsureACL(domain
->conn
, vm
->def
, flags
) < 0)
15796 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
15799 if (qemuProcessAutoDestroyActive(driver
, vm
)) {
15800 virReportError(VIR_ERR_OPERATION_INVALID
,
15801 "%s", _("domain is marked for auto destroy"));
15805 if (!vm
->persistent
&& (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_HALT
)) {
15806 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
15807 _("cannot halt after transient domain snapshot"));
15810 if ((flags
& VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
) ||
15811 !virDomainObjIsActive(vm
))
15812 parse_flags
|= VIR_DOMAIN_SNAPSHOT_PARSE_OFFLINE
;
15814 if (!(def
= virDomainSnapshotDefParseString(xmlDesc
, caps
, driver
->xmlopt
,
15815 NULL
, parse_flags
)))
15818 /* reject snapshot names containing slashes or starting with dot as
15819 * snapshot definitions are saved in files named by the snapshot name */
15820 if (!(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA
)) {
15821 if (strchr(def
->common
.name
, '/')) {
15822 virReportError(VIR_ERR_XML_DETAIL
,
15823 _("invalid snapshot name '%s': "
15824 "name can't contain '/'"),
15829 if (def
->common
.name
[0] == '.') {
15830 virReportError(VIR_ERR_XML_DETAIL
,
15831 _("invalid snapshot name '%s': "
15832 "name can't start with '.'"),
15838 /* reject the VIR_DOMAIN_SNAPSHOT_CREATE_LIVE flag where not supported */
15839 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_LIVE
&&
15840 (!virDomainObjIsActive(vm
) ||
15841 def
->memory
!= VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
)) {
15842 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
15843 _("live snapshot creation is supported only "
15844 "during full system snapshots"));
15848 /* allow snapshots only in certain states */
15849 state
= redefine
? def
->state
: vm
->state
.state
;
15852 case VIR_DOMAIN_SNAPSHOT_RUNNING
:
15853 case VIR_DOMAIN_SNAPSHOT_PAUSED
:
15854 case VIR_DOMAIN_SNAPSHOT_SHUTDOWN
:
15855 case VIR_DOMAIN_SNAPSHOT_SHUTOFF
:
15856 case VIR_DOMAIN_SNAPSHOT_CRASHED
:
15859 case VIR_DOMAIN_SNAPSHOT_DISK_SNAPSHOT
:
15861 virReportError(VIR_ERR_INTERNAL_ERROR
, _("Invalid domain state %s"),
15862 virDomainSnapshotStateTypeToString(state
));
15867 case VIR_DOMAIN_SNAPSHOT_PMSUSPENDED
:
15868 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
15869 _("qemu doesn't support taking snapshots of "
15870 "PMSUSPENDED guests"));
15873 /* invalid states */
15874 case VIR_DOMAIN_SNAPSHOT_NOSTATE
:
15875 case VIR_DOMAIN_SNAPSHOT_BLOCKED
: /* invalid state, unused in qemu */
15876 case VIR_DOMAIN_SNAPSHOT_LAST
:
15877 virReportError(VIR_ERR_INTERNAL_ERROR
, _("Invalid domain state %s"),
15878 virDomainSnapshotStateTypeToString(state
));
15882 /* We are going to modify the domain below. Internal snapshots would use
15883 * a regular job, so we need to set the job mask to disallow query as
15884 * 'savevm' blocks the monitor. External snapshot will then modify the
15885 * job mask appropriately. */
15886 if (qemuDomainObjBeginAsyncJob(driver
, vm
, QEMU_ASYNC_JOB_SNAPSHOT
,
15887 VIR_DOMAIN_JOB_OPERATION_SNAPSHOT
, flags
) < 0)
15890 qemuDomainObjSetAsyncJobMask(vm
, QEMU_JOB_NONE
);
15892 priv
= vm
->privateData
;
15895 if (virDomainSnapshotRedefinePrep(domain
, vm
, &def
, &snap
,
15897 &update_current
, flags
) < 0)
15900 /* Easiest way to clone inactive portion of vm->def is via
15901 * conversion in and back out of xml. */
15902 if (!(xml
= qemuDomainDefFormatLive(driver
, vm
->def
, priv
->origCPU
,
15904 !(def
->common
.dom
= virDomainDefParseString(xml
, caps
, driver
->xmlopt
, NULL
,
15905 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
15906 VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
)))
15909 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
) {
15910 align_location
= VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
;
15911 align_match
= false;
15912 if (virDomainObjIsActive(vm
))
15913 def
->state
= VIR_DOMAIN_SNAPSHOT_DISK_SNAPSHOT
;
15915 def
->state
= VIR_DOMAIN_SNAPSHOT_SHUTOFF
;
15916 def
->memory
= VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
;
15917 } else if (def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
) {
15918 def
->state
= virDomainObjGetState(vm
, NULL
);
15919 align_location
= VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
;
15920 align_match
= false;
15922 def
->state
= virDomainObjGetState(vm
, NULL
);
15924 if (virDomainObjIsActive(vm
) &&
15925 def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
) {
15926 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
15927 _("internal snapshot of a running VM "
15928 "must include the memory state"));
15932 def
->memory
= (def
->state
== VIR_DOMAIN_SNAPSHOT_SHUTOFF
?
15933 VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
:
15934 VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL
);
15936 if (virDomainSnapshotAlignDisks(def
, align_location
,
15937 align_match
) < 0 ||
15938 qemuDomainSnapshotPrepare(vm
, def
, &flags
) < 0)
15943 if (!(snap
= virDomainSnapshotAssignDef(vm
->snapshots
, def
)))
15949 current
= virDomainSnapshotGetCurrent(vm
->snapshots
);
15952 VIR_STRDUP(snap
->def
->parent
, current
->def
->name
) < 0)
15954 if (update_current
) {
15955 virDomainSnapshotSetCurrent(vm
->snapshots
, NULL
);
15956 if (qemuDomainSnapshotWriteMetadata(vm
, current
,
15957 driver
->caps
, driver
->xmlopt
,
15958 cfg
->snapshotDir
) < 0)
15963 /* actually do the snapshot */
15965 /* XXX Should we validate that the redefined snapshot even
15966 * makes sense, such as checking that qemu-img recognizes the
15967 * snapshot name in at least one of the domain's disks? */
15968 } else if (virDomainObjIsActive(vm
)) {
15969 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
||
15970 virDomainSnapshotObjGetDef(snap
)->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
) {
15971 /* external full system or disk snapshot */
15972 if (qemuDomainSnapshotCreateActiveExternal(driver
,
15973 vm
, snap
, flags
) < 0)
15976 /* internal full system */
15977 if (qemuDomainSnapshotCreateActiveInternal(driver
,
15978 vm
, snap
, flags
) < 0)
15982 /* inactive; qemuDomainSnapshotPrepare guaranteed that we
15983 * aren't mixing internal and external, and altered flags to
15984 * contain DISK_ONLY if there is an external disk. */
15985 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
) {
15986 bool reuse
= !!(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT
);
15988 if (qemuDomainSnapshotCreateInactiveExternal(driver
, vm
, snap
,
15992 if (qemuDomainSnapshotCreateInactiveInternal(driver
, vm
, snap
) < 0)
15997 /* If we fail after this point, there's not a whole lot we can
15998 * do; we've successfully taken the snapshot, and we are now running
15999 * on it, so we have to go forward the best we can
16001 snapshot
= virGetDomainSnapshot(domain
, snap
->def
->name
);
16004 if (snapshot
&& !(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA
)) {
16005 if (update_current
)
16006 virDomainSnapshotSetCurrent(vm
->snapshots
, snap
);
16007 if (qemuDomainSnapshotWriteMetadata(vm
, snap
, driver
->caps
,
16009 cfg
->snapshotDir
) < 0) {
16010 /* if writing of metadata fails, error out rather than trying
16011 * to silently carry on without completing the snapshot */
16012 virObjectUnref(snapshot
);
16014 virReportError(VIR_ERR_INTERNAL_ERROR
,
16015 _("unable to save metadata for snapshot %s"),
16017 virDomainSnapshotObjListRemove(vm
->snapshots
, snap
);
16019 other
= virDomainSnapshotFindByName(vm
->snapshots
,
16020 snap
->def
->parent
);
16021 virDomainMomentSetParent(snap
, other
);
16024 virDomainSnapshotObjListRemove(vm
->snapshots
, snap
);
16027 qemuDomainObjEndAsyncJob(driver
, vm
);
16030 virDomainObjEndAPI(&vm
);
16031 virDomainSnapshotDefFree(def
);
16033 virObjectUnref(caps
);
16034 virObjectUnref(cfg
);
16040 qemuDomainSnapshotListNames(virDomainPtr domain
,
16043 unsigned int flags
)
16045 virDomainObjPtr vm
= NULL
;
16048 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
|
16049 VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL
|
16050 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16052 if (!(vm
= qemuDomObjFromDomain(domain
)))
16055 if (virDomainSnapshotListNamesEnsureACL(domain
->conn
, vm
->def
) < 0)
16058 n
= virDomainSnapshotObjListGetNames(vm
->snapshots
, NULL
, names
, nameslen
,
16062 virDomainObjEndAPI(&vm
);
16068 qemuDomainSnapshotNum(virDomainPtr domain
,
16069 unsigned int flags
)
16071 virDomainObjPtr vm
= NULL
;
16074 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
|
16075 VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL
|
16076 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16078 if (!(vm
= qemuDomObjFromDomain(domain
)))
16081 if (virDomainSnapshotNumEnsureACL(domain
->conn
, vm
->def
) < 0)
16084 n
= virDomainSnapshotObjListNum(vm
->snapshots
, NULL
, flags
);
16087 virDomainObjEndAPI(&vm
);
16093 qemuDomainListAllSnapshots(virDomainPtr domain
,
16094 virDomainSnapshotPtr
**snaps
,
16095 unsigned int flags
)
16097 virDomainObjPtr vm
= NULL
;
16100 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
|
16101 VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL
|
16102 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16104 if (!(vm
= qemuDomObjFromDomain(domain
)))
16107 if (virDomainListAllSnapshotsEnsureACL(domain
->conn
, vm
->def
) < 0)
16110 n
= virDomainListSnapshots(vm
->snapshots
, NULL
, domain
, snaps
, flags
);
16113 virDomainObjEndAPI(&vm
);
16119 qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot
,
16122 unsigned int flags
)
16124 virDomainObjPtr vm
= NULL
;
16125 virDomainMomentObjPtr snap
= NULL
;
16128 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS
|
16129 VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL
|
16130 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16132 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16135 if (virDomainSnapshotListChildrenNamesEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16138 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16141 n
= virDomainSnapshotObjListGetNames(vm
->snapshots
, snap
, names
, nameslen
,
16145 virDomainObjEndAPI(&vm
);
16151 qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot
,
16152 unsigned int flags
)
16154 virDomainObjPtr vm
= NULL
;
16155 virDomainMomentObjPtr snap
= NULL
;
16158 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS
|
16159 VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL
|
16160 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16162 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16165 if (virDomainSnapshotNumChildrenEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16168 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16171 n
= virDomainSnapshotObjListNum(vm
->snapshots
, snap
, flags
);
16174 virDomainObjEndAPI(&vm
);
16180 qemuDomainSnapshotListAllChildren(virDomainSnapshotPtr snapshot
,
16181 virDomainSnapshotPtr
**snaps
,
16182 unsigned int flags
)
16184 virDomainObjPtr vm
= NULL
;
16185 virDomainMomentObjPtr snap
= NULL
;
16188 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS
|
16189 VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL
|
16190 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16192 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16195 if (virDomainSnapshotListAllChildrenEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16198 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16201 n
= virDomainListSnapshots(vm
->snapshots
, snap
, snapshot
->domain
, snaps
,
16205 virDomainObjEndAPI(&vm
);
16210 static virDomainSnapshotPtr
16211 qemuDomainSnapshotLookupByName(virDomainPtr domain
,
16213 unsigned int flags
)
16215 virDomainObjPtr vm
;
16216 virDomainMomentObjPtr snap
= NULL
;
16217 virDomainSnapshotPtr snapshot
= NULL
;
16219 virCheckFlags(0, NULL
);
16221 if (!(vm
= qemuDomObjFromDomain(domain
)))
16224 if (virDomainSnapshotLookupByNameEnsureACL(domain
->conn
, vm
->def
) < 0)
16227 if (!(snap
= qemuSnapObjFromName(vm
, name
)))
16230 snapshot
= virGetDomainSnapshot(domain
, snap
->def
->name
);
16233 virDomainObjEndAPI(&vm
);
16239 qemuDomainHasCurrentSnapshot(virDomainPtr domain
,
16240 unsigned int flags
)
16242 virDomainObjPtr vm
;
16245 virCheckFlags(0, -1);
16247 if (!(vm
= qemuDomObjFromDomain(domain
)))
16250 if (virDomainHasCurrentSnapshotEnsureACL(domain
->conn
, vm
->def
) < 0)
16253 ret
= (virDomainSnapshotGetCurrent(vm
->snapshots
) != NULL
);
16256 virDomainObjEndAPI(&vm
);
16261 static virDomainSnapshotPtr
16262 qemuDomainSnapshotGetParent(virDomainSnapshotPtr snapshot
,
16263 unsigned int flags
)
16265 virDomainObjPtr vm
;
16266 virDomainMomentObjPtr snap
= NULL
;
16267 virDomainSnapshotPtr parent
= NULL
;
16269 virCheckFlags(0, NULL
);
16271 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16274 if (virDomainSnapshotGetParentEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16277 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16280 if (!snap
->def
->parent
) {
16281 virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT
,
16282 _("snapshot '%s' does not have a parent"),
16287 parent
= virGetDomainSnapshot(snapshot
->domain
, snap
->def
->parent
);
16290 virDomainObjEndAPI(&vm
);
16295 static virDomainSnapshotPtr
16296 qemuDomainSnapshotCurrent(virDomainPtr domain
,
16297 unsigned int flags
)
16299 virDomainObjPtr vm
;
16300 virDomainSnapshotPtr snapshot
= NULL
;
16303 virCheckFlags(0, NULL
);
16305 if (!(vm
= qemuDomObjFromDomain(domain
)))
16308 if (virDomainSnapshotCurrentEnsureACL(domain
->conn
, vm
->def
) < 0)
16311 name
= virDomainSnapshotGetCurrentName(vm
->snapshots
);
16313 virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT
, "%s",
16314 _("the domain does not have a current snapshot"));
16318 snapshot
= virGetDomainSnapshot(domain
, name
);
16321 virDomainObjEndAPI(&vm
);
16327 qemuDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot
,
16328 unsigned int flags
)
16330 virQEMUDriverPtr driver
= snapshot
->domain
->conn
->privateData
;
16331 virDomainObjPtr vm
= NULL
;
16333 virDomainMomentObjPtr snap
= NULL
;
16334 char uuidstr
[VIR_UUID_STRING_BUFLEN
];
16336 virCheckFlags(VIR_DOMAIN_SNAPSHOT_XML_SECURE
, NULL
);
16338 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16341 if (virDomainSnapshotGetXMLDescEnsureACL(snapshot
->domain
->conn
, vm
->def
, flags
) < 0)
16344 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16347 virUUIDFormat(snapshot
->domain
->uuid
, uuidstr
);
16349 xml
= virDomainSnapshotDefFormat(uuidstr
, virDomainSnapshotObjGetDef(snap
),
16350 driver
->caps
, driver
->xmlopt
,
16351 virDomainSnapshotFormatConvertXMLFlags(flags
));
16354 virDomainObjEndAPI(&vm
);
16360 qemuDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot
,
16361 unsigned int flags
)
16363 virDomainObjPtr vm
= NULL
;
16365 virDomainMomentObjPtr snap
= NULL
;
16367 virCheckFlags(0, -1);
16369 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16372 if (virDomainSnapshotIsCurrentEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16375 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16378 ret
= snap
== virDomainSnapshotGetCurrent(vm
->snapshots
);
16381 virDomainObjEndAPI(&vm
);
16387 qemuDomainSnapshotHasMetadata(virDomainSnapshotPtr snapshot
,
16388 unsigned int flags
)
16390 virDomainObjPtr vm
= NULL
;
16392 virDomainMomentObjPtr snap
= NULL
;
16394 virCheckFlags(0, -1);
16396 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16399 if (virDomainSnapshotHasMetadataEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16402 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16405 /* XXX Someday, we should recognize internal snapshots in qcow2
16406 * images that are not tied to a libvirt snapshot; if we ever do
16407 * that, then we would have a reason to return 0 here. */
16411 virDomainObjEndAPI(&vm
);
16416 /* The domain is expected to be locked and inactive. */
16418 qemuDomainSnapshotRevertInactive(virQEMUDriverPtr driver
,
16419 virDomainObjPtr vm
,
16420 virDomainMomentObjPtr snap
)
16422 /* Try all disks, but report failure if we skipped any. */
16423 int ret
= qemuDomainSnapshotForEachQcow2(driver
, vm
, snap
, "-a", true);
16424 return ret
> 0 ? -1 : ret
;
16429 qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot
,
16430 unsigned int flags
)
16432 virQEMUDriverPtr driver
= snapshot
->domain
->conn
->privateData
;
16433 virDomainObjPtr vm
= NULL
;
16435 virDomainMomentObjPtr snap
= NULL
;
16436 virDomainMomentObjPtr current
= NULL
;
16437 virDomainSnapshotDefPtr snapdef
;
16438 virObjectEventPtr event
= NULL
;
16439 virObjectEventPtr event2
= NULL
;
16441 qemuDomainObjPrivatePtr priv
;
16443 virDomainDefPtr config
= NULL
;
16444 virQEMUDriverConfigPtr cfg
= NULL
;
16445 virCapsPtr caps
= NULL
;
16446 bool was_stopped
= false;
16447 qemuDomainSaveCookiePtr cookie
;
16448 virCPUDefPtr origCPU
= NULL
;
16449 unsigned int start_flags
= VIR_QEMU_PROCESS_START_GEN_VMID
;
16450 qemuDomainAsyncJob jobType
= QEMU_ASYNC_JOB_START
;
16452 virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING
|
16453 VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
|
16454 VIR_DOMAIN_SNAPSHOT_REVERT_FORCE
, -1);
16456 /* We have the following transitions, which create the following events:
16457 * 1. inactive -> inactive: none
16458 * 2. inactive -> running: EVENT_STARTED
16459 * 3. inactive -> paused: EVENT_STARTED, EVENT_PAUSED
16460 * 4. running -> inactive: EVENT_STOPPED
16461 * 5. running -> running: none
16462 * 6. running -> paused: EVENT_PAUSED
16463 * 7. paused -> inactive: EVENT_STOPPED
16464 * 8. paused -> running: EVENT_RESUMED
16465 * 9. paused -> paused: none
16466 * Also, several transitions occur even if we fail partway through,
16467 * and use of FORCE can cause multiple transitions.
16470 virNWFilterReadLockFilterUpdates();
16472 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16475 cfg
= virQEMUDriverGetConfig(driver
);
16477 if (virDomainRevertToSnapshotEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16480 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
16483 if (qemuDomainHasBlockjob(vm
, false)) {
16484 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
16485 _("domain has active block job"));
16489 if (qemuProcessBeginJob(driver
, vm
,
16490 VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT
,
16494 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16496 snapdef
= virDomainSnapshotObjGetDef(snap
);
16498 if (!vm
->persistent
&&
16499 snapdef
->state
!= VIR_DOMAIN_SNAPSHOT_RUNNING
&&
16500 snapdef
->state
!= VIR_DOMAIN_SNAPSHOT_PAUSED
&&
16501 (flags
& (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING
|
16502 VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
)) == 0) {
16503 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
16504 _("transient domain needs to request run or pause "
16505 "to revert to inactive snapshot"));
16509 if (virDomainSnapshotIsExternal(snap
)) {
16510 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
16511 _("revert to external snapshot not supported yet"));
16515 if (!(flags
& VIR_DOMAIN_SNAPSHOT_REVERT_FORCE
)) {
16516 if (!snap
->def
->dom
) {
16517 virReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY
,
16518 _("snapshot '%s' lacks domain '%s' rollback info"),
16519 snap
->def
->name
, vm
->def
->name
);
16522 if (virDomainObjIsActive(vm
) &&
16523 !(snapdef
->state
== VIR_DOMAIN_SNAPSHOT_RUNNING
||
16524 snapdef
->state
== VIR_DOMAIN_SNAPSHOT_PAUSED
) &&
16525 (flags
& (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING
|
16526 VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
))) {
16527 virReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY
, "%s",
16528 _("must respawn qemu to start inactive snapshot"));
16533 current
= virDomainSnapshotGetCurrent(vm
->snapshots
);
16535 virDomainSnapshotSetCurrent(vm
->snapshots
, NULL
);
16536 if (qemuDomainSnapshotWriteMetadata(vm
, current
,
16537 driver
->caps
, driver
->xmlopt
,
16538 cfg
->snapshotDir
) < 0)
16540 /* XXX Should we restore the current snapshot after this point
16541 * in the failure cases where we know there was no change? */
16544 /* Prepare to copy the snapshot inactive xml as the config of this
16547 * XXX Should domain snapshots track live xml rather
16548 * than inactive xml? */
16549 if (snap
->def
->dom
) {
16550 config
= virDomainDefCopy(snap
->def
->dom
, caps
,
16551 driver
->xmlopt
, NULL
, true);
16556 cookie
= (qemuDomainSaveCookiePtr
) snapdef
->cookie
;
16558 switch ((virDomainSnapshotState
) snapdef
->state
) {
16559 case VIR_DOMAIN_SNAPSHOT_RUNNING
:
16560 case VIR_DOMAIN_SNAPSHOT_PAUSED
:
16562 start_flags
|= VIR_QEMU_PROCESS_START_PAUSED
;
16564 /* Transitions 2, 3, 5, 6, 8, 9 */
16565 /* When using the loadvm monitor command, qemu does not know
16566 * whether to pause or run the reverted domain, and just stays
16567 * in the same state as before the monitor command, whether
16568 * that is paused or running. We always pause before loadvm,
16569 * to have finer control. */
16570 if (virDomainObjIsActive(vm
)) {
16571 /* Transitions 5, 6, 8, 9 */
16572 /* Check for ABI compatibility. We need to do this check against
16573 * the migratable XML or it will always fail otherwise */
16577 /* Replace the CPU in config and put the original one in priv
16578 * once we're done. When we have the updated CPU def in the
16579 * cookie, we don't want to replace the CPU in migratable def
16580 * when doing ABI checks to make sure the current CPU exactly
16581 * matches the one used at the time the snapshot was taken.
16583 if (cookie
&& cookie
->cpu
&& config
->cpu
) {
16584 origCPU
= config
->cpu
;
16585 if (!(config
->cpu
= virCPUDefCopy(cookie
->cpu
)))
16588 compatible
= qemuDomainDefCheckABIStability(driver
, vm
->def
,
16591 compatible
= qemuDomainCheckABIStability(driver
, vm
, config
);
16594 /* If using VM GenID, there is no way currently to change
16595 * the genid for the running guest, so set an error,
16596 * mark as incompatible, and don't allow change of genid
16597 * if the revert force flag would start the guest again. */
16598 if (compatible
&& config
->genidRequested
) {
16599 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
16600 _("domain genid update requires restart"));
16601 compatible
= false;
16602 start_flags
&= ~VIR_QEMU_PROCESS_START_GEN_VMID
;
16606 virErrorPtr err
= virGetLastError();
16608 if (!(flags
& VIR_DOMAIN_SNAPSHOT_REVERT_FORCE
)) {
16609 /* Re-spawn error using correct category. */
16610 if (err
->code
== VIR_ERR_CONFIG_UNSUPPORTED
)
16611 virReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY
, "%s",
16615 virResetError(err
);
16616 qemuProcessStop(driver
, vm
,
16617 VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT
,
16618 QEMU_ASYNC_JOB_START
, 0);
16619 virDomainAuditStop(vm
, "from-snapshot");
16620 detail
= VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT
;
16621 event
= virDomainEventLifecycleNewFromObj(vm
,
16622 VIR_DOMAIN_EVENT_STOPPED
,
16624 virObjectEventStateQueue(driver
->domainEventState
, event
);
16625 /* Start after stop won't be an async start job, so
16627 jobType
= QEMU_ASYNC_JOB_NONE
;
16632 priv
= vm
->privateData
;
16633 if (virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
) {
16634 /* Transitions 5, 6 */
16635 if (qemuProcessStopCPUs(driver
, vm
,
16636 VIR_DOMAIN_PAUSED_FROM_SNAPSHOT
,
16637 QEMU_ASYNC_JOB_START
) < 0)
16639 /* Create an event now in case the restore fails, so
16640 * that user will be alerted that they are now paused.
16641 * If restore later succeeds, we might replace this. */
16642 detail
= VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT
;
16643 event
= virDomainEventLifecycleNewFromObj(vm
,
16644 VIR_DOMAIN_EVENT_SUSPENDED
,
16646 if (!virDomainObjIsActive(vm
)) {
16647 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
16648 _("guest unexpectedly quit"));
16653 if (qemuDomainObjEnterMonitorAsync(driver
, vm
,
16654 QEMU_ASYNC_JOB_START
) < 0)
16656 rc
= qemuMonitorLoadSnapshot(priv
->mon
, snap
->def
->name
);
16657 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
16660 /* XXX resume domain if it was running before the
16661 * failed loadvm attempt? */
16665 virDomainObjAssignDef(vm
, config
, false, NULL
);
16666 virCPUDefFree(priv
->origCPU
);
16667 VIR_STEAL_PTR(priv
->origCPU
, origCPU
);
16670 /* Transitions 2, 3 */
16672 was_stopped
= true;
16674 virDomainObjAssignDef(vm
, config
, false, NULL
);
16676 /* No cookie means libvirt which saved the domain was too old to
16677 * mess up the CPU definitions.
16680 qemuDomainFixupCPUs(vm
, &cookie
->cpu
) < 0)
16683 rc
= qemuProcessStart(snapshot
->domain
->conn
, driver
, vm
,
16684 cookie
? cookie
->cpu
: NULL
,
16685 jobType
, NULL
, -1, NULL
, snap
,
16686 VIR_NETDEV_VPORT_PROFILE_OP_CREATE
,
16688 virDomainAuditStart(vm
, "from-snapshot", rc
>= 0);
16689 detail
= VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT
;
16690 event
= virDomainEventLifecycleNewFromObj(vm
,
16691 VIR_DOMAIN_EVENT_STARTED
,
16697 /* Touch up domain state. */
16698 if (!(flags
& VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING
) &&
16699 (snapdef
->state
== VIR_DOMAIN_SNAPSHOT_PAUSED
||
16700 (flags
& VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
))) {
16701 /* Transitions 3, 6, 9 */
16702 virDomainObjSetState(vm
, VIR_DOMAIN_PAUSED
,
16703 VIR_DOMAIN_PAUSED_FROM_SNAPSHOT
);
16705 /* Transition 3, use event as-is and add event2 */
16706 detail
= VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT
;
16707 event2
= virDomainEventLifecycleNewFromObj(vm
,
16708 VIR_DOMAIN_EVENT_SUSPENDED
,
16710 } /* else transition 6 and 9 use event as-is */
16712 /* Transitions 2, 5, 8 */
16713 if (!virDomainObjIsActive(vm
)) {
16714 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
16715 _("guest unexpectedly quit"));
16718 rc
= qemuProcessStartCPUs(driver
, vm
,
16719 VIR_DOMAIN_RUNNING_FROM_SNAPSHOT
,
16723 virObjectUnref(event
);
16727 detail
= VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT
;
16728 event
= virDomainEventLifecycleNewFromObj(vm
,
16729 VIR_DOMAIN_EVENT_STARTED
,
16735 case VIR_DOMAIN_SNAPSHOT_SHUTDOWN
:
16736 case VIR_DOMAIN_SNAPSHOT_SHUTOFF
:
16737 case VIR_DOMAIN_SNAPSHOT_CRASHED
:
16738 /* Transitions 1, 4, 7 */
16739 /* Newer qemu -loadvm refuses to revert to the state of a snapshot
16740 * created by qemu-img snapshot -c. If the domain is running, we
16741 * must take it offline; then do the revert using qemu-img.
16744 if (virDomainObjIsActive(vm
)) {
16745 /* Transitions 4, 7 */
16746 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT
,
16747 QEMU_ASYNC_JOB_START
, 0);
16748 virDomainAuditStop(vm
, "from-snapshot");
16749 detail
= VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT
;
16750 event
= virDomainEventLifecycleNewFromObj(vm
,
16751 VIR_DOMAIN_EVENT_STOPPED
,
16755 if (qemuDomainSnapshotRevertInactive(driver
, vm
, snap
) < 0) {
16756 qemuDomainRemoveInactive(driver
, vm
);
16757 qemuProcessEndJob(driver
, vm
);
16761 virDomainObjAssignDef(vm
, config
, false, NULL
);
16763 if (flags
& (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING
|
16764 VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
)) {
16765 /* Flush first event, now do transition 2 or 3 */
16766 bool paused
= (flags
& VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
) != 0;
16768 start_flags
|= paused
? VIR_QEMU_PROCESS_START_PAUSED
: 0;
16770 virObjectEventStateQueue(driver
->domainEventState
, event
);
16771 rc
= qemuProcessStart(snapshot
->domain
->conn
, driver
, vm
, NULL
,
16772 QEMU_ASYNC_JOB_START
, NULL
, -1, NULL
, NULL
,
16773 VIR_NETDEV_VPORT_PROFILE_OP_CREATE
,
16775 virDomainAuditStart(vm
, "from-snapshot", rc
>= 0);
16777 qemuDomainRemoveInactive(driver
, vm
);
16778 qemuProcessEndJob(driver
, vm
);
16781 detail
= VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT
;
16782 event
= virDomainEventLifecycleNewFromObj(vm
,
16783 VIR_DOMAIN_EVENT_STARTED
,
16786 detail
= VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT
;
16787 event2
= virDomainEventLifecycleNewFromObj(vm
,
16788 VIR_DOMAIN_EVENT_SUSPENDED
,
16794 case VIR_DOMAIN_SNAPSHOT_PMSUSPENDED
:
16795 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
16796 _("qemu doesn't support reversion of snapshot taken in "
16797 "PMSUSPENDED state"));
16800 case VIR_DOMAIN_SNAPSHOT_DISK_SNAPSHOT
:
16801 /* Rejected earlier as an external snapshot */
16802 case VIR_DOMAIN_SNAPSHOT_NOSTATE
:
16803 case VIR_DOMAIN_SNAPSHOT_BLOCKED
:
16804 case VIR_DOMAIN_SNAPSHOT_LAST
:
16805 virReportError(VIR_ERR_INTERNAL_ERROR
,
16806 _("Invalid target domain state '%s'. Refusing "
16807 "snapshot reversion"),
16808 virDomainSnapshotStateTypeToString(snapdef
->state
));
16815 qemuProcessEndJob(driver
, vm
);
16819 virDomainSnapshotSetCurrent(vm
->snapshots
, snap
);
16820 if (qemuDomainSnapshotWriteMetadata(vm
, snap
, driver
->caps
,
16822 cfg
->snapshotDir
) < 0) {
16823 virDomainSnapshotSetCurrent(vm
->snapshots
, NULL
);
16827 virDomainSnapshotSetCurrent(vm
->snapshots
, NULL
);
16829 if (ret
== 0 && config
&& vm
->persistent
&&
16830 !(ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
16831 vm
->newDef
? vm
->newDef
: vm
->def
))) {
16832 detail
= VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT
;
16833 virObjectEventStateQueue(driver
->domainEventState
,
16834 virDomainEventLifecycleNewFromObj(vm
,
16835 VIR_DOMAIN_EVENT_DEFINED
,
16838 virObjectEventStateQueue(driver
->domainEventState
, event
);
16839 virObjectEventStateQueue(driver
->domainEventState
, event2
);
16840 virDomainObjEndAPI(&vm
);
16841 virObjectUnref(caps
);
16842 virObjectUnref(cfg
);
16843 virNWFilterUnlockFilterUpdates();
16844 virCPUDefFree(origCPU
);
16850 typedef struct _virQEMUMomentReparent virQEMUMomentReparent
;
16851 typedef virQEMUMomentReparent
*virQEMUMomentReparentPtr
;
16852 struct _virQEMUMomentReparent
{
16854 virDomainMomentObjPtr parent
;
16855 virDomainObjPtr vm
;
16857 virDomainXMLOptionPtr xmlopt
;
16859 int (*writeMetadata
)(virDomainObjPtr
, virDomainMomentObjPtr
,
16860 virCapsPtr
, virDomainXMLOptionPtr
, const char *);
16865 qemuDomainMomentReparentChildren(void *payload
,
16866 const void *name ATTRIBUTE_UNUSED
,
16869 virDomainMomentObjPtr moment
= payload
;
16870 virQEMUMomentReparentPtr rep
= data
;
16875 VIR_FREE(moment
->def
->parent
);
16877 if (rep
->parent
->def
&&
16878 VIR_STRDUP(moment
->def
->parent
, rep
->parent
->def
->name
) < 0) {
16883 rep
->err
= rep
->writeMetadata(rep
->vm
, moment
, rep
->caps
, rep
->xmlopt
,
16890 qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot
,
16891 unsigned int flags
)
16893 virQEMUDriverPtr driver
= snapshot
->domain
->conn
->privateData
;
16894 virDomainObjPtr vm
= NULL
;
16896 virDomainMomentObjPtr snap
= NULL
;
16897 virQEMUMomentRemove rem
;
16898 virQEMUMomentReparent rep
;
16899 bool metadata_only
= !!(flags
& VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY
);
16901 virQEMUDriverConfigPtr cfg
= NULL
;
16903 virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN
|
16904 VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY
|
16905 VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
, -1);
16907 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16910 cfg
= virQEMUDriverGetConfig(driver
);
16912 if (virDomainSnapshotDeleteEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16915 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
16918 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16921 if (!metadata_only
) {
16922 if (!(flags
& VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
) &&
16923 virDomainSnapshotIsExternal(snap
))
16925 if (flags
& (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN
|
16926 VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
))
16927 virDomainMomentForEachDescendant(snap
,
16928 qemuDomainSnapshotCountExternal
,
16931 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
16932 _("deletion of %d external disk snapshots not "
16933 "supported yet"), external
);
16938 if (flags
& (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN
|
16939 VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
)) {
16940 rem
.driver
= driver
;
16942 rem
.metadata_only
= metadata_only
;
16944 rem
.current
= virDomainSnapshotGetCurrent(vm
->snapshots
);
16946 rem
.momentDiscard
= qemuDomainSnapshotDiscard
;
16947 virDomainMomentForEachDescendant(snap
, qemuDomainMomentDiscardAll
,
16952 virDomainSnapshotSetCurrent(vm
->snapshots
, snap
);
16953 if (flags
& VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
) {
16954 if (qemuDomainSnapshotWriteMetadata(vm
, snap
, driver
->caps
,
16956 cfg
->snapshotDir
) < 0) {
16957 virReportError(VIR_ERR_INTERNAL_ERROR
,
16958 _("failed to set snapshot '%s' as current"),
16960 virDomainSnapshotSetCurrent(vm
->snapshots
, NULL
);
16965 } else if (snap
->nchildren
) {
16966 rep
.dir
= cfg
->snapshotDir
;
16967 rep
.parent
= snap
->parent
;
16970 rep
.caps
= driver
->caps
;
16971 rep
.xmlopt
= driver
->xmlopt
;
16972 rep
.writeMetadata
= qemuDomainSnapshotWriteMetadata
;
16973 virDomainMomentForEachChild(snap
,
16974 qemuDomainMomentReparentChildren
,
16978 virDomainMomentMoveChildren(snap
, snap
->parent
);
16981 if (flags
& VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
) {
16982 virDomainMomentDropChildren(snap
);
16985 ret
= qemuDomainSnapshotDiscard(driver
, vm
, snap
, true, metadata_only
);
16989 qemuDomainObjEndJob(driver
, vm
);
16992 virDomainObjEndAPI(&vm
);
16993 virObjectUnref(cfg
);
16998 /* Called prior to job lock */
16999 static virDomainCheckpointDefPtr
17000 qemuDomainCheckpointDefParseString(virQEMUDriverPtr driver
, virCapsPtr caps
,
17001 const char *xmlDesc
, unsigned int flags
)
17003 virDomainCheckpointDefPtr def
= NULL
;
17004 virDomainCheckpointDefPtr ret
= NULL
;
17005 unsigned int parse_flags
= 0;
17007 if (flags
& VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE
)
17008 parse_flags
|= VIR_DOMAIN_CHECKPOINT_PARSE_REDEFINE
;
17009 if (!(def
= virDomainCheckpointDefParseString(xmlDesc
, caps
, driver
->xmlopt
,
17010 NULL
, parse_flags
)))
17013 /* reject checkpoint names containing slashes or starting with dot as
17014 * checkpoint definitions are saved in files named by the checkpoint name */
17015 if (!(flags
& VIR_DOMAIN_CHECKPOINT_CREATE_NO_METADATA
)) {
17016 if (strchr(def
->common
.name
, '/')) {
17017 virReportError(VIR_ERR_XML_DETAIL
,
17018 _("invalid checkpoint name '%s': "
17019 "name can't contain '/'"),
17024 if (def
->common
.name
[0] == '.') {
17025 virReportError(VIR_ERR_XML_DETAIL
,
17026 _("invalid checkpoint name '%s': "
17027 "name can't start with '.'"),
17033 VIR_STEAL_PTR(ret
, def
);
17036 virDomainCheckpointDefFree(def
);
17041 /* Called inside job lock */
17043 qemuDomainCheckpointPrepare(virQEMUDriverPtr driver
, virCapsPtr caps
,
17044 virDomainObjPtr vm
,
17045 virDomainCheckpointDefPtr def
)
17050 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
17052 /* Easiest way to clone inactive portion of vm->def is via
17053 * conversion in and back out of xml. */
17054 if (!(xml
= qemuDomainDefFormatLive(driver
, vm
->def
, priv
->origCPU
,
17056 !(def
->common
.dom
= virDomainDefParseString(xml
, caps
, driver
->xmlopt
, NULL
,
17057 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
17058 VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
)))
17061 if (virDomainCheckpointAlignDisks(def
) < 0 ||
17062 qemuBlockNodeNamesDetect(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
17065 for (i
= 0; i
< def
->ndisks
; i
++) {
17066 virDomainCheckpointDiskDefPtr disk
= &def
->disks
[i
];
17068 if (disk
->type
!= VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP
)
17071 /* We want to name temporary bitmap after disk name during
17072 * incremental backup, which is not possible if that is a
17073 * persistent bitmap name. We can also make life easier by
17074 * enforcing bitmap names match checkpoint name, although this
17075 * is not technically necessary. */
17076 if (STREQ(disk
->name
, disk
->bitmap
)) {
17077 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
17078 _("checkpoint for disk %s must have distinct bitmap name"),
17082 if (STRNEQ(disk
->bitmap
, def
->common
.name
)) {
17083 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
17084 _("disk %s bitmap should match checkpoint name %s"),
17085 disk
->name
, def
->common
.name
);
17089 if (vm
->def
->disks
[i
]->src
->format
> 0 &&
17090 vm
->def
->disks
[i
]->src
->format
!= VIR_STORAGE_FILE_QCOW2
) {
17091 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
17092 _("checkpoint for disk %s unsupported "
17093 "for storage type %s"),
17095 virStorageFileFormatTypeToString(
17096 vm
->def
->disks
[i
]->src
->format
));
17109 qemuDomainCheckpointAddActions(virDomainObjPtr vm
,
17110 virJSONValuePtr actions
,
17111 virDomainMomentObjPtr old_current
,
17112 virDomainCheckpointDefPtr def
)
17116 virDomainCheckpointDefPtr olddef
;
17118 olddef
= virDomainCheckpointObjGetDef(old_current
);
17119 for (i
= 0; i
< def
->ndisks
; i
++) {
17120 virDomainCheckpointDiskDef
*disk
= &def
->disks
[i
];
17123 if (disk
->type
!= VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP
)
17125 node
= qemuBlockNodeLookup(vm
, disk
->name
);
17126 if (qemuMonitorJSONTransactionAdd(actions
,
17127 "block-dirty-bitmap-add",
17129 "s:name", disk
->bitmap
,
17130 "b:persistent", true,
17134 for (j
= 0; j
< olddef
->ndisks
; j
++) {
17135 virDomainCheckpointDiskDef
*disk2
;
17137 disk2
= &olddef
->disks
[j
];
17138 if (STRNEQ(disk
->name
, disk2
->name
))
17140 if (disk2
->type
== VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP
&&
17141 qemuMonitorJSONTransactionAdd(actions
,
17142 "block-dirty-bitmap-disable",
17144 "s:name", disk2
->bitmap
,
17156 static virDomainCheckpointPtr
17157 qemuDomainCheckpointCreateXML(virDomainPtr domain
,
17158 const char *xmlDesc
,
17159 unsigned int flags
)
17161 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
17162 virDomainObjPtr vm
= NULL
;
17164 virDomainMomentObjPtr chk
= NULL
;
17165 virDomainCheckpointPtr checkpoint
= NULL
;
17166 virDomainCheckpointDefPtr def
= NULL
;
17167 virDomainMomentObjPtr current
= NULL
;
17168 bool update_current
= true;
17169 bool redefine
= flags
& VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE
;
17170 unsigned int parse_flags
= 0;
17171 virDomainMomentObjPtr other
= NULL
;
17172 virQEMUDriverConfigPtr cfg
= NULL
;
17173 virCapsPtr caps
= NULL
;
17174 qemuDomainObjPrivatePtr priv
;
17175 virJSONValuePtr actions
= NULL
;
17178 virCheckFlags(VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE
|
17179 VIR_DOMAIN_CHECKPOINT_CREATE_CURRENT
|
17180 VIR_DOMAIN_CHECKPOINT_CREATE_NO_METADATA
, NULL
);
17181 /* TODO: VIR_DOMAIN_CHECKPOINT_CREATE_QUIESCE */
17184 parse_flags
|= VIR_DOMAIN_CHECKPOINT_PARSE_REDEFINE
;
17185 if ((redefine
&& !(flags
& VIR_DOMAIN_CHECKPOINT_CREATE_CURRENT
)) ||
17186 (flags
& VIR_DOMAIN_CHECKPOINT_CREATE_NO_METADATA
))
17187 update_current
= false;
17189 if (!(vm
= qemuDomObjFromDomain(domain
)))
17192 priv
= vm
->privateData
;
17193 cfg
= virQEMUDriverGetConfig(driver
);
17195 if (virDomainCheckpointCreateXMLEnsureACL(domain
->conn
, vm
->def
, flags
) < 0)
17198 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BITMAP_MERGE
)) {
17199 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
17200 _("qemu binary lacks persistent bitmaps support"));
17204 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
17207 if (qemuProcessAutoDestroyActive(driver
, vm
)) {
17208 virReportError(VIR_ERR_OPERATION_INVALID
,
17209 "%s", _("domain is marked for auto destroy"));
17213 if (!virDomainObjIsActive(vm
)) {
17214 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
17215 _("cannot create checkpoint for inactive domain"));
17219 if (!(def
= qemuDomainCheckpointDefParseString(driver
, caps
, xmlDesc
,
17223 /* We are going to modify the domain below. */
17224 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
17228 if (virDomainCheckpointRedefinePrep(domain
, vm
, &def
, &chk
,
17230 &update_current
) < 0)
17232 } else if (qemuDomainCheckpointPrepare(driver
, caps
, vm
, def
) < 0) {
17237 if (!(chk
= virDomainCheckpointAssignDef(vm
->checkpoints
, def
)))
17243 other
= virDomainCheckpointGetCurrent(vm
->checkpoints
);
17246 VIR_STRDUP(chk
->def
->parent
, other
->def
->name
) < 0)
17248 if (update_current
) {
17249 virDomainCheckpointSetCurrent(vm
->checkpoints
, NULL
);
17250 if (qemuDomainCheckpointWriteMetadata(vm
, current
,
17251 driver
->caps
, driver
->xmlopt
,
17252 cfg
->checkpointDir
) < 0)
17257 /* actually do the checkpoint */
17259 /* XXX Should we validate that the redefined checkpoint even
17260 * makes sense, such as checking that qemu-img recognizes the
17261 * checkpoint bitmap name in at least one of the domain's disks? */
17263 if (!(actions
= virJSONValueNewArray()))
17265 if (qemuDomainCheckpointAddActions(vm
, actions
, other
,
17266 virDomainCheckpointObjGetDef(chk
)) < 0)
17268 qemuDomainObjEnterMonitor(driver
, vm
);
17269 ret
= qemuMonitorTransaction(priv
->mon
, &actions
);
17270 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || ret
< 0)
17274 /* If we fail after this point, there's not a whole lot we can do;
17275 * we've successfully created the checkpoint, so we have to go
17276 * forward the best we can.
17278 checkpoint
= virGetDomainCheckpoint(domain
, chk
->def
->name
);
17281 if (checkpoint
&& !(flags
& VIR_DOMAIN_CHECKPOINT_CREATE_NO_METADATA
)) {
17282 if (update_current
)
17283 virDomainCheckpointSetCurrent(vm
->checkpoints
, chk
);
17284 if (qemuDomainCheckpointWriteMetadata(vm
, chk
, driver
->caps
,
17286 cfg
->checkpointDir
) < 0) {
17287 /* if writing of metadata fails, error out rather than trying
17288 * to silently carry on without completing the checkpoint */
17289 virObjectUnref(checkpoint
);
17291 virReportError(VIR_ERR_INTERNAL_ERROR
,
17292 _("unable to save metadata for checkpoint %s"),
17294 virDomainCheckpointObjListRemove(vm
->checkpoints
, chk
);
17296 other
= virDomainCheckpointFindByName(vm
->checkpoints
,
17298 virDomainMomentSetParent(chk
, other
);
17301 virDomainCheckpointObjListRemove(vm
->checkpoints
, chk
);
17304 qemuDomainObjEndJob(driver
, vm
);
17307 virJSONValueFree(actions
);
17308 virDomainObjEndAPI(&vm
);
17309 virDomainCheckpointDefFree(def
);
17311 virObjectUnref(caps
);
17312 virObjectUnref(cfg
);
17318 qemuDomainListAllCheckpoints(virDomainPtr domain
,
17319 virDomainCheckpointPtr
**chks
,
17320 unsigned int flags
)
17322 virDomainObjPtr vm
= NULL
;
17325 virCheckFlags(VIR_DOMAIN_CHECKPOINT_LIST_ROOTS
|
17326 VIR_DOMAIN_CHECKPOINT_LIST_TOPOLOGICAL
|
17327 VIR_DOMAIN_CHECKPOINT_FILTERS_ALL
, -1);
17329 if (!(vm
= qemuDomObjFromDomain(domain
)))
17332 if (virDomainListAllCheckpointsEnsureACL(domain
->conn
, vm
->def
) < 0)
17335 n
= virDomainListCheckpoints(vm
->checkpoints
, NULL
, domain
, chks
, flags
);
17338 virDomainObjEndAPI(&vm
);
17344 qemuDomainCheckpointListAllChildren(virDomainCheckpointPtr checkpoint
,
17345 virDomainCheckpointPtr
**chks
,
17346 unsigned int flags
)
17348 virDomainObjPtr vm
= NULL
;
17349 virDomainMomentObjPtr chk
= NULL
;
17352 virCheckFlags(VIR_DOMAIN_CHECKPOINT_LIST_DESCENDANTS
|
17353 VIR_DOMAIN_CHECKPOINT_LIST_TOPOLOGICAL
|
17354 VIR_DOMAIN_CHECKPOINT_FILTERS_ALL
, -1);
17356 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17359 if (virDomainCheckpointListAllChildrenEnsureACL(checkpoint
->domain
->conn
,
17363 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17366 n
= virDomainListCheckpoints(vm
->checkpoints
, chk
, checkpoint
->domain
,
17370 virDomainObjEndAPI(&vm
);
17375 static virDomainCheckpointPtr
17376 qemuDomainCheckpointLookupByName(virDomainPtr domain
,
17378 unsigned int flags
)
17380 virDomainObjPtr vm
;
17381 virDomainMomentObjPtr chk
= NULL
;
17382 virDomainCheckpointPtr checkpoint
= NULL
;
17384 virCheckFlags(0, NULL
);
17386 if (!(vm
= qemuDomObjFromDomain(domain
)))
17389 if (virDomainCheckpointLookupByNameEnsureACL(domain
->conn
, vm
->def
) < 0)
17392 if (!(chk
= qemuCheckObjFromName(vm
, name
)))
17395 checkpoint
= virGetDomainCheckpoint(domain
, chk
->def
->name
);
17398 virDomainObjEndAPI(&vm
);
17404 qemuDomainHasCurrentCheckpoint(virDomainPtr domain
,
17405 unsigned int flags
)
17407 virDomainObjPtr vm
;
17410 virCheckFlags(0, -1);
17412 if (!(vm
= qemuDomObjFromDomain(domain
)))
17415 if (virDomainHasCurrentCheckpointEnsureACL(domain
->conn
, vm
->def
) < 0)
17418 ret
= (virDomainCheckpointGetCurrent(vm
->checkpoints
) != NULL
);
17421 virDomainObjEndAPI(&vm
);
17426 static virDomainCheckpointPtr
17427 qemuDomainCheckpointGetParent(virDomainCheckpointPtr checkpoint
,
17428 unsigned int flags
)
17430 virDomainObjPtr vm
;
17431 virDomainMomentObjPtr chk
= NULL
;
17432 virDomainCheckpointPtr parent
= NULL
;
17434 virCheckFlags(0, NULL
);
17436 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17439 if (virDomainCheckpointGetParentEnsureACL(checkpoint
->domain
->conn
, vm
->def
) < 0)
17442 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17445 if (!chk
->def
->parent
) {
17446 virReportError(VIR_ERR_NO_DOMAIN_CHECKPOINT
,
17447 _("checkpoint '%s' does not have a parent"),
17452 parent
= virGetDomainCheckpoint(checkpoint
->domain
, chk
->def
->parent
);
17455 virDomainObjEndAPI(&vm
);
17460 static virDomainCheckpointPtr
17461 qemuDomainCheckpointCurrent(virDomainPtr domain
,
17462 unsigned int flags
)
17464 virDomainObjPtr vm
;
17465 virDomainCheckpointPtr checkpoint
= NULL
;
17468 virCheckFlags(0, NULL
);
17470 if (!(vm
= qemuDomObjFromDomain(domain
)))
17473 if (virDomainCheckpointCurrentEnsureACL(domain
->conn
, vm
->def
) < 0)
17476 name
= virDomainCheckpointGetCurrentName(vm
->checkpoints
);
17478 virReportError(VIR_ERR_NO_DOMAIN_CHECKPOINT
, "%s",
17479 _("the domain does not have a current checkpoint"));
17483 checkpoint
= virGetDomainCheckpoint(domain
, name
);
17486 virDomainObjEndAPI(&vm
);
17492 qemuDomainCheckpointGetXMLDesc(virDomainCheckpointPtr checkpoint
,
17493 unsigned int flags
)
17495 virQEMUDriverPtr driver
= checkpoint
->domain
->conn
->privateData
;
17496 virDomainObjPtr vm
= NULL
;
17498 virDomainMomentObjPtr chk
= NULL
;
17499 qemuDomainObjPrivatePtr priv
;
17502 virDomainCheckpointDefPtr chkdef
;
17504 virCheckFlags(VIR_DOMAIN_CHECKPOINT_XML_SECURE
|
17505 VIR_DOMAIN_CHECKPOINT_XML_NO_DOMAIN
|
17506 VIR_DOMAIN_CHECKPOINT_XML_SIZE
, NULL
);
17508 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17511 if (virDomainCheckpointGetXMLDescEnsureACL(checkpoint
->domain
->conn
, vm
->def
, flags
) < 0)
17514 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17516 chkdef
= virDomainCheckpointObjGetDef(chk
);
17518 if (flags
& VIR_DOMAIN_CHECKPOINT_XML_SIZE
) {
17519 /* TODO: for non-current checkpoint, this requires a QMP sequence per
17520 disk, since the stat of one bitmap in isolation is too low,
17521 and merely adding bitmap sizes may be too high:
17522 block-dirty-bitmap-create tmp
17523 for each bitmap from checkpoint to current:
17524 add bitmap to src_list
17525 block-dirty-bitmap-merge dst=tmp src_list
17526 query-block and read tmp size
17527 block-dirty-bitmap-remove tmp
17528 So for now, go with simpler query-blocks only for current.
17530 if (virDomainCheckpointGetCurrent(vm
->checkpoints
) != chk
) {
17531 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
17532 _("cannot compute size for non-current checkpoint '%s'"),
17537 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
17540 if (virDomainObjCheckActive(vm
) < 0)
17543 if (qemuBlockNodeNamesDetect(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
17546 /* TODO: Shouldn't need to recompute node names. */
17547 for (i
= 0; i
< chkdef
->ndisks
; i
++) {
17548 virDomainCheckpointDiskDef
*disk
= &chkdef
->disks
[i
];
17550 if (disk
->type
!= VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP
)
17552 VIR_FREE(chk
->def
->dom
->disks
[disk
->idx
]->src
->nodeformat
);
17553 if (VIR_STRDUP(chk
->def
->dom
->disks
[disk
->idx
]->src
->nodeformat
,
17554 qemuBlockNodeLookup(vm
, disk
->name
)) < 0)
17558 priv
= vm
->privateData
;
17559 qemuDomainObjEnterMonitor(driver
, vm
);
17560 rc
= qemuMonitorUpdateCheckpointSize(priv
->mon
, chkdef
);
17561 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
17567 xml
= virDomainCheckpointDefFormat(chkdef
, driver
->caps
, driver
->xmlopt
,
17571 if (flags
& VIR_DOMAIN_CHECKPOINT_XML_SIZE
)
17572 qemuDomainObjEndJob(driver
, vm
);
17575 virDomainObjEndAPI(&vm
);
17581 qemuDomainCheckpointIsCurrent(virDomainCheckpointPtr checkpoint
,
17582 unsigned int flags
)
17584 virDomainObjPtr vm
= NULL
;
17586 virDomainMomentObjPtr chk
= NULL
;
17588 virCheckFlags(0, -1);
17590 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17593 if (virDomainCheckpointIsCurrentEnsureACL(checkpoint
->domain
->conn
, vm
->def
) < 0)
17596 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17599 ret
= chk
== virDomainCheckpointGetCurrent(vm
->checkpoints
);
17602 virDomainObjEndAPI(&vm
);
17608 qemuDomainCheckpointHasMetadata(virDomainCheckpointPtr checkpoint
,
17609 unsigned int flags
)
17611 virDomainObjPtr vm
= NULL
;
17613 virDomainMomentObjPtr chk
= NULL
;
17615 virCheckFlags(0, -1);
17617 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17620 if (virDomainCheckpointHasMetadataEnsureACL(checkpoint
->domain
->conn
, vm
->def
) < 0)
17623 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17626 /* XXX Someday, we should recognize internal bitmaps in qcow2
17627 * images that are not tied to a libvirt checkpoint; if we ever do
17628 * that, then we would have a reason to return 0 here. */
17632 virDomainObjEndAPI(&vm
);
17638 qemuDomainCheckpointDelete(virDomainCheckpointPtr checkpoint
,
17639 unsigned int flags
)
17641 virQEMUDriverPtr driver
= checkpoint
->domain
->conn
->privateData
;
17642 virDomainObjPtr vm
= NULL
;
17643 qemuDomainObjPrivatePtr priv
;
17645 virDomainMomentObjPtr chk
= NULL
;
17646 virQEMUMomentRemove rem
;
17647 virQEMUMomentReparent rep
;
17648 bool metadata_only
= !!(flags
& VIR_DOMAIN_CHECKPOINT_DELETE_METADATA_ONLY
);
17649 virQEMUDriverConfigPtr cfg
= NULL
;
17651 virCheckFlags(VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN
|
17652 VIR_DOMAIN_CHECKPOINT_DELETE_METADATA_ONLY
|
17653 VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN_ONLY
, -1);
17655 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17658 cfg
= virQEMUDriverGetConfig(driver
);
17660 if (virDomainCheckpointDeleteEnsureACL(checkpoint
->domain
->conn
, vm
->def
) < 0)
17663 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
17666 priv
= vm
->privateData
;
17667 if (!metadata_only
) {
17668 /* Until qemu-img supports offline bitmap deletion, we are stuck
17669 * with requiring a running guest */
17670 if (!virDomainObjIsActive(vm
)) {
17671 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
17672 _("cannot delete checkpoint for inactive domain"));
17675 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BITMAP_MERGE
)) {
17676 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
17677 _("qemu binary lacks persistent bitmaps support"));
17682 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17685 if (flags
& (VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN
|
17686 VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN_ONLY
)) {
17687 rem
.driver
= driver
;
17689 rem
.metadata_only
= metadata_only
;
17691 rem
.current
= virDomainCheckpointGetCurrent(vm
->checkpoints
);
17693 rem
.momentDiscard
= qemuDomainCheckpointDiscard
;
17694 virDomainMomentForEachDescendant(chk
, qemuDomainMomentDiscardAll
,
17699 virDomainCheckpointSetCurrent(vm
->checkpoints
, chk
);
17700 if (flags
& VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN_ONLY
) {
17701 if (qemuDomainCheckpointWriteMetadata(vm
, chk
, driver
->caps
,
17703 cfg
->checkpointDir
) < 0) {
17704 virReportError(VIR_ERR_INTERNAL_ERROR
,
17705 _("failed to set checkpoint '%s' as current"),
17707 virDomainCheckpointSetCurrent(vm
->checkpoints
, NULL
);
17712 } else if (chk
->nchildren
) {
17713 rep
.dir
= cfg
->checkpointDir
;
17714 rep
.parent
= chk
->parent
;
17717 rep
.caps
= driver
->caps
;
17718 rep
.xmlopt
= driver
->xmlopt
;
17719 rep
.writeMetadata
= qemuDomainCheckpointWriteMetadata
;
17720 virDomainMomentForEachChild(chk
, qemuDomainMomentReparentChildren
,
17724 virDomainMomentMoveChildren(chk
, chk
->parent
);
17727 if (flags
& VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN_ONLY
) {
17728 virDomainMomentDropChildren(chk
);
17731 ret
= qemuDomainCheckpointDiscard(driver
, vm
, chk
, true, metadata_only
);
17735 qemuDomainObjEndJob(driver
, vm
);
17738 virDomainObjEndAPI(&vm
);
17739 virObjectUnref(cfg
);
17744 qemuDomainBackupPrepare(virQEMUDriverPtr driver
, virDomainObjPtr vm
,
17745 virDomainBackupDefPtr def
,
17746 virDomainMomentObjPtr chk
)
17750 virDomainCheckpointDefPtr chkdef
= virDomainCheckpointObjGetDef(chk
);
17752 if (chk
&& def
->ndisks
!= chkdef
->ndisks
) {
17753 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
17754 _("inconsistency between backup and checkpoint disks"));
17757 if (qemuBlockNodeNamesDetect(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
17759 for (i
= 0; i
< def
->ndisks
; i
++) {
17760 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
17761 virStorageSourcePtr src
= vm
->def
->disks
[disk
->idx
]->src
;
17763 /* For now, insist that atomic checkpoint affect same disks as
17764 * those being backed up. */
17765 if (!disk
->store
) {
17767 chkdef
->disks
[i
].type
!= VIR_DOMAIN_CHECKPOINT_TYPE_NONE
) {
17768 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
17769 _("disk %s requested checkpoint without backup"),
17776 chkdef
->disks
[i
].type
!= VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP
) {
17777 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
17778 _("disk %s requested backup without checkpoint"),
17782 if (virAsprintf(&disk
->store
->nodeformat
, "tmp-%s", disk
->name
) < 0)
17784 if (!disk
->store
->format
)
17785 disk
->store
->format
= VIR_STORAGE_FILE_QCOW2
;
17786 if (def
->incremental
) {
17787 if (src
->format
!= VIR_STORAGE_FILE_QCOW2
) {
17788 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
17789 _("incremental backup of %s requires qcow2"),
17800 /* Called while monitor lock is held. Best-effort cleanup. */
17802 qemuDomainBackupDiskCleanup(virQEMUDriverPtr driver
, virDomainObjPtr vm
,
17803 virDomainBackupDiskDef
*disk
, bool push
,
17804 bool incremental
, bool completed
)
17806 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
17807 const char *node
= vm
->def
->disks
[disk
->idx
]->src
->nodeformat
;
17810 if (disk
->state
>= VIR_DOMAIN_BACKUP_DISK_STATE_EXPORT
) {
17811 /* No real need to use nbd-server-remove, since we will
17812 * shortly be calling nbd-server-stop. */
17814 if (incremental
&& disk
->state
>= VIR_DOMAIN_BACKUP_DISK_STATE_BITMAP
&&
17815 qemuMonitorDeleteBitmap(priv
->mon
, node
, disk
->name
) < 0) {
17816 VIR_WARN("Unable to remove temp bitmap for disk %s after backup",
17820 if (disk
->state
>= VIR_DOMAIN_BACKUP_DISK_STATE_READY
&&
17821 qemuMonitorBlockdevDel(priv
->mon
, disk
->store
->nodeformat
) < 0) {
17822 VIR_WARN("Unable to remove %s disk %s after backup",
17823 push
? "target" : "scratch", disk
->name
);
17826 if (disk
->state
>= VIR_DOMAIN_BACKUP_DISK_STATE_LABEL
)
17827 qemuDomainDiskChainElementRevoke(driver
, vm
, disk
->store
);
17828 if ((!push
|| !completed
) &&
17829 disk
->state
>= VIR_DOMAIN_BACKUP_DISK_STATE_CREATED
&&
17830 disk
->store
->detected
&& unlink(disk
->store
->path
) < 0) {
17831 VIR_WARN("Unable to unlink %s disk %s after backup",
17832 push
? "failed target" : "scratch", disk
->store
->path
);
17839 qemuDomainBackupBegin(virDomainPtr domain
, const char *diskXml
,
17840 const char *checkpointXml
, unsigned int flags
)
17842 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
17843 virDomainObjPtr vm
= NULL
;
17844 virDomainBackupDefPtr def
= NULL
;
17845 virQEMUDriverConfigPtr cfg
= NULL
;
17846 virCapsPtr caps
= NULL
;
17847 qemuDomainObjPrivatePtr priv
;
17849 virJSONValuePtr json
= NULL
;
17850 bool job_started
= false;
17851 bool nbd_running
= false;
17856 char *suffix
= NULL
;
17857 virCommandPtr cmd
= NULL
;
17858 const char *qemuImgPath
;
17859 virDomainCheckpointDefPtr chkdef
= NULL
;
17860 virDomainMomentObjPtr chk
= NULL
;
17861 virDomainMomentObjPtr other
= NULL
;
17862 virDomainMomentObjPtr parent
= NULL
;
17863 virDomainMomentObjPtr current
;
17864 virJSONValuePtr arr
= NULL
;
17866 virCheckFlags(VIR_DOMAIN_BACKUP_BEGIN_NO_METADATA
, -1);
17867 /* TODO: VIR_DOMAIN_BACKUP_BEGIN_QUIESCE */
17869 if (!(vm
= qemuDomObjFromDomain(domain
)))
17872 priv
= vm
->privateData
;
17873 cfg
= virQEMUDriverGetConfig(driver
);
17875 if (virDomainBackupBeginEnsureACL(domain
->conn
, vm
->def
, flags
) < 0)
17878 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
17881 if (qemuProcessAutoDestroyActive(driver
, vm
)) {
17882 virReportError(VIR_ERR_OPERATION_INVALID
,
17883 "%s", _("domain is marked for auto destroy"));
17887 if (!virDomainObjIsActive(vm
)) {
17888 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
17889 _("cannot perform disk backup for inactive domain"));
17892 if (!(def
= virDomainBackupDefParseString(diskXml
, driver
->xmlopt
, 0)))
17895 if (checkpointXml
) {
17896 if (!(chkdef
= qemuDomainCheckpointDefParseString(driver
, caps
,
17897 checkpointXml
, 0)) ||
17898 VIR_STRDUP(suffix
, chkdef
->common
.name
) < 0)
17901 gettimeofday(&tv
, NULL
);
17902 if (virAsprintf(&suffix
, "%lld", (long long)tv
.tv_sec
) < 0)
17906 push
= def
->type
== VIR_DOMAIN_BACKUP_TYPE_PUSH
;
17908 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_NBD_BITMAP
)) {
17909 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
17910 _("qemu binary lacks pull-mode backup support"));
17913 if (!def
->server
||
17914 def
->server
->transport
!= VIR_STORAGE_NET_HOST_TRANS_TCP
) {
17915 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
17916 _("<domainbackup> must specify TCP server for now"));
17920 current
= virDomainCheckpointGetCurrent(vm
->checkpoints
);
17921 if (def
->incremental
) {
17922 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BITMAP_MERGE
)) {
17923 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
17924 _("qemu binary lacks persistent bitmaps support"));
17927 for (other
= current
; other
;
17928 other
= other
->def
->parent
?
17929 virDomainCheckpointFindByName(vm
->checkpoints
,
17930 other
->def
->parent
) : NULL
)
17931 if (STREQ(other
->def
->name
, def
->incremental
))
17934 virReportError(VIR_ERR_OPERATION_INVALID
,
17935 _("could not locate checkpoint '%s' for incremental backup"),
17941 if (!(qemuImgPath
= qemuFindQemuImgBinary(driver
)))
17944 /* We are going to modify the domain below. */
17945 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
17948 if (priv
->backup
) {
17949 virReportError(VIR_ERR_OPERATION_INVALID
,
17950 "%s", _("another backup job is already running"));
17955 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BITMAP_MERGE
)) {
17956 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
17957 _("qemu binary lacks persistent bitmaps support"));
17961 if (qemuDomainCheckpointPrepare(driver
, caps
, vm
, chkdef
) < 0)
17963 if (!(chk
= virDomainCheckpointAssignDef(vm
->checkpoints
, chkdef
)))
17968 if (VIR_STRDUP(chk
->def
->parent
, parent
->def
->name
) < 0)
17970 if (qemuDomainCheckpointWriteMetadata(vm
, parent
, driver
->caps
,
17972 cfg
->checkpointDir
) < 0)
17977 if (virDomainBackupAlignDisks(def
, vm
->def
, suffix
) < 0 ||
17978 qemuDomainBackupPrepare(driver
, vm
, def
, chk
) < 0)
17981 /* actually start the checkpoint. 2x2 array of push/pull, full/incr,
17982 plus additional tweak if checkpoint requested */
17983 qemuDomainObjEnterMonitor(driver
, vm
);
17984 /* - push/pull: blockdev-add per <disk>
17985 - incr: bitmap-add of tmp, bitmap-merge per <disk> */
17986 for (i
= 0; i
< def
->ndisks
; i
++) {
17987 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
17988 virJSONValuePtr file
;
17989 virStorageSourcePtr src
= vm
->def
->disks
[disk
->idx
]->src
;
17990 const char *node
= src
->nodeformat
;
17994 if (qemuDomainStorageFileInit(driver
, vm
, disk
->store
, src
) < 0)
17996 if (disk
->store
->detected
) {
17997 if (virStorageFileCreate(disk
->store
) < 0) {
17998 virReportSystemError(errno
,
17999 _("failed to create image file '%s'"),
18000 NULLSTR(disk
->store
->path
));
18003 disk
->state
= VIR_DOMAIN_BACKUP_DISK_STATE_CREATED
;
18005 if (qemuDomainDiskChainElementPrepare(driver
, vm
, disk
->store
, false,
18008 disk
->state
= VIR_DOMAIN_BACKUP_DISK_STATE_LABEL
;
18009 if (disk
->store
->detected
) {
18010 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
18012 /* Force initialization of scratch/target file to new qcow2 */
18013 if (!(cmd
= virCommandNewArgList(qemuImgPath
,
18016 virStorageFileFormatTypeToString(disk
->store
->format
),
18020 virBufferAsprintf(&buf
, "backing_fmt=%s,backing_file=",
18021 virStorageFileFormatTypeToString(src
->format
));
18022 virQEMUBuildBufferEscapeComma(&buf
, src
->path
);
18023 virCommandAddArgBuffer(cmd
, &buf
);
18025 virQEMUBuildBufferEscapeComma(&buf
, disk
->store
->path
);
18026 virCommandAddArgBuffer(cmd
, &buf
);
18027 if (virCommandRun(cmd
, NULL
) < 0)
18029 virCommandFree(cmd
);
18033 /* FIXME: allow non-local files for push destinations */
18034 if (virJSONValueObjectCreate(&file
,
18035 "s:driver", "file",
18036 "s:filename", disk
->store
->path
,
18039 if (virJSONValueObjectCreate(&json
,
18040 "s:driver", virStorageFileFormatTypeToString(disk
->store
->format
),
18041 "s:node-name", disk
->store
->nodeformat
,
18043 "s:backing", node
, NULL
) < 0) {
18044 virJSONValueFree(file
);
18047 if (qemuMonitorBlockdevAdd(priv
->mon
, json
) < 0)
18050 disk
->state
= VIR_DOMAIN_BACKUP_DISK_STATE_READY
;
18052 if (def
->incremental
) {
18053 if (!(arr
= virJSONValueNewArray()))
18055 if (qemuMonitorAddBitmap(priv
->mon
, node
, disk
->name
, false) < 0) {
18056 virJSONValueFree(arr
);
18059 disk
->state
= VIR_DOMAIN_BACKUP_DISK_STATE_BITMAP
;
18060 for (other
= parent
? parent
: current
; other
;
18061 other
= other
->def
->parent
?
18062 virDomainCheckpointFindByName(vm
->checkpoints
,
18063 other
->def
->parent
) : NULL
) {
18064 if (virJSONValueArrayAppendString(arr
, other
->def
->name
) < 0) {
18065 virJSONValueFree(arr
);
18068 if (STREQ(other
->def
->name
, def
->incremental
))
18071 if (qemuMonitorMergeBitmaps(priv
->mon
, node
, disk
->name
, &arr
) < 0)
18076 /* - transaction, containing:
18077 - push+full: blockdev-backup sync:full
18078 - push+incr: blockdev-backup sync:incremental bitmap:tmp
18079 - pull+full: blockdev-backup sync:none
18080 - pull+incr: blockdev-backup sync:none, bitmap-disable of tmp
18081 - if checkpoint: bitmap-disable of old, bitmap-add of new
18083 if (!(json
= virJSONValueNewArray()))
18086 mode
= def
->incremental
? "incremental" : "full";
18089 for (i
= 0; i
< def
->ndisks
; i
++) {
18090 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18092 const char *push_bitmap
= NULL
;
18096 node
= qemuBlockNodeLookup(vm
, disk
->name
);
18097 if (push
&& def
->incremental
)
18098 push_bitmap
= disk
->name
;
18099 if (qemuMonitorJSONTransactionAdd(json
,
18102 "s:target", disk
->store
->nodeformat
,
18104 "S:bitmap", push_bitmap
,
18105 "s:job-id", disk
->name
,
18108 if (def
->incremental
&& !push
&&
18109 qemuMonitorJSONTransactionAdd(json
,
18110 "block-dirty-bitmap-disable",
18112 "s:name", disk
->name
,
18116 if (chk
&& qemuDomainCheckpointAddActions(vm
, json
, parent
,
18117 virDomainCheckpointObjGetDef(chk
)) < 0)
18119 if (qemuMonitorTransaction(priv
->mon
, &json
) < 0)
18121 job_started
= true;
18123 if (qemuDomainCheckpointWriteMetadata(vm
, chk
, driver
->caps
,
18125 cfg
->checkpointDir
) < 0) {
18126 virReportError(VIR_ERR_INTERNAL_ERROR
,
18127 _("unable to save metadata for checkpoint %s"),
18129 virDomainCheckpointObjListRemove(vm
->checkpoints
, chk
);
18132 virDomainCheckpointSetCurrent(vm
->checkpoints
, chk
);
18133 other
= virDomainCheckpointFindByName(vm
->checkpoints
,
18135 chk
->parent
= other
;
18136 other
->nchildren
++;
18137 chk
->sibling
= other
->first_child
;
18138 other
->first_child
= chk
;
18142 - pull: nbd-server-start with <server> from user (or autogenerate server)
18143 - pull: nbd-server-add per <disk>, including bitmap for incr
18146 if (qemuMonitorNBDServerStart(priv
->mon
, def
->server
->name
,
18147 def
->server
->port
, NULL
) < 0)
18149 nbd_running
= true;
18150 for (i
= 0; i
< def
->ndisks
; i
++) {
18151 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18155 if (qemuMonitorNBDServerAdd(priv
->mon
, disk
->store
->nodeformat
,
18157 def
->incremental
? disk
->name
:
18160 disk
->state
= VIR_DOMAIN_BACKUP_DISK_STATE_EXPORT
;
18166 /* Best effort cleanup if we fail partway through */
18168 virErrorPtr save_err
= virSaveLastError();
18171 qemuMonitorNBDServerStop(priv
->mon
) < 0)
18172 VIR_WARN("Unable to stop NBD server on vm %s after backup job",
18174 for (i
= 0; i
< def
->ndisks
; i
++) {
18175 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18180 qemuMonitorBlockJobCancel(priv
->mon
, disk
->name
) < 0)
18181 VIR_WARN("Unable to stop backup job %s on vm %s after failure",
18182 disk
->name
, vm
->def
->name
);
18183 qemuDomainBackupDiskCleanup(driver
, vm
, disk
, push
,
18184 !!def
->incremental
, false);
18186 virSetError(save_err
);
18187 virFreeError(save_err
);
18189 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
18194 VIR_STEAL_PTR(priv
->backup
, def
);
18195 ret
= priv
->backup
->id
= 1; /* Hard-coded job id for now */
18196 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
,
18198 VIR_WARN("Unable to save status on vm %s after backup job",
18202 qemuDomainObjEndJob(driver
, vm
);
18205 virJSONValueFree(arr
);
18206 virDomainCheckpointDefFree(chkdef
);
18207 virCommandFree(cmd
);
18209 virJSONValueFree(json
);
18210 virDomainObjEndAPI(&vm
);
18211 virDomainBackupDefFree(def
);
18212 virObjectUnref(caps
);
18213 virObjectUnref(cfg
);
18217 static char *qemuDomainBackupGetXMLDesc(virDomainPtr domain
, int id
,
18218 unsigned int flags
)
18220 virDomainObjPtr vm
= NULL
;
18222 qemuDomainObjPrivatePtr priv
;
18223 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
18225 virCheckFlags(0, NULL
);
18227 if (!(vm
= qemuDomObjFromDomain(domain
)))
18230 if (virDomainBackupGetXMLDescEnsureACL(domain
->conn
, vm
->def
) < 0)
18233 /* TODO: Allow more than one hard-coded job id */
18234 priv
= vm
->privateData
;
18235 if (id
!= 1 || !priv
->backup
) {
18236 virReportError(VIR_ERR_NO_DOMAIN_CHECKPOINT
,
18237 _("no domain backup job with id '%d'"), id
);
18241 if (virDomainBackupDefFormat(&buf
, priv
->backup
, false) < 0)
18243 xml
= virBufferContentAndReset(&buf
);
18246 virDomainObjEndAPI(&vm
);
18250 static int qemuDomainBackupEnd(virDomainPtr domain
, int id
, unsigned int flags
)
18252 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
18253 virQEMUDriverConfigPtr cfg
= NULL
;
18254 virDomainObjPtr vm
= NULL
;
18256 virDomainBackupDefPtr backup
= NULL
;
18257 qemuDomainObjPrivatePtr priv
;
18258 bool want_abort
= flags
& VIR_DOMAIN_BACKUP_END_ABORT
;
18259 virDomainBackupDefPtr def
;
18262 bool completed
= true;
18264 virCheckFlags(VIR_DOMAIN_BACKUP_END_ABORT
, -1);
18266 if (!(vm
= qemuDomObjFromDomain(domain
)))
18269 cfg
= virQEMUDriverGetConfig(driver
);
18270 if (virDomainBackupEndEnsureACL(domain
->conn
, vm
->def
) < 0)
18273 /* TODO: Allow more than one hard-coded job id */
18274 priv
= vm
->privateData
;
18275 if (id
!= 1 || !priv
->backup
) {
18276 virReportError(VIR_ERR_NO_DOMAIN_CHECKPOINT
,
18277 _("no domain backup job with id '%d'"), id
);
18281 def
= priv
->backup
;
18282 if (def
->type
!= VIR_DOMAIN_BACKUP_TYPE_PUSH
) {
18283 want_abort
= false;
18287 /* We are going to modify the domain below. */
18288 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
18291 qemuDomainObjEnterMonitor(driver
, vm
);
18293 for (i
= 0; i
< def
->ndisks
; i
++) {
18294 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18298 if (disk
->state
!= VIR_DOMAIN_BACKUP_DISK_STATE_COMPLETE
)
18302 ret
= qemuMonitorNBDServerStop(priv
->mon
);
18304 if (!completed
&& !want_abort
) {
18305 virReportError(VIR_ERR_OPERATION_INVALID
,
18306 _("backup job id '%d' not complete yet"), id
);
18308 for (i
= 0; i
< def
->ndisks
; i
++) {
18309 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18313 if (!push
|| disk
->state
< VIR_DOMAIN_BACKUP_DISK_STATE_COMPLETE
) {
18314 if (qemuMonitorBlockJobCancel(priv
->mon
,
18321 if (qemuDomainBackupDiskCleanup(driver
, vm
, disk
, push
,
18322 !!def
->incremental
, completed
) < 0)
18326 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || ret
< 0) {
18331 VIR_STEAL_PTR(backup
, priv
->backup
);
18332 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
,
18334 VIR_WARN("Unable to save status on vm %s after backup job",
18337 ret
= want_abort
? 0 : 1;
18340 qemuDomainObjEndJob(driver
, vm
);
18343 virDomainBackupDefFree(backup
);
18344 virDomainObjEndAPI(&vm
);
18348 static int qemuDomainQemuMonitorCommand(virDomainPtr domain
, const char *cmd
,
18349 char **result
, unsigned int flags
)
18351 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
18352 virDomainObjPtr vm
= NULL
;
18354 qemuDomainObjPrivatePtr priv
;
18357 virCheckFlags(VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP
, -1);
18359 if (!(vm
= qemuDomObjFromDomain(domain
)))
18362 if (virDomainQemuMonitorCommandEnsureACL(domain
->conn
, vm
->def
) < 0)
18365 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
18368 if (virDomainObjCheckActive(vm
) < 0)
18371 priv
= vm
->privateData
;
18373 qemuDomainObjTaint(driver
, vm
, VIR_DOMAIN_TAINT_CUSTOM_MONITOR
, NULL
);
18375 hmp
= !!(flags
& VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP
);
18377 qemuDomainObjEnterMonitor(driver
, vm
);
18378 ret
= qemuMonitorArbitraryCommand(priv
->mon
, cmd
, result
, hmp
);
18379 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
18383 qemuDomainObjEndJob(driver
, vm
);
18386 virDomainObjEndAPI(&vm
);
18391 static virDomainPtr
qemuDomainQemuAttach(virConnectPtr conn
,
18392 unsigned int pid_value
,
18393 unsigned int flags
)
18395 virQEMUDriverPtr driver
= conn
->privateData
;
18396 virDomainObjPtr vm
= NULL
;
18397 virDomainDefPtr def
= NULL
;
18398 virDomainPtr dom
= NULL
;
18399 virDomainChrSourceDefPtr monConfig
= NULL
;
18400 bool monJSON
= false;
18401 pid_t pid
= pid_value
;
18402 char *pidfile
= NULL
;
18403 virQEMUCapsPtr qemuCaps
= NULL
;
18404 virCapsPtr caps
= NULL
;
18406 virCheckFlags(0, NULL
);
18408 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
18411 if (!(def
= qemuParseCommandLinePid(driver
->qemuCapsCache
,
18412 caps
, driver
->xmlopt
, pid
,
18413 &pidfile
, &monConfig
, &monJSON
)))
18416 if (virDomainQemuAttachEnsureACL(conn
, def
) < 0)
18420 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
18421 _("No monitor connection for pid %u"), pid_value
);
18424 if (monConfig
->type
!= VIR_DOMAIN_CHR_TYPE_UNIX
) {
18425 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
18426 _("Cannot connect to monitor connection of type '%s' "
18428 virDomainChrTypeToString(monConfig
->type
),
18433 if (!(def
->name
) &&
18434 virAsprintf(&def
->name
, "attach-pid-%u", pid_value
) < 0)
18437 if (!(qemuCaps
= virQEMUCapsCacheLookup(driver
->qemuCapsCache
,
18441 if (qemuAssignDeviceAliases(def
, qemuCaps
) < 0)
18444 if (!(vm
= virDomainObjListAdd(driver
->domains
, def
,
18446 VIR_DOMAIN_OBJ_LIST_ADD_LIVE
|
18447 VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE
,
18453 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0) {
18454 qemuDomainRemoveInactive(driver
, vm
);
18458 if (qemuProcessAttach(conn
, driver
, vm
, pid
,
18459 pidfile
, monConfig
, monJSON
) < 0) {
18461 qemuDomainRemoveInactive(driver
, vm
);
18462 qemuDomainObjEndJob(driver
, vm
);
18468 if (qemuProcessAttach(conn
, driver
, vm
, pid
,
18469 pidfile
, monConfig
, monJSON
) < 0) {
18470 qemuDomainRemoveInactive(driver
, vm
);
18471 qemuDomainObjEndJob(driver
, vm
);
18475 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
18477 qemuDomainObjEndJob(driver
, vm
);
18480 virDomainDefFree(def
);
18481 virObjectUnref(monConfig
);
18482 virDomainObjEndAPI(&vm
);
18484 virObjectUnref(caps
);
18485 virObjectUnref(qemuCaps
);
18491 qemuDomainOpenConsole(virDomainPtr dom
,
18492 const char *dev_name
,
18494 unsigned int flags
)
18496 virDomainObjPtr vm
= NULL
;
18499 virDomainChrDefPtr chr
= NULL
;
18500 qemuDomainObjPrivatePtr priv
;
18502 virCheckFlags(VIR_DOMAIN_CONSOLE_SAFE
|
18503 VIR_DOMAIN_CONSOLE_FORCE
, -1);
18505 if (!(vm
= qemuDomObjFromDomain(dom
)))
18508 if (virDomainOpenConsoleEnsureACL(dom
->conn
, vm
->def
) < 0)
18511 if (virDomainObjCheckActive(vm
) < 0)
18514 priv
= vm
->privateData
;
18517 for (i
= 0; !chr
&& i
< vm
->def
->nconsoles
; i
++) {
18518 if (vm
->def
->consoles
[i
]->info
.alias
&&
18519 STREQ(dev_name
, vm
->def
->consoles
[i
]->info
.alias
))
18520 chr
= vm
->def
->consoles
[i
];
18522 for (i
= 0; !chr
&& i
< vm
->def
->nserials
; i
++) {
18523 if (STREQ(dev_name
, vm
->def
->serials
[i
]->info
.alias
))
18524 chr
= vm
->def
->serials
[i
];
18526 for (i
= 0; !chr
&& i
< vm
->def
->nparallels
; i
++) {
18527 if (STREQ(dev_name
, vm
->def
->parallels
[i
]->info
.alias
))
18528 chr
= vm
->def
->parallels
[i
];
18531 if (vm
->def
->nconsoles
)
18532 chr
= vm
->def
->consoles
[0];
18533 else if (vm
->def
->nserials
)
18534 chr
= vm
->def
->serials
[0];
18538 virReportError(VIR_ERR_INTERNAL_ERROR
,
18539 _("cannot find character device %s"),
18540 NULLSTR(dev_name
));
18544 if (chr
->source
->type
!= VIR_DOMAIN_CHR_TYPE_PTY
) {
18545 virReportError(VIR_ERR_INTERNAL_ERROR
,
18546 _("character device %s is not using a PTY"),
18547 dev_name
? dev_name
: NULLSTR(chr
->info
.alias
));
18551 /* handle mutually exclusive access to console devices */
18552 ret
= virChrdevOpen(priv
->devs
,
18555 (flags
& VIR_DOMAIN_CONSOLE_FORCE
) != 0);
18558 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
18559 _("Active console session exists for this domain"));
18564 virDomainObjEndAPI(&vm
);
18569 qemuDomainOpenChannel(virDomainPtr dom
,
18572 unsigned int flags
)
18574 virDomainObjPtr vm
= NULL
;
18577 virDomainChrDefPtr chr
= NULL
;
18578 qemuDomainObjPrivatePtr priv
;
18580 virCheckFlags(VIR_DOMAIN_CHANNEL_FORCE
, -1);
18582 if (!(vm
= qemuDomObjFromDomain(dom
)))
18585 if (virDomainOpenChannelEnsureACL(dom
->conn
, vm
->def
) < 0)
18588 if (virDomainObjCheckActive(vm
) < 0)
18591 priv
= vm
->privateData
;
18594 for (i
= 0; !chr
&& i
< vm
->def
->nchannels
; i
++) {
18595 if (STREQ(name
, vm
->def
->channels
[i
]->info
.alias
))
18596 chr
= vm
->def
->channels
[i
];
18598 if (vm
->def
->channels
[i
]->targetType
== \
18599 VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO
&&
18600 STREQ_NULLABLE(name
, vm
->def
->channels
[i
]->target
.name
))
18601 chr
= vm
->def
->channels
[i
];
18604 if (vm
->def
->nchannels
)
18605 chr
= vm
->def
->channels
[0];
18609 virReportError(VIR_ERR_INTERNAL_ERROR
,
18610 _("cannot find channel %s"),
18615 if (chr
->source
->type
!= VIR_DOMAIN_CHR_TYPE_UNIX
) {
18616 virReportError(VIR_ERR_INTERNAL_ERROR
,
18617 _("channel %s is not using a UNIX socket"),
18618 name
? name
: NULLSTR(chr
->info
.alias
));
18622 /* handle mutually exclusive access to channel devices */
18623 ret
= virChrdevOpen(priv
->devs
,
18626 (flags
& VIR_DOMAIN_CHANNEL_FORCE
) != 0);
18629 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
18630 _("Active channel stream exists for this domain"));
18635 virDomainObjEndAPI(&vm
);
18640 /* Called while holding the VM job lock, to implement a block job
18641 * abort with pivot; this updates the VM definition as appropriate, on
18642 * either success or failure. */
18644 qemuDomainBlockPivot(virQEMUDriverPtr driver
,
18645 virDomainObjPtr vm
,
18646 qemuBlockJobDataPtr job
,
18647 virDomainDiskDefPtr disk
)
18650 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
18652 if (!disk
->mirror
) {
18653 virReportError(VIR_ERR_OPERATION_INVALID
,
18654 _("pivot of disk '%s' requires an active copy job"),
18659 if (disk
->mirrorState
!= VIR_DOMAIN_DISK_MIRROR_STATE_READY
) {
18660 virReportError(VIR_ERR_BLOCK_COPY_ACTIVE
,
18661 _("disk '%s' not ready for pivot yet"),
18666 /* Attempt the pivot. Record the attempt now, to prevent duplicate
18667 * attempts; but the actual disk change will be made when emitting
18669 * XXX On libvirtd restarts, if we missed the qemu event, we need
18670 * to double check what state qemu is in.
18671 * XXX We should be using qemu's rerror flag to make sure the job
18672 * remains alive until we know its final state.
18673 * XXX If the abort command is synchronous but the qemu event says
18674 * that pivot failed, we need to reflect that failure into the
18675 * overall return value. */
18676 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT
;
18677 qemuDomainObjEnterMonitor(driver
, vm
);
18678 ret
= qemuMonitorDrivePivot(priv
->mon
, job
->name
);
18679 if (qemuDomainObjExitMonitor(driver
, vm
) < 0) {
18685 /* The pivot failed. The block job in QEMU remains in the synchronised
18686 * phase. Reset the state we changed and return the error to the user */
18687 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_READY
;
18695 /* bandwidth in MiB/s per public API. Caller must lock vm beforehand,
18696 * and not access it afterwards. */
18698 qemuDomainBlockPullCommon(virQEMUDriverPtr driver
,
18699 virDomainObjPtr vm
,
18702 unsigned long bandwidth
,
18703 unsigned int flags
)
18705 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
18706 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
18707 char *device
= NULL
;
18708 virDomainDiskDefPtr disk
;
18709 virStorageSourcePtr baseSource
= NULL
;
18710 unsigned int baseIndex
= 0;
18711 char *basePath
= NULL
;
18712 char *backingPath
= NULL
;
18713 unsigned long long speed
= bandwidth
;
18714 qemuBlockJobDataPtr job
= NULL
;
18717 if (flags
& VIR_DOMAIN_BLOCK_REBASE_RELATIVE
&& !base
) {
18718 virReportError(VIR_ERR_INVALID_ARG
, "%s",
18719 _("flag VIR_DOMAIN_BLOCK_REBASE_RELATIVE is valid only "
18720 "with non-null base"));
18724 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
18727 if (virDomainObjCheckActive(vm
) < 0)
18730 if (qemuDomainSupportsBlockJobs(vm
) < 0)
18733 if (!(disk
= qemuDomainDiskByName(vm
->def
, path
)))
18736 if (!(device
= qemuAliasDiskDriveFromDisk(disk
)))
18739 if (qemuDomainDiskBlockJobIsActive(disk
))
18743 (virStorageFileParseChainIndex(disk
->dst
, base
, &baseIndex
) < 0 ||
18744 !(baseSource
= virStorageFileChainLookup(disk
->src
, disk
->src
,
18745 base
, baseIndex
, NULL
))))
18749 if (flags
& VIR_DOMAIN_BLOCK_REBASE_RELATIVE
) {
18750 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_CHANGE_BACKING_FILE
)) {
18751 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
18752 _("this QEMU binary doesn't support relative "
18753 "block pull/rebase"));
18757 if (virStorageFileGetRelativeBackingPath(disk
->src
->backingStore
,
18762 if (!backingPath
) {
18763 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
18764 _("can't keep relative backing relationship"));
18770 /* Convert bandwidth MiB to bytes, if needed */
18771 if (!(flags
& VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES
)) {
18772 if (speed
> LLONG_MAX
>> 20) {
18773 virReportError(VIR_ERR_OVERFLOW
,
18774 _("bandwidth must be less than %llu"),
18781 if (!(job
= qemuBlockJobDiskNew(disk
, QEMU_BLOCKJOB_TYPE_PULL
, device
)))
18784 qemuDomainObjEnterMonitor(driver
, vm
);
18786 basePath
= qemuMonitorDiskNameLookup(priv
->mon
, device
, disk
->src
,
18788 if (!baseSource
|| basePath
)
18789 ret
= qemuMonitorBlockStream(priv
->mon
, device
, basePath
, backingPath
,
18791 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
18797 qemuBlockJobStarted(job
);
18799 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
18800 VIR_WARN("Unable to save status on vm %s after state change",
18804 qemuDomainObjEndJob(driver
, vm
);
18807 qemuBlockJobStartupFinalize(job
);
18808 virObjectUnref(cfg
);
18809 VIR_FREE(basePath
);
18810 VIR_FREE(backingPath
);
18812 virDomainObjEndAPI(&vm
);
18818 qemuDomainBlockJobAbort(virDomainPtr dom
,
18820 unsigned int flags
)
18822 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
18823 virDomainDiskDefPtr disk
= NULL
;
18824 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
18825 bool pivot
= !!(flags
& VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT
);
18826 bool async
= !!(flags
& VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC
);
18827 qemuBlockJobDataPtr job
= NULL
;
18828 virDomainObjPtr vm
;
18831 virCheckFlags(VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC
|
18832 VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT
, -1);
18834 if (!(vm
= qemuDomObjFromDomain(dom
)))
18837 if (virDomainBlockJobAbortEnsureACL(dom
->conn
, vm
->def
) < 0)
18840 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
18843 if (virDomainObjCheckActive(vm
) < 0)
18846 if (qemuDomainSupportsBlockJobs(vm
) < 0)
18849 if (!(disk
= qemuDomainDiskByName(vm
->def
, path
)))
18852 if (!(job
= qemuBlockJobDiskGetJob(disk
))) {
18853 virReportError(VIR_ERR_INVALID_ARG
,
18854 _("disk %s does not have an active block job"), disk
->dst
);
18858 if (disk
->mirrorState
!= VIR_DOMAIN_DISK_MIRROR_STATE_NONE
&&
18859 disk
->mirrorState
!= VIR_DOMAIN_DISK_MIRROR_STATE_READY
) {
18860 virReportError(VIR_ERR_OPERATION_INVALID
,
18861 _("another job on disk '%s' is still being ended"),
18867 qemuBlockJobSyncBegin(job
);
18870 if ((ret
= qemuDomainBlockPivot(driver
, vm
, job
, disk
)) < 0)
18874 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_ABORT
;
18876 qemuDomainObjEnterMonitor(driver
, vm
);
18877 ret
= qemuMonitorBlockJobCancel(qemuDomainGetMonitor(vm
), job
->name
);
18878 if (qemuDomainObjExitMonitor(driver
, vm
) < 0) {
18885 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_NONE
;
18890 ignore_value(virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
));
18893 * With the ABORT_ASYNC flag we don't need to do anything, the event will
18894 * come from qemu and will update the XML as appropriate, but without the
18895 * ABORT_ASYNC flag, we must block to guarantee synchronous operation. We
18896 * do the waiting while still holding the VM job, to prevent newly
18897 * scheduled block jobs from confusing us. */
18899 qemuBlockJobUpdate(vm
, job
, QEMU_ASYNC_JOB_NONE
);
18900 while (qemuBlockJobIsRunning(job
)) {
18901 if (virDomainObjWait(vm
) < 0) {
18905 qemuBlockJobUpdate(vm
, job
, QEMU_ASYNC_JOB_NONE
);
18911 qemuBlockJobSyncEnd(vm
, job
, QEMU_ASYNC_JOB_NONE
);
18912 qemuDomainObjEndJob(driver
, vm
);
18915 virObjectUnref(job
);
18916 virObjectUnref(cfg
);
18917 virDomainObjEndAPI(&vm
);
18923 qemuBlockJobInfoTranslate(qemuMonitorBlockJobInfoPtr rawInfo
,
18924 virDomainBlockJobInfoPtr info
,
18925 virDomainDiskDefPtr disk
,
18928 info
->cur
= rawInfo
->cur
;
18929 info
->end
= rawInfo
->end
;
18931 /* Fix job completeness reporting. If cur == end mgmt
18932 * applications think job is completed. Except when both cur
18933 * and end are zero, in which case qemu hasn't started the
18935 if (!info
->cur
&& !info
->end
) {
18936 if (rawInfo
->ready
> 0) {
18937 info
->cur
= info
->end
= 1;
18938 } else if (!rawInfo
->ready
) {
18943 /* If qemu reports that it's not ready yet don't make the job go to
18944 * cur == end as some apps wrote code polling this instead of waiting for
18945 * the ready event */
18946 if (rawInfo
->ready
== 0 &&
18947 info
->cur
== info
->end
&&
18951 info
->type
= rawInfo
->type
;
18952 if (info
->type
== VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT
&&
18953 disk
->mirrorJob
== VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT
)
18954 info
->type
= disk
->mirrorJob
;
18956 if (rawInfo
->bandwidth
&& !reportBytes
)
18957 rawInfo
->bandwidth
= VIR_DIV_UP(rawInfo
->bandwidth
, 1024 * 1024);
18958 info
->bandwidth
= rawInfo
->bandwidth
;
18959 if (info
->bandwidth
!= rawInfo
->bandwidth
) {
18960 virReportError(VIR_ERR_OVERFLOW
,
18961 _("bandwidth %llu cannot be represented in result"),
18962 rawInfo
->bandwidth
);
18971 qemuDomainGetBlockJobInfo(virDomainPtr dom
,
18973 virDomainBlockJobInfoPtr info
,
18974 unsigned int flags
)
18976 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
18977 virDomainObjPtr vm
;
18978 virDomainDiskDefPtr disk
;
18980 qemuMonitorBlockJobInfo rawInfo
;
18982 virCheckFlags(VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES
, -1);
18984 if (!(vm
= qemuDomObjFromDomain(dom
)))
18987 if (virDomainGetBlockJobInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
18991 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
18994 if (virDomainObjCheckActive(vm
) < 0)
18997 if (qemuDomainSupportsBlockJobs(vm
) < 0)
19000 if (!(disk
= virDomainDiskByName(vm
->def
, path
, true))) {
19001 virReportError(VIR_ERR_INVALID_ARG
,
19002 _("disk %s not found in the domain"), path
);
19006 qemuDomainObjEnterMonitor(driver
, vm
);
19007 ret
= qemuMonitorGetBlockJobInfo(qemuDomainGetMonitor(vm
),
19008 disk
->info
.alias
, &rawInfo
);
19009 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
19014 if (qemuBlockJobInfoTranslate(&rawInfo
, info
, disk
,
19015 flags
& VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES
) < 0) {
19020 /* Snoop block copy operations, so future cancel operations can
19021 * avoid checking if pivot is safe. Save the change to XML, but
19022 * we can ignore failure because it is only an optimization. We
19023 * hold the vm lock, so modifying the in-memory representation is
19024 * safe, even if we are a query rather than a modify job. */
19025 if (disk
->mirror
&&
19026 rawInfo
.ready
!= 0 &&
19027 info
->cur
== info
->end
&& !disk
->mirrorState
) {
19028 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
19030 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_READY
;
19031 ignore_value(virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
));
19032 virObjectUnref(cfg
);
19035 qemuDomainObjEndJob(driver
, vm
);
19038 virDomainObjEndAPI(&vm
);
19044 qemuDomainBlockJobSetSpeed(virDomainPtr dom
,
19046 unsigned long bandwidth
,
19047 unsigned int flags
)
19049 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19050 virDomainDiskDefPtr disk
;
19052 virDomainObjPtr vm
;
19053 char *device
= NULL
;
19054 unsigned long long speed
= bandwidth
;
19056 virCheckFlags(VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES
, -1);
19058 /* Convert bandwidth MiB to bytes, if needed */
19059 if (!(flags
& VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES
)) {
19060 if (speed
> LLONG_MAX
>> 20) {
19061 virReportError(VIR_ERR_OVERFLOW
,
19062 _("bandwidth must be less than %llu"),
19069 if (!(vm
= qemuDomObjFromDomain(dom
)))
19072 if (virDomainBlockJobSetSpeedEnsureACL(dom
->conn
, vm
->def
) < 0)
19075 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
19078 if (virDomainObjCheckActive(vm
) < 0)
19081 if (qemuDomainSupportsBlockJobs(vm
) < 0)
19084 if (!(disk
= qemuDomainDiskByName(vm
->def
, path
)))
19087 if (!(device
= qemuAliasDiskDriveFromDisk(disk
)))
19090 qemuDomainObjEnterMonitor(driver
, vm
);
19091 ret
= qemuMonitorBlockJobSetSpeed(qemuDomainGetMonitor(vm
),
19094 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
19098 qemuDomainObjEndJob(driver
, vm
);
19102 virDomainObjEndAPI(&vm
);
19109 qemuDomainBlockCopyValidateMirror(virStorageSourcePtr mirror
,
19113 int desttype
= virStorageSourceGetActualType(mirror
);
19116 if (virStorageFileAccess(mirror
, F_OK
) < 0) {
19117 if (errno
!= ENOENT
) {
19118 virReportSystemError(errno
, "%s",
19119 _("unable to verify existence of "
19120 "block copy target"));
19124 if (*reuse
|| desttype
== VIR_STORAGE_TYPE_BLOCK
) {
19125 virReportSystemError(errno
,
19126 _("missing destination file for disk %s: %s"),
19127 dst
, mirror
->path
);
19131 if (virStorageFileStat(mirror
, &st
) < 0) {
19132 virReportSystemError(errno
,
19133 _("unable to stat block copy target '%s'"),
19138 if (S_ISBLK(st
.st_mode
)) {
19139 /* if the target is a block device, assume that we are reusing it,
19140 * so there are no attempts to create it */
19143 if (st
.st_size
&& !(*reuse
)) {
19144 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
19145 _("external destination file for disk %s already "
19146 "exists and is not a block device: %s"),
19147 dst
, mirror
->path
);
19151 if (desttype
== VIR_STORAGE_TYPE_BLOCK
) {
19152 virReportError(VIR_ERR_INVALID_ARG
,
19153 _("blockdev flag requested for disk %s, but file "
19154 "'%s' is not a block device"),
19155 dst
, mirror
->path
);
19165 /* bandwidth in bytes/s. Caller must lock vm beforehand, and not
19166 * access mirror afterwards. */
19168 qemuDomainBlockCopyCommon(virDomainObjPtr vm
,
19169 virConnectPtr conn
,
19171 virStorageSourcePtr mirror
,
19172 unsigned long long bandwidth
,
19173 unsigned int granularity
,
19174 unsigned long long buf_size
,
19175 unsigned int flags
,
19176 bool keepParentLabel
)
19178 virQEMUDriverPtr driver
= conn
->privateData
;
19179 qemuDomainObjPrivatePtr priv
;
19180 char *device
= NULL
;
19181 virDomainDiskDefPtr disk
= NULL
;
19183 bool need_unlink
= false;
19184 virQEMUDriverConfigPtr cfg
= NULL
;
19185 const char *format
= NULL
;
19186 virErrorPtr monitor_error
= NULL
;
19187 bool reuse
= !!(flags
& VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
);
19188 qemuBlockJobDataPtr job
= NULL
;
19190 /* Preliminaries: find the disk we are editing, sanity checks */
19191 virCheckFlags(VIR_DOMAIN_BLOCK_COPY_SHALLOW
|
19192 VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
|
19193 VIR_DOMAIN_BLOCK_COPY_TRANSIENT_JOB
, -1);
19195 priv
= vm
->privateData
;
19196 cfg
= virQEMUDriverGetConfig(driver
);
19198 if (virStorageSourceIsRelative(mirror
)) {
19199 virReportError(VIR_ERR_INVALID_ARG
, "%s",
19200 _("absolute path must be used as block copy target"));
19204 if (bandwidth
> LLONG_MAX
) {
19205 virReportError(VIR_ERR_INVALID_ARG
,
19206 _("bandwidth must be less than "
19207 "'%llu' bytes/s (%llu MiB/s)"),
19208 LLONG_MAX
, LLONG_MAX
>> 20);
19212 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
19215 if (virDomainObjCheckActive(vm
) < 0)
19218 if (!(disk
= qemuDomainDiskByName(vm
->def
, path
)))
19221 if (!(device
= qemuAliasDiskDriveFromDisk(disk
)))
19224 if (qemuDomainDiskBlockJobIsActive(disk
))
19227 if (disk
->device
== VIR_DOMAIN_DISK_DEVICE_LUN
&&
19228 qemuDomainDefValidateDiskLunSource(mirror
) < 0)
19231 if (!(virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DRIVE_MIRROR
) &&
19232 virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKJOB_ASYNC
))) {
19233 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
19234 _("block copy is not supported with this QEMU binary"));
19237 if (!(flags
& VIR_DOMAIN_BLOCK_COPY_TRANSIENT_JOB
) &&
19239 /* XXX if qemu ever lets us start a new domain with mirroring
19240 * already active, we can relax this; but for now, the risk of
19241 * 'managedsave' due to libvirt-guests means we can't risk
19242 * this on persistent domains. */
19243 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
19244 _("domain is not transient"));
19248 /* clear the _SHALLOW flag if there is only one layer */
19249 if (!virStorageSourceHasBacking(disk
->src
))
19250 flags
&= ~VIR_DOMAIN_BLOCK_COPY_SHALLOW
;
19252 /* unless the user provides a pre-created file, shallow copy into a raw
19253 * file is not possible */
19254 if ((flags
& VIR_DOMAIN_BLOCK_COPY_SHALLOW
) && !reuse
&&
19255 mirror
->format
== VIR_STORAGE_FILE_RAW
) {
19256 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
19257 _("shallow copy of disk '%s' into a raw file "
19258 "is not possible"),
19263 /* Prepare the destination file. */
19264 /* XXX Allow non-file mirror destinations */
19265 if (!virStorageSourceIsLocalStorage(mirror
)) {
19266 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
19267 _("non-file destination not supported yet"));
19271 if (qemuDomainStorageFileInit(driver
, vm
, mirror
, NULL
) < 0)
19274 if (qemuDomainBlockCopyValidateMirror(mirror
, disk
->dst
, &reuse
) < 0)
19277 if (!mirror
->format
) {
19278 if (!(flags
& VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
)) {
19279 mirror
->format
= disk
->src
->format
;
19281 /* If the user passed the REUSE_EXT flag, then either they
19282 * can also pass the RAW flag or use XML to tell us the format.
19283 * So if we get here, we assume it is safe for us to probe the
19284 * format from the file that we will be using. */
19285 mirror
->format
= virStorageFileProbeFormat(mirror
->path
, cfg
->user
,
19290 /* When copying a shareable disk we need to make sure that the disk can
19291 * be safely shared, since block copy may change the format. */
19292 if (disk
->src
->shared
&& !disk
->src
->readonly
&&
19293 !qemuBlockStorageSourceSupportsConcurrentAccess(mirror
)) {
19294 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
19295 _("can't pivot a shared disk to a storage volume not "
19296 "supporting sharing"));
19300 /* pre-create the image file */
19302 if (virStorageFileCreate(mirror
) < 0) {
19303 virReportSystemError(errno
, "%s", _("failed to create copy target"));
19307 need_unlink
= true;
19310 if (mirror
->format
> 0)
19311 format
= virStorageFileFormatTypeToString(mirror
->format
);
19313 if (virStorageSourceInitChainElement(mirror
, disk
->src
,
19314 keepParentLabel
) < 0)
19317 /* If reusing an external image that includes a backing file, the pivot may
19318 * result in qemu needing to open the entire backing chain, so we need to
19319 * label the full backing chain of the mirror instead of just the top image */
19320 if (flags
& VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
&&
19321 mirror
->format
>= VIR_STORAGE_FILE_BACKING
&&
19322 qemuDomainDetermineDiskChain(driver
, vm
, disk
, mirror
, true) < 0)
19325 if (flags
& VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
&&
19326 virStorageSourceHasBacking(mirror
)) {
19327 /* note that we don't really know whether a part of the backing chain
19328 * is shared so rolling this back is not as easy. Thus we do it only
19329 * if there's a backing chain */
19330 if (qemuDomainNamespaceSetupDisk(vm
, mirror
) < 0 ||
19331 qemuSetupImageChainCgroup(vm
, mirror
) < 0 ||
19332 qemuSecuritySetImageLabel(driver
, vm
, mirror
, true) < 0)
19335 if (qemuDomainDiskChainElementPrepare(driver
, vm
, mirror
, false, true) < 0) {
19336 qemuDomainDiskChainElementRevoke(driver
, vm
, mirror
);
19341 if (!(job
= qemuBlockJobDiskNew(disk
, QEMU_BLOCKJOB_TYPE_COPY
, device
)))
19344 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_NONE
;
19346 /* Actually start the mirroring */
19347 qemuDomainObjEnterMonitor(driver
, vm
);
19348 /* qemuMonitorDriveMirror needs to honor the REUSE_EXT flag as specified
19349 * by the user regardless of how @reuse was modified */
19350 ret
= qemuMonitorDriveMirror(priv
->mon
, device
, mirror
->path
, format
,
19351 bandwidth
, granularity
, buf_size
, flags
);
19352 virDomainAuditDisk(vm
, NULL
, mirror
, "mirror", ret
>= 0);
19353 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
19356 monitor_error
= virSaveLastError();
19357 qemuDomainDiskChainElementRevoke(driver
, vm
, mirror
);
19361 /* Update vm in place to match changes. */
19362 qemuBlockJobStarted(job
);
19363 need_unlink
= false;
19364 virStorageFileDeinit(mirror
);
19365 disk
->mirror
= mirror
;
19367 disk
->mirrorJob
= VIR_DOMAIN_BLOCK_JOB_TYPE_COPY
;
19369 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
19370 VIR_WARN("Unable to save status on vm %s after state change",
19374 if (need_unlink
&& virStorageFileUnlink(mirror
) < 0)
19375 VIR_WARN("%s", _("unable to remove just-created copy target"));
19376 virStorageFileDeinit(mirror
);
19377 qemuDomainObjEndJob(driver
, vm
);
19378 if (monitor_error
) {
19379 virSetError(monitor_error
);
19380 virFreeError(monitor_error
);
19382 qemuBlockJobStartupFinalize(job
);
19386 virObjectUnref(cfg
);
19387 virObjectUnref(mirror
);
19392 qemuDomainBlockRebase(virDomainPtr dom
, const char *path
, const char *base
,
19393 unsigned long bandwidth
, unsigned int flags
)
19395 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19396 virDomainObjPtr vm
;
19398 unsigned long long speed
= bandwidth
;
19399 VIR_AUTOUNREF(virStorageSourcePtr
) dest
= NULL
;
19401 virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW
|
19402 VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT
|
19403 VIR_DOMAIN_BLOCK_REBASE_COPY
|
19404 VIR_DOMAIN_BLOCK_REBASE_COPY_RAW
|
19405 VIR_DOMAIN_BLOCK_REBASE_RELATIVE
|
19406 VIR_DOMAIN_BLOCK_REBASE_COPY_DEV
|
19407 VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES
, -1);
19409 if (!(vm
= qemuDomObjFromDomain(dom
)))
19412 if (virDomainBlockRebaseEnsureACL(dom
->conn
, vm
->def
) < 0)
19415 /* For normal rebase (enhanced blockpull), the common code handles
19416 * everything, including vm cleanup. */
19417 if (!(flags
& VIR_DOMAIN_BLOCK_REBASE_COPY
))
19418 return qemuDomainBlockPullCommon(driver
, vm
, path
, base
, bandwidth
, flags
);
19420 /* If we got here, we are doing a block copy rebase. */
19421 if (!(dest
= virStorageSourceNew()))
19423 dest
->type
= (flags
& VIR_DOMAIN_BLOCK_REBASE_COPY_DEV
) ?
19424 VIR_STORAGE_TYPE_BLOCK
: VIR_STORAGE_TYPE_FILE
;
19425 if (VIR_STRDUP(dest
->path
, base
) < 0)
19427 if (flags
& VIR_DOMAIN_BLOCK_REBASE_COPY_RAW
)
19428 dest
->format
= VIR_STORAGE_FILE_RAW
;
19430 /* Convert bandwidth MiB to bytes, if necessary */
19431 if (!(flags
& VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES
)) {
19432 if (speed
> LLONG_MAX
>> 20) {
19433 virReportError(VIR_ERR_OVERFLOW
,
19434 _("bandwidth must be less than %llu"),
19441 /* XXX: If we are doing a shallow copy but not reusing an external
19442 * file, we should attempt to pre-create the destination with a
19443 * relative backing chain instead of qemu's default of absolute */
19444 if (flags
& VIR_DOMAIN_BLOCK_REBASE_RELATIVE
) {
19445 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
19446 _("Relative backing during copy not supported yet"));
19450 /* We rely on the fact that VIR_DOMAIN_BLOCK_REBASE_SHALLOW
19451 * and VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT map to the same values
19452 * as for block copy. */
19453 flags
&= (VIR_DOMAIN_BLOCK_REBASE_SHALLOW
|
19454 VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT
);
19455 ret
= qemuDomainBlockCopyCommon(vm
, dom
->conn
, path
, dest
,
19456 speed
, 0, 0, flags
, true);
19460 virDomainObjEndAPI(&vm
);
19466 qemuDomainBlockCopy(virDomainPtr dom
, const char *disk
, const char *destxml
,
19467 virTypedParameterPtr params
, int nparams
,
19468 unsigned int flags
)
19470 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19471 virDomainObjPtr vm
;
19473 unsigned long long bandwidth
= 0;
19474 unsigned int granularity
= 0;
19475 unsigned long long buf_size
= 0;
19476 virDomainDiskDefPtr diskdef
= NULL
;
19477 virStorageSourcePtr dest
= NULL
;
19480 virCheckFlags(VIR_DOMAIN_BLOCK_COPY_SHALLOW
|
19481 VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
|
19482 VIR_DOMAIN_BLOCK_COPY_TRANSIENT_JOB
, -1);
19483 if (virTypedParamsValidate(params
, nparams
,
19484 VIR_DOMAIN_BLOCK_COPY_BANDWIDTH
,
19485 VIR_TYPED_PARAM_ULLONG
,
19486 VIR_DOMAIN_BLOCK_COPY_GRANULARITY
,
19487 VIR_TYPED_PARAM_UINT
,
19488 VIR_DOMAIN_BLOCK_COPY_BUF_SIZE
,
19489 VIR_TYPED_PARAM_ULLONG
,
19493 if (!(vm
= qemuDomObjFromDomain(dom
)))
19496 if (virDomainBlockCopyEnsureACL(dom
->conn
, vm
->def
) < 0)
19499 for (i
= 0; i
< nparams
; i
++) {
19500 virTypedParameterPtr param
= ¶ms
[i
];
19502 /* Typed params (wisely) refused to expose unsigned long, but
19503 * back-compat demands that we stick with a maximum of
19504 * unsigned long bandwidth in MiB/s, while our value is
19505 * unsigned long long in bytes/s. Hence, we have to do
19506 * overflow detection if this is a 32-bit server handling a
19507 * 64-bit client. */
19508 if (STREQ(param
->field
, VIR_DOMAIN_BLOCK_COPY_BANDWIDTH
)) {
19509 if (sizeof(unsigned long)< sizeof(bandwidth
) &&
19510 param
->value
.ul
> ULONG_MAX
* (1ULL << 20)) {
19511 virReportError(VIR_ERR_OVERFLOW
,
19512 _("bandwidth must be less than %llu bytes"),
19513 ULONG_MAX
* (1ULL << 20));
19516 bandwidth
= param
->value
.ul
;
19517 } else if (STREQ(param
->field
, VIR_DOMAIN_BLOCK_COPY_GRANULARITY
)) {
19518 if (param
->value
.ui
!= VIR_ROUND_UP_POWER_OF_TWO(param
->value
.ui
)) {
19519 virReportError(VIR_ERR_INVALID_ARG
, "%s",
19520 _("granularity must be power of 2"));
19523 granularity
= param
->value
.ui
;
19524 } else if (STREQ(param
->field
, VIR_DOMAIN_BLOCK_COPY_BUF_SIZE
)) {
19525 buf_size
= param
->value
.ul
;
19529 if (!(diskdef
= virDomainDiskDefParse(destxml
, vm
->def
, driver
->xmlopt
,
19530 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
19531 VIR_DOMAIN_DEF_PARSE_DISK_SOURCE
)))
19534 VIR_STEAL_PTR(dest
, diskdef
->src
);
19536 ret
= qemuDomainBlockCopyCommon(vm
, dom
->conn
, disk
, dest
, bandwidth
,
19537 granularity
, buf_size
, flags
, false);
19540 virDomainDiskDefFree(diskdef
);
19541 virDomainObjEndAPI(&vm
);
19547 qemuDomainBlockPull(virDomainPtr dom
, const char *path
, unsigned long bandwidth
,
19548 unsigned int flags
)
19550 virDomainObjPtr vm
;
19551 virCheckFlags(VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES
, -1);
19553 if (!(vm
= qemuDomObjFromDomain(dom
)))
19556 if (virDomainBlockPullEnsureACL(dom
->conn
, vm
->def
) < 0) {
19557 virDomainObjEndAPI(&vm
);
19561 return qemuDomainBlockPullCommon(dom
->conn
->privateData
,
19562 vm
, path
, NULL
, bandwidth
, flags
);
19567 qemuDomainBlockCommit(virDomainPtr dom
,
19571 unsigned long bandwidth
,
19572 unsigned int flags
)
19574 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19575 virQEMUDriverConfigPtr cfg
= NULL
;
19576 qemuDomainObjPrivatePtr priv
;
19577 virDomainObjPtr vm
= NULL
;
19578 char *device
= NULL
;
19580 virDomainDiskDefPtr disk
= NULL
;
19581 virStorageSourcePtr topSource
;
19582 unsigned int topIndex
= 0;
19583 virStorageSourcePtr baseSource
= NULL
;
19584 unsigned int baseIndex
= 0;
19585 virStorageSourcePtr top_parent
= NULL
;
19586 bool clean_access
= false;
19587 char *topPath
= NULL
;
19588 char *basePath
= NULL
;
19589 char *backingPath
= NULL
;
19590 unsigned long long speed
= bandwidth
;
19591 qemuBlockJobDataPtr job
= NULL
;
19592 qemuBlockJobType jobtype
= QEMU_BLOCKJOB_TYPE_COMMIT
;
19593 VIR_AUTOUNREF(virStorageSourcePtr
) mirror
= NULL
;
19595 /* XXX Add support for COMMIT_DELETE */
19596 virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW
|
19597 VIR_DOMAIN_BLOCK_COMMIT_ACTIVE
|
19598 VIR_DOMAIN_BLOCK_COMMIT_RELATIVE
|
19599 VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES
, -1);
19601 if (!(vm
= qemuDomObjFromDomain(dom
)))
19603 priv
= vm
->privateData
;
19604 cfg
= virQEMUDriverGetConfig(driver
);
19606 if (virDomainBlockCommitEnsureACL(dom
->conn
, vm
->def
) < 0)
19609 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
19612 if (virDomainObjCheckActive(vm
) < 0)
19614 /* Ensure that no one backports commit to RHEL 6.2, where cancel
19615 * behaved differently */
19616 if (!(virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCK_COMMIT
) &&
19617 virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKJOB_ASYNC
))) {
19618 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
19619 _("online commit not supported with this QEMU binary"));
19623 /* Convert bandwidth MiB to bytes, if necessary */
19624 if (!(flags
& VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES
)) {
19625 if (speed
> LLONG_MAX
>> 20) {
19626 virReportError(VIR_ERR_OVERFLOW
,
19627 _("bandwidth must be less than %llu"),
19634 if (!(disk
= qemuDomainDiskByName(vm
->def
, path
)))
19637 if (!(device
= qemuAliasDiskDriveFromDisk(disk
)))
19640 if (!disk
->src
->path
) {
19641 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
19642 _("disk %s has no source file to be committed"),
19647 if (qemuDomainDiskBlockJobIsActive(disk
))
19650 if (!top
|| STREQ(top
, disk
->dst
))
19651 topSource
= disk
->src
;
19652 else if (virStorageFileParseChainIndex(disk
->dst
, top
, &topIndex
) < 0 ||
19653 !(topSource
= virStorageFileChainLookup(disk
->src
, NULL
,
19658 if (topSource
== disk
->src
) {
19659 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_ACTIVE_COMMIT
)) {
19660 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
19661 _("active commit not supported with this QEMU binary"));
19664 /* XXX Should we auto-pivot when COMMIT_ACTIVE is not specified? */
19665 if (!(flags
& VIR_DOMAIN_BLOCK_COMMIT_ACTIVE
)) {
19666 virReportError(VIR_ERR_INVALID_ARG
,
19667 _("commit of '%s' active layer requires active flag"),
19672 jobtype
= QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT
;
19673 } else if (flags
& VIR_DOMAIN_BLOCK_COMMIT_ACTIVE
) {
19674 virReportError(VIR_ERR_INVALID_ARG
,
19675 _("active commit requested but '%s' is not active"),
19680 if (!virStorageSourceHasBacking(topSource
)) {
19681 virReportError(VIR_ERR_INVALID_ARG
,
19682 _("top '%s' in chain for '%s' has no backing file"),
19683 topSource
->path
, path
);
19687 if (!base
&& (flags
& VIR_DOMAIN_BLOCK_COMMIT_SHALLOW
))
19688 baseSource
= topSource
->backingStore
;
19689 else if (virStorageFileParseChainIndex(disk
->dst
, base
, &baseIndex
) < 0 ||
19690 !(baseSource
= virStorageFileChainLookup(disk
->src
, topSource
,
19691 base
, baseIndex
, NULL
)))
19694 if ((flags
& VIR_DOMAIN_BLOCK_COMMIT_SHALLOW
) &&
19695 baseSource
!= topSource
->backingStore
) {
19696 virReportError(VIR_ERR_INVALID_ARG
,
19697 _("base '%s' is not immediately below '%s' in chain "
19699 base
, topSource
->path
, path
);
19703 /* For an active commit, clone enough of the base to act as the mirror */
19704 if (topSource
== disk
->src
) {
19705 if (!(mirror
= virStorageSourceCopy(baseSource
, false)))
19707 if (virStorageSourceInitChainElement(mirror
,
19713 if (flags
& VIR_DOMAIN_BLOCK_COMMIT_RELATIVE
&&
19714 topSource
!= disk
->src
) {
19715 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_CHANGE_BACKING_FILE
)) {
19716 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
19717 _("this qemu doesn't support relative block commit"));
19721 if (virStorageFileGetRelativeBackingPath(topSource
, baseSource
,
19725 if (!backingPath
) {
19726 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
19727 _("can't keep relative backing relationship"));
19732 /* For the commit to succeed, we must allow qemu to open both the
19733 * 'base' image and the parent of 'top' as read/write; 'top' might
19734 * not have a parent, or might already be read-write. XXX It
19735 * would also be nice to revert 'base' to read-only, as well as
19736 * revoke access to files removed from the chain, when the commit
19737 * operation succeeds, but doing that requires tracking the
19738 * operation in XML across libvirtd restarts. */
19739 clean_access
= true;
19740 if (qemuDomainDiskChainElementPrepare(driver
, vm
, baseSource
, false, false) < 0 ||
19741 (top_parent
&& top_parent
!= disk
->src
&&
19742 qemuDomainDiskChainElementPrepare(driver
, vm
, top_parent
, false, false) < 0))
19745 if (!(job
= qemuBlockJobDiskNew(disk
, jobtype
, device
)))
19748 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_NONE
;
19750 /* Start the commit operation. Pass the user's original spelling,
19751 * if any, through to qemu, since qemu may behave differently
19752 * depending on whether the input was specified as relative or
19753 * absolute (that is, our absolute top_canon may do the wrong
19754 * thing if the user specified a relative name). */
19755 qemuDomainObjEnterMonitor(driver
, vm
);
19756 basePath
= qemuMonitorDiskNameLookup(priv
->mon
, device
, disk
->src
,
19758 topPath
= qemuMonitorDiskNameLookup(priv
->mon
, device
, disk
->src
,
19760 if (basePath
&& topPath
)
19761 ret
= qemuMonitorBlockCommit(priv
->mon
, device
,
19762 topPath
, basePath
, backingPath
,
19764 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || ret
< 0) {
19769 qemuBlockJobStarted(job
);
19771 VIR_STEAL_PTR(disk
->mirror
, mirror
);
19772 disk
->mirrorJob
= VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT
;
19775 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
19776 VIR_WARN("Unable to save status on vm %s after block job",
19780 if (ret
< 0 && clean_access
) {
19781 virErrorPtr orig_err
= virSaveLastError();
19782 /* Revert access to read-only, if possible. */
19783 qemuDomainDiskChainElementPrepare(driver
, vm
, baseSource
, true, false);
19784 if (top_parent
&& top_parent
!= disk
->src
)
19785 qemuDomainDiskChainElementPrepare(driver
, vm
, top_parent
, true, false);
19788 virSetError(orig_err
);
19789 virFreeError(orig_err
);
19792 qemuBlockJobStartupFinalize(job
);
19793 qemuDomainObjEndJob(driver
, vm
);
19797 VIR_FREE(basePath
);
19798 VIR_FREE(backingPath
);
19800 virObjectUnref(cfg
);
19801 virDomainObjEndAPI(&vm
);
19806 qemuDomainOpenGraphics(virDomainPtr dom
,
19809 unsigned int flags
)
19811 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19812 virDomainObjPtr vm
= NULL
;
19814 qemuDomainObjPrivatePtr priv
;
19815 const char *protocol
;
19817 virCheckFlags(VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
, -1);
19819 if (!(vm
= qemuDomObjFromDomain(dom
)))
19822 if (virDomainOpenGraphicsEnsureACL(dom
->conn
, vm
->def
) < 0)
19825 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
19828 if (virDomainObjCheckActive(vm
) < 0)
19831 priv
= vm
->privateData
;
19833 if (idx
>= vm
->def
->ngraphics
) {
19834 virReportError(VIR_ERR_INTERNAL_ERROR
,
19835 _("No graphics backend with index %d"), idx
);
19838 switch (vm
->def
->graphics
[idx
]->type
) {
19839 case VIR_DOMAIN_GRAPHICS_TYPE_VNC
:
19842 case VIR_DOMAIN_GRAPHICS_TYPE_SPICE
:
19843 protocol
= "spice";
19845 case VIR_DOMAIN_GRAPHICS_TYPE_SDL
:
19846 case VIR_DOMAIN_GRAPHICS_TYPE_RDP
:
19847 case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP
:
19848 case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS
:
19849 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
19850 _("Can only open VNC or SPICE graphics backends, not %s"),
19851 virDomainGraphicsTypeToString(vm
->def
->graphics
[idx
]->type
));
19853 case VIR_DOMAIN_GRAPHICS_TYPE_LAST
:
19855 virReportEnumRangeError(virDomainGraphicsType
,
19856 vm
->def
->graphics
[idx
]->type
);
19860 if (qemuSecuritySetImageFDLabel(driver
->securityManager
, vm
->def
, fd
) < 0)
19863 qemuDomainObjEnterMonitor(driver
, vm
);
19864 ret
= qemuMonitorOpenGraphics(priv
->mon
, protocol
, fd
, "graphicsfd",
19865 (flags
& VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
) != 0);
19866 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
19870 qemuDomainObjEndJob(driver
, vm
);
19873 virDomainObjEndAPI(&vm
);
19878 qemuDomainOpenGraphicsFD(virDomainPtr dom
,
19880 unsigned int flags
)
19882 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19883 virDomainObjPtr vm
= NULL
;
19885 qemuDomainObjPrivatePtr priv
;
19886 const char *protocol
;
19887 int pair
[2] = {-1, -1};
19889 virCheckFlags(VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
, -1);
19891 if (!(vm
= qemuDomObjFromDomain(dom
)))
19894 if (virDomainOpenGraphicsFdEnsureACL(dom
->conn
, vm
->def
) < 0)
19897 if (virDomainObjCheckActive(vm
) < 0)
19900 priv
= vm
->privateData
;
19902 if (idx
>= vm
->def
->ngraphics
) {
19903 virReportError(VIR_ERR_INTERNAL_ERROR
,
19904 _("No graphics backend with index %d"), idx
);
19907 switch (vm
->def
->graphics
[idx
]->type
) {
19908 case VIR_DOMAIN_GRAPHICS_TYPE_VNC
:
19911 case VIR_DOMAIN_GRAPHICS_TYPE_SPICE
:
19912 protocol
= "spice";
19914 case VIR_DOMAIN_GRAPHICS_TYPE_SDL
:
19915 case VIR_DOMAIN_GRAPHICS_TYPE_RDP
:
19916 case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP
:
19917 case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS
:
19918 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
19919 _("Can only open VNC or SPICE graphics backends, not %s"),
19920 virDomainGraphicsTypeToString(vm
->def
->graphics
[idx
]->type
));
19922 case VIR_DOMAIN_GRAPHICS_TYPE_LAST
:
19924 virReportEnumRangeError(virDomainGraphicsType
,
19925 vm
->def
->graphics
[idx
]->type
);
19929 if (qemuSecuritySetSocketLabel(driver
->securityManager
, vm
->def
) < 0)
19932 if (socketpair(PF_UNIX
, SOCK_STREAM
, 0, pair
) < 0)
19935 if (qemuSecurityClearSocketLabel(driver
->securityManager
, vm
->def
) < 0)
19938 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
19940 qemuDomainObjEnterMonitor(driver
, vm
);
19941 ret
= qemuMonitorOpenGraphics(priv
->mon
, protocol
, pair
[1], "graphicsfd",
19942 (flags
& VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
));
19943 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
19945 qemuDomainObjEndJob(driver
, vm
);
19953 VIR_FORCE_CLOSE(pair
[0]);
19954 VIR_FORCE_CLOSE(pair
[1]);
19955 virDomainObjEndAPI(&vm
);
19960 QEMU_BLOCK_IOTUNE_SET_BYTES
= 1 << 0,
19961 QEMU_BLOCK_IOTUNE_SET_IOPS
= 1 << 1,
19962 QEMU_BLOCK_IOTUNE_SET_BYTES_MAX
= 1 << 2,
19963 QEMU_BLOCK_IOTUNE_SET_IOPS_MAX
= 1 << 3,
19964 QEMU_BLOCK_IOTUNE_SET_SIZE_IOPS
= 1 << 4,
19965 QEMU_BLOCK_IOTUNE_SET_GROUP_NAME
= 1 << 5,
19966 QEMU_BLOCK_IOTUNE_SET_BYTES_MAX_LENGTH
= 1 << 6,
19967 QEMU_BLOCK_IOTUNE_SET_IOPS_MAX_LENGTH
= 1 << 7,
19968 } qemuBlockIoTuneSetFlags
;
19971 /* If the user didn't specify bytes limits, inherit previous values;
19972 * likewise if the user didn't specify iops limits. */
19974 qemuDomainSetBlockIoTuneDefaults(virDomainBlockIoTuneInfoPtr newinfo
,
19975 virDomainBlockIoTuneInfoPtr oldinfo
,
19976 qemuBlockIoTuneSetFlags set_fields
)
19978 #define SET_IOTUNE_DEFAULTS(BOOL, FIELD) \
19979 if (!(set_fields & QEMU_BLOCK_IOTUNE_SET_##BOOL)) { \
19980 newinfo->total_##FIELD = oldinfo->total_##FIELD; \
19981 newinfo->read_##FIELD = oldinfo->read_##FIELD; \
19982 newinfo->write_##FIELD = oldinfo->write_##FIELD; \
19985 SET_IOTUNE_DEFAULTS(BYTES
, bytes_sec
);
19986 SET_IOTUNE_DEFAULTS(BYTES_MAX
, bytes_sec_max
);
19987 SET_IOTUNE_DEFAULTS(IOPS
, iops_sec
);
19988 SET_IOTUNE_DEFAULTS(IOPS_MAX
, iops_sec_max
);
19989 #undef SET_IOTUNE_DEFAULTS
19991 if (!(set_fields
& QEMU_BLOCK_IOTUNE_SET_SIZE_IOPS
))
19992 newinfo
->size_iops_sec
= oldinfo
->size_iops_sec
;
19993 if (!(set_fields
& QEMU_BLOCK_IOTUNE_SET_GROUP_NAME
) &&
19994 VIR_STRDUP(newinfo
->group_name
, oldinfo
->group_name
) < 0)
19997 /* The length field is handled a bit differently. If not defined/set,
19998 * QEMU will default these to 0 or 1 depending on whether something in
19999 * the same family is set or not.
20001 * Similar to other values, if nothing in the family is defined/set,
20002 * then take whatever is in the oldinfo.
20004 * To clear an existing limit, a 0 is provided; however, passing that
20005 * 0 onto QEMU if there's a family value defined/set (or defaulted)
20006 * will cause an error. So, to mimic that, if our oldinfo was set and
20007 * our newinfo is clearing, then set max_length based on whether we
20008 * have a value in the family set/defined. */
20009 #define SET_MAX_LENGTH(BOOL, FIELD) \
20010 if (!(set_fields & QEMU_BLOCK_IOTUNE_SET_##BOOL)) \
20011 newinfo->FIELD##_max_length = oldinfo->FIELD##_max_length; \
20012 else if ((set_fields & QEMU_BLOCK_IOTUNE_SET_##BOOL) && \
20013 oldinfo->FIELD##_max_length && \
20014 !newinfo->FIELD##_max_length) \
20015 newinfo->FIELD##_max_length = (newinfo->FIELD || \
20016 newinfo->FIELD##_max) ? 1 : 0;
20018 SET_MAX_LENGTH(BYTES_MAX_LENGTH
, total_bytes_sec
);
20019 SET_MAX_LENGTH(BYTES_MAX_LENGTH
, read_bytes_sec
);
20020 SET_MAX_LENGTH(BYTES_MAX_LENGTH
, write_bytes_sec
);
20021 SET_MAX_LENGTH(IOPS_MAX_LENGTH
, total_iops_sec
);
20022 SET_MAX_LENGTH(IOPS_MAX_LENGTH
, read_iops_sec
);
20023 SET_MAX_LENGTH(IOPS_MAX_LENGTH
, write_iops_sec
);
20025 #undef SET_MAX_LENGTH
20032 qemuDomainSetBlockIoTune(virDomainPtr dom
,
20034 virTypedParameterPtr params
,
20036 unsigned int flags
)
20038 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20039 virDomainObjPtr vm
= NULL
;
20040 qemuDomainObjPrivatePtr priv
;
20041 virDomainDefPtr def
= NULL
;
20042 virDomainDefPtr persistentDef
= NULL
;
20043 virDomainBlockIoTuneInfo info
;
20044 char *drivealias
= NULL
;
20045 const char *qdevid
= NULL
;
20048 virDomainDiskDefPtr conf_disk
= NULL
;
20049 virDomainDiskDefPtr disk
;
20050 qemuBlockIoTuneSetFlags set_fields
= 0;
20051 bool supportMaxOptions
= true;
20052 bool supportGroupNameOption
= true;
20053 bool supportMaxLengthOptions
= true;
20054 virQEMUDriverConfigPtr cfg
= NULL
;
20055 virObjectEventPtr event
= NULL
;
20056 virTypedParameterPtr eventParams
= NULL
;
20057 int eventNparams
= 0;
20058 int eventMaxparams
= 0;
20060 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
20061 VIR_DOMAIN_AFFECT_CONFIG
, -1);
20062 if (virTypedParamsValidate(params
, nparams
,
20063 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC
,
20064 VIR_TYPED_PARAM_ULLONG
,
20065 VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC
,
20066 VIR_TYPED_PARAM_ULLONG
,
20067 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC
,
20068 VIR_TYPED_PARAM_ULLONG
,
20069 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC
,
20070 VIR_TYPED_PARAM_ULLONG
,
20071 VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC
,
20072 VIR_TYPED_PARAM_ULLONG
,
20073 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC
,
20074 VIR_TYPED_PARAM_ULLONG
,
20075 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX
,
20076 VIR_TYPED_PARAM_ULLONG
,
20077 VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX
,
20078 VIR_TYPED_PARAM_ULLONG
,
20079 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX
,
20080 VIR_TYPED_PARAM_ULLONG
,
20081 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX
,
20082 VIR_TYPED_PARAM_ULLONG
,
20083 VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX
,
20084 VIR_TYPED_PARAM_ULLONG
,
20085 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX
,
20086 VIR_TYPED_PARAM_ULLONG
,
20087 VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC
,
20088 VIR_TYPED_PARAM_ULLONG
,
20089 VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME
,
20090 VIR_TYPED_PARAM_STRING
,
20091 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX_LENGTH
,
20092 VIR_TYPED_PARAM_ULLONG
,
20093 VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX_LENGTH
,
20094 VIR_TYPED_PARAM_ULLONG
,
20095 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX_LENGTH
,
20096 VIR_TYPED_PARAM_ULLONG
,
20097 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX_LENGTH
,
20098 VIR_TYPED_PARAM_ULLONG
,
20099 VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX_LENGTH
,
20100 VIR_TYPED_PARAM_ULLONG
,
20101 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX_LENGTH
,
20102 VIR_TYPED_PARAM_ULLONG
,
20106 memset(&info
, 0, sizeof(info
));
20108 if (!(vm
= qemuDomObjFromDomain(dom
)))
20111 if (virDomainSetBlockIoTuneEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
20114 cfg
= virQEMUDriverGetConfig(driver
);
20116 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
20119 priv
= vm
->privateData
;
20121 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
20124 if (virTypedParamsAddString(&eventParams
, &eventNparams
, &eventMaxparams
,
20125 VIR_DOMAIN_TUNABLE_BLKDEV_DISK
, path
) < 0)
20128 #define SET_IOTUNE_FIELD(FIELD, BOOL, CONST) \
20129 if (STREQ(param->field, VIR_DOMAIN_BLOCK_IOTUNE_##CONST)) { \
20130 info.FIELD = param->value.ul; \
20131 set_fields |= QEMU_BLOCK_IOTUNE_SET_##BOOL; \
20132 if (virTypedParamsAddULLong(&eventParams, &eventNparams, \
20134 VIR_DOMAIN_TUNABLE_BLKDEV_##CONST, \
20135 param->value.ul) < 0) \
20140 for (i
= 0; i
< nparams
; i
++) {
20141 virTypedParameterPtr param
= ¶ms
[i
];
20143 if (param
->value
.ul
> QEMU_BLOCK_IOTUNE_MAX
) {
20144 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
,
20145 _("block I/O throttle limit value must"
20146 " be no more than %llu"), QEMU_BLOCK_IOTUNE_MAX
);
20150 SET_IOTUNE_FIELD(total_bytes_sec
, BYTES
, TOTAL_BYTES_SEC
);
20151 SET_IOTUNE_FIELD(read_bytes_sec
, BYTES
, READ_BYTES_SEC
);
20152 SET_IOTUNE_FIELD(write_bytes_sec
, BYTES
, WRITE_BYTES_SEC
);
20153 SET_IOTUNE_FIELD(total_iops_sec
, IOPS
, TOTAL_IOPS_SEC
);
20154 SET_IOTUNE_FIELD(read_iops_sec
, IOPS
, READ_IOPS_SEC
);
20155 SET_IOTUNE_FIELD(write_iops_sec
, IOPS
, WRITE_IOPS_SEC
);
20157 SET_IOTUNE_FIELD(total_bytes_sec_max
, BYTES_MAX
,
20158 TOTAL_BYTES_SEC_MAX
);
20159 SET_IOTUNE_FIELD(read_bytes_sec_max
, BYTES_MAX
,
20160 READ_BYTES_SEC_MAX
);
20161 SET_IOTUNE_FIELD(write_bytes_sec_max
, BYTES_MAX
,
20162 WRITE_BYTES_SEC_MAX
);
20163 SET_IOTUNE_FIELD(total_iops_sec_max
, IOPS_MAX
,
20164 TOTAL_IOPS_SEC_MAX
);
20165 SET_IOTUNE_FIELD(read_iops_sec_max
, IOPS_MAX
,
20166 READ_IOPS_SEC_MAX
);
20167 SET_IOTUNE_FIELD(write_iops_sec_max
, IOPS_MAX
,
20168 WRITE_IOPS_SEC_MAX
);
20169 SET_IOTUNE_FIELD(size_iops_sec
, SIZE_IOPS
, SIZE_IOPS_SEC
);
20171 /* NB: Cannot use macro since this is a value.s not a value.ul */
20172 if (STREQ(param
->field
, VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME
)) {
20173 if (VIR_STRDUP(info
.group_name
, param
->value
.s
) < 0)
20175 set_fields
|= QEMU_BLOCK_IOTUNE_SET_GROUP_NAME
;
20176 if (virTypedParamsAddString(&eventParams
, &eventNparams
,
20178 VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME
,
20179 param
->value
.s
) < 0)
20184 SET_IOTUNE_FIELD(total_bytes_sec_max_length
, BYTES_MAX_LENGTH
,
20185 TOTAL_BYTES_SEC_MAX_LENGTH
);
20186 SET_IOTUNE_FIELD(read_bytes_sec_max_length
, BYTES_MAX_LENGTH
,
20187 READ_BYTES_SEC_MAX_LENGTH
);
20188 SET_IOTUNE_FIELD(write_bytes_sec_max_length
, BYTES_MAX_LENGTH
,
20189 WRITE_BYTES_SEC_MAX_LENGTH
);
20190 SET_IOTUNE_FIELD(total_iops_sec_max_length
, IOPS_MAX_LENGTH
,
20191 TOTAL_IOPS_SEC_MAX_LENGTH
);
20192 SET_IOTUNE_FIELD(read_iops_sec_max_length
, IOPS_MAX_LENGTH
,
20193 READ_IOPS_SEC_MAX_LENGTH
);
20194 SET_IOTUNE_FIELD(write_iops_sec_max_length
, IOPS_MAX_LENGTH
,
20195 WRITE_IOPS_SEC_MAX_LENGTH
);
20198 #undef SET_IOTUNE_FIELD
20200 if ((info
.total_bytes_sec
&& info
.read_bytes_sec
) ||
20201 (info
.total_bytes_sec
&& info
.write_bytes_sec
)) {
20202 virReportError(VIR_ERR_INVALID_ARG
, "%s",
20203 _("total and read/write of bytes_sec "
20204 "cannot be set at the same time"));
20208 if ((info
.total_iops_sec
&& info
.read_iops_sec
) ||
20209 (info
.total_iops_sec
&& info
.write_iops_sec
)) {
20210 virReportError(VIR_ERR_INVALID_ARG
, "%s",
20211 _("total and read/write of iops_sec "
20212 "cannot be set at the same time"));
20216 if ((info
.total_bytes_sec_max
&& info
.read_bytes_sec_max
) ||
20217 (info
.total_bytes_sec_max
&& info
.write_bytes_sec_max
)) {
20218 virReportError(VIR_ERR_INVALID_ARG
, "%s",
20219 _("total and read/write of bytes_sec_max "
20220 "cannot be set at the same time"));
20224 if ((info
.total_iops_sec_max
&& info
.read_iops_sec_max
) ||
20225 (info
.total_iops_sec_max
&& info
.write_iops_sec_max
)) {
20226 virReportError(VIR_ERR_INVALID_ARG
, "%s",
20227 _("total and read/write of iops_sec_max "
20228 "cannot be set at the same time"));
20233 supportMaxOptions
= virQEMUCapsGet(priv
->qemuCaps
,
20234 QEMU_CAPS_DRIVE_IOTUNE_MAX
);
20235 supportGroupNameOption
= virQEMUCapsGet(priv
->qemuCaps
,
20236 QEMU_CAPS_DRIVE_IOTUNE_GROUP
);
20237 supportMaxLengthOptions
=
20238 virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DRIVE_IOTUNE_MAX_LENGTH
);
20240 if (!supportMaxOptions
&&
20241 (set_fields
& (QEMU_BLOCK_IOTUNE_SET_BYTES_MAX
|
20242 QEMU_BLOCK_IOTUNE_SET_IOPS_MAX
|
20243 QEMU_BLOCK_IOTUNE_SET_SIZE_IOPS
))) {
20244 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
20245 _("a block I/O throttling parameter is not "
20246 "supported with this QEMU binary"));
20250 if (!supportGroupNameOption
&&
20251 (set_fields
& QEMU_BLOCK_IOTUNE_SET_GROUP_NAME
)) {
20252 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
20253 _("the block I/O throttling group parameter is not "
20254 "supported with this QEMU binary"));
20258 if (!supportMaxLengthOptions
&&
20259 (set_fields
& (QEMU_BLOCK_IOTUNE_SET_BYTES_MAX_LENGTH
|
20260 QEMU_BLOCK_IOTUNE_SET_IOPS_MAX_LENGTH
))) {
20261 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
20262 _("a block I/O throttling length parameter is not "
20263 "supported with this QEMU binary"));
20267 if (!(disk
= qemuDomainDiskByName(def
, path
)))
20270 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
)) {
20271 qdevid
= QEMU_DOMAIN_DISK_PRIVATE(disk
)->qomName
;
20273 if (!(drivealias
= qemuAliasDiskDriveFromDisk(disk
)))
20277 if (qemuDomainSetBlockIoTuneDefaults(&info
, &disk
->blkdeviotune
,
20281 #define CHECK_MAX(val, _bool) \
20283 if (info.val##_max) { \
20285 if (QEMU_BLOCK_IOTUNE_SET_##_bool) { \
20286 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
20287 _("cannot reset '%s' when " \
20289 #val, #val "_max"); \
20291 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
20292 _("value '%s' cannot be set if " \
20293 "'%s' is not set"), \
20294 #val "_max", #val); \
20298 if (info.val##_max < info.val) { \
20299 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
20300 _("value '%s' cannot be " \
20301 "smaller than '%s'"), \
20302 #val "_max", #val); \
20308 CHECK_MAX(total_bytes_sec
, BYTES
);
20309 CHECK_MAX(read_bytes_sec
, BYTES
);
20310 CHECK_MAX(write_bytes_sec
, BYTES
);
20311 CHECK_MAX(total_iops_sec
, IOPS
);
20312 CHECK_MAX(read_iops_sec
, IOPS
);
20313 CHECK_MAX(write_iops_sec
, IOPS
);
20317 /* NB: Let's let QEMU decide how to handle issues with _length
20318 * via the JSON error code from the block_set_io_throttle call */
20320 qemuDomainObjEnterMonitor(driver
, vm
);
20321 ret
= qemuMonitorSetBlockIoThrottle(priv
->mon
, drivealias
, qdevid
,
20322 &info
, supportMaxOptions
,
20323 set_fields
& QEMU_BLOCK_IOTUNE_SET_GROUP_NAME
,
20324 supportMaxLengthOptions
);
20325 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
20331 if (virDomainDiskSetBlockIOTune(disk
, &info
) < 0)
20334 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
,
20335 vm
, driver
->caps
) < 0)
20338 if (eventNparams
) {
20339 event
= virDomainEventTunableNewFromDom(dom
, eventParams
, eventNparams
);
20341 virObjectEventStateQueue(driver
->domainEventState
, event
);
20345 if (persistentDef
) {
20346 if (!(conf_disk
= virDomainDiskByName(persistentDef
, path
, true))) {
20347 virReportError(VIR_ERR_INVALID_ARG
,
20348 _("missing persistent configuration for disk '%s'"),
20353 if (qemuDomainSetBlockIoTuneDefaults(&info
, &conf_disk
->blkdeviotune
,
20357 if (virDomainDiskSetBlockIOTune(conf_disk
, &info
) < 0)
20360 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
20361 persistentDef
) < 0)
20367 qemuDomainObjEndJob(driver
, vm
);
20370 VIR_FREE(info
.group_name
);
20371 VIR_FREE(drivealias
);
20372 virDomainObjEndAPI(&vm
);
20374 virTypedParamsFree(eventParams
, eventNparams
);
20375 virObjectUnref(cfg
);
20380 qemuDomainGetBlockIoTune(virDomainPtr dom
,
20382 virTypedParameterPtr params
,
20384 unsigned int flags
)
20386 virDomainDiskDefPtr disk
;
20387 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20388 virDomainObjPtr vm
= NULL
;
20389 qemuDomainObjPrivatePtr priv
= NULL
;
20390 virDomainDefPtr def
= NULL
;
20391 virDomainDefPtr persistentDef
= NULL
;
20392 virDomainBlockIoTuneInfo reply
= {0};
20393 char *drivealias
= NULL
;
20394 const char *qdevid
= NULL
;
20398 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
20399 VIR_DOMAIN_AFFECT_CONFIG
|
20400 VIR_TYPED_PARAM_STRING_OKAY
, -1);
20402 /* We don't return strings, and thus trivially support this flag. */
20403 flags
&= ~VIR_TYPED_PARAM_STRING_OKAY
;
20405 if (!(vm
= qemuDomObjFromDomain(dom
)))
20408 priv
= vm
->privateData
;
20410 if (virDomainGetBlockIoTuneEnsureACL(dom
->conn
, vm
->def
) < 0)
20413 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
20416 /* the API check guarantees that only one of the definitions will be set */
20417 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
20421 /* If the VM is running, we can check if the current VM can use
20422 * optional parameters or not. */
20423 maxparams
= QEMU_NB_BLOCK_IO_TUNE_BASE_PARAMS
;
20424 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DRIVE_IOTUNE_MAX
))
20425 maxparams
+= QEMU_NB_BLOCK_IO_TUNE_MAX_PARAMS
;
20426 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DRIVE_IOTUNE_GROUP
))
20427 maxparams
+= QEMU_NB_BLOCK_IO_TUNE_GROUP_PARAMS
;
20428 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DRIVE_IOTUNE_MAX_LENGTH
))
20429 maxparams
+= QEMU_NB_BLOCK_IO_TUNE_LENGTH_PARAMS
;
20431 maxparams
= QEMU_NB_BLOCK_IO_TUNE_ALL_PARAMS
;
20434 if (*nparams
== 0) {
20435 *nparams
= maxparams
;
20438 } else if (*nparams
< maxparams
) {
20439 maxparams
= *nparams
;
20445 if (!(disk
= qemuDomainDiskByName(def
, path
)))
20448 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
)) {
20449 qdevid
= QEMU_DOMAIN_DISK_PRIVATE(disk
)->qomName
;
20451 if (!(drivealias
= qemuAliasDiskDriveFromDisk(disk
)))
20454 qemuDomainObjEnterMonitor(driver
, vm
);
20455 ret
= qemuMonitorGetBlockIoThrottle(priv
->mon
, drivealias
, qdevid
, &reply
);
20456 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
20462 if (persistentDef
) {
20463 if (!(disk
= virDomainDiskByName(persistentDef
, path
, true))) {
20464 virReportError(VIR_ERR_INVALID_ARG
,
20465 _("disk '%s' was not found in the domain config"),
20469 reply
= disk
->blkdeviotune
;
20471 /* Group name needs to be copied since qemuMonitorGetBlockIoThrottle
20472 * allocates it as well */
20473 if (VIR_STRDUP(reply
.group_name
, disk
->blkdeviotune
.group_name
) < 0)
20477 #define BLOCK_IOTUNE_ASSIGN(name, var) \
20478 if (*nparams < maxparams && \
20479 virTypedParameterAssign(¶ms[(*nparams)++], \
20480 VIR_DOMAIN_BLOCK_IOTUNE_ ## name, \
20481 VIR_TYPED_PARAM_ULLONG, \
20486 BLOCK_IOTUNE_ASSIGN(TOTAL_BYTES_SEC
, total_bytes_sec
);
20487 BLOCK_IOTUNE_ASSIGN(READ_BYTES_SEC
, read_bytes_sec
);
20488 BLOCK_IOTUNE_ASSIGN(WRITE_BYTES_SEC
, write_bytes_sec
);
20490 BLOCK_IOTUNE_ASSIGN(TOTAL_IOPS_SEC
, total_iops_sec
);
20491 BLOCK_IOTUNE_ASSIGN(READ_IOPS_SEC
, read_iops_sec
);
20492 BLOCK_IOTUNE_ASSIGN(WRITE_IOPS_SEC
, write_iops_sec
);
20494 BLOCK_IOTUNE_ASSIGN(TOTAL_BYTES_SEC_MAX
, total_bytes_sec_max
);
20495 BLOCK_IOTUNE_ASSIGN(READ_BYTES_SEC_MAX
, read_bytes_sec_max
);
20496 BLOCK_IOTUNE_ASSIGN(WRITE_BYTES_SEC_MAX
, write_bytes_sec_max
);
20498 BLOCK_IOTUNE_ASSIGN(TOTAL_IOPS_SEC_MAX
, total_iops_sec_max
);
20499 BLOCK_IOTUNE_ASSIGN(READ_IOPS_SEC_MAX
, read_iops_sec_max
);
20500 BLOCK_IOTUNE_ASSIGN(WRITE_IOPS_SEC_MAX
, write_iops_sec_max
);
20502 BLOCK_IOTUNE_ASSIGN(SIZE_IOPS_SEC
, size_iops_sec
);
20504 if (*nparams
< maxparams
) {
20505 if (virTypedParameterAssign(¶ms
[(*nparams
)++],
20506 VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME
,
20507 VIR_TYPED_PARAM_STRING
,
20508 reply
.group_name
) < 0)
20511 reply
.group_name
= NULL
;
20514 BLOCK_IOTUNE_ASSIGN(TOTAL_BYTES_SEC_MAX_LENGTH
, total_bytes_sec_max_length
);
20515 BLOCK_IOTUNE_ASSIGN(READ_BYTES_SEC_MAX_LENGTH
, read_bytes_sec_max_length
);
20516 BLOCK_IOTUNE_ASSIGN(WRITE_BYTES_SEC_MAX_LENGTH
, write_bytes_sec_max_length
);
20518 BLOCK_IOTUNE_ASSIGN(TOTAL_IOPS_SEC_MAX_LENGTH
, total_iops_sec_max_length
);
20519 BLOCK_IOTUNE_ASSIGN(READ_IOPS_SEC_MAX_LENGTH
, read_iops_sec_max_length
);
20520 BLOCK_IOTUNE_ASSIGN(WRITE_IOPS_SEC_MAX_LENGTH
, write_iops_sec_max_length
);
20521 #undef BLOCK_IOTUNE_ASSIGN
20526 qemuDomainObjEndJob(driver
, vm
);
20529 VIR_FREE(reply
.group_name
);
20530 VIR_FREE(drivealias
);
20531 virDomainObjEndAPI(&vm
);
20536 qemuDomainGetDiskErrors(virDomainPtr dom
,
20537 virDomainDiskErrorPtr errors
,
20538 unsigned int nerrors
,
20539 unsigned int flags
)
20541 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20542 virDomainObjPtr vm
= NULL
;
20543 qemuDomainObjPrivatePtr priv
;
20544 virHashTablePtr table
= NULL
;
20545 bool blockdev
= false;
20550 virCheckFlags(0, -1);
20552 if (!(vm
= qemuDomObjFromDomain(dom
)))
20555 priv
= vm
->privateData
;
20556 blockdev
= virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
);
20558 if (virDomainGetDiskErrorsEnsureACL(dom
->conn
, vm
->def
) < 0)
20561 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
20564 if (virDomainObjCheckActive(vm
) < 0)
20568 ret
= vm
->def
->ndisks
;
20572 qemuDomainObjEnterMonitor(driver
, vm
);
20573 table
= qemuMonitorGetBlockInfo(priv
->mon
);
20574 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
20579 for (i
= n
= 0; i
< vm
->def
->ndisks
; i
++) {
20580 struct qemuDomainDiskInfo
*info
;
20581 virDomainDiskDefPtr disk
= vm
->def
->disks
[i
];
20582 qemuDomainDiskPrivatePtr diskPriv
= QEMU_DOMAIN_DISK_PRIVATE(disk
);
20583 const char *entryname
= disk
->info
.alias
;
20586 entryname
= diskPriv
->qomName
;
20588 if ((info
= virHashLookup(table
, entryname
)) &&
20589 info
->io_status
!= VIR_DOMAIN_DISK_ERROR_NONE
) {
20593 if (VIR_STRDUP(errors
[n
].disk
, disk
->dst
) < 0)
20595 errors
[n
].error
= info
->io_status
;
20603 qemuDomainObjEndJob(driver
, vm
);
20606 virDomainObjEndAPI(&vm
);
20607 virHashFree(table
);
20609 for (i
= 0; i
< n
; i
++)
20610 VIR_FREE(errors
[i
].disk
);
20616 qemuDomainSetMetadata(virDomainPtr dom
,
20618 const char *metadata
,
20621 unsigned int flags
)
20623 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20624 virDomainObjPtr vm
;
20625 virQEMUDriverConfigPtr cfg
= NULL
;
20626 virCapsPtr caps
= NULL
;
20629 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
20630 VIR_DOMAIN_AFFECT_CONFIG
, -1);
20632 if (!(vm
= qemuDomObjFromDomain(dom
)))
20635 cfg
= virQEMUDriverGetConfig(driver
);
20637 if (virDomainSetMetadataEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
20640 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
20643 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
20646 ret
= virDomainObjSetMetadata(vm
, type
, metadata
, key
, uri
, caps
,
20647 driver
->xmlopt
, cfg
->stateDir
,
20648 cfg
->configDir
, flags
);
20651 virObjectEventPtr ev
= NULL
;
20652 ev
= virDomainEventMetadataChangeNewFromObj(vm
, type
, uri
);
20653 virObjectEventStateQueue(driver
->domainEventState
, ev
);
20656 qemuDomainObjEndJob(driver
, vm
);
20659 virDomainObjEndAPI(&vm
);
20660 virObjectUnref(caps
);
20661 virObjectUnref(cfg
);
20666 qemuDomainGetMetadata(virDomainPtr dom
,
20669 unsigned int flags
)
20671 virDomainObjPtr vm
;
20674 if (!(vm
= qemuDomObjFromDomain(dom
)))
20677 if (virDomainGetMetadataEnsureACL(dom
->conn
, vm
->def
) < 0)
20680 ret
= virDomainObjGetMetadata(vm
, type
, uri
, flags
);
20683 virDomainObjEndAPI(&vm
);
20689 qemuDomainGetCPUStats(virDomainPtr domain
,
20690 virTypedParameterPtr params
,
20691 unsigned int nparams
,
20693 unsigned int ncpus
,
20694 unsigned int flags
)
20696 virDomainObjPtr vm
= NULL
;
20698 qemuDomainObjPrivatePtr priv
;
20699 virBitmapPtr guestvcpus
= NULL
;
20701 virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY
, -1);
20703 if (!(vm
= qemuDomObjFromDomain(domain
)))
20706 priv
= vm
->privateData
;
20708 if (virDomainGetCPUStatsEnsureACL(domain
->conn
, vm
->def
) < 0)
20711 if (virDomainObjCheckActive(vm
) < 0)
20714 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPUACCT
)) {
20715 virReportError(VIR_ERR_OPERATION_INVALID
,
20716 "%s", _("cgroup CPUACCT controller is not mounted"));
20720 if (qemuDomainHasVcpuPids(vm
) &&
20721 !(guestvcpus
= virDomainDefGetOnlineVcpumap(vm
->def
)))
20724 if (start_cpu
== -1)
20725 ret
= virCgroupGetDomainTotalCpuStats(priv
->cgroup
,
20728 ret
= virCgroupGetPercpuStats(priv
->cgroup
, params
, nparams
,
20729 start_cpu
, ncpus
, guestvcpus
);
20731 virBitmapFree(guestvcpus
);
20732 virDomainObjEndAPI(&vm
);
20737 qemuDomainPMSuspendForDuration(virDomainPtr dom
,
20738 unsigned int target
,
20739 unsigned long long duration
,
20740 unsigned int flags
)
20742 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20743 virDomainObjPtr vm
;
20744 qemuAgentPtr agent
;
20747 virCheckFlags(0, -1);
20750 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
20751 _("Duration not supported. Use 0 for now"));
20755 if (!(target
== VIR_NODE_SUSPEND_TARGET_MEM
||
20756 target
== VIR_NODE_SUSPEND_TARGET_DISK
||
20757 target
== VIR_NODE_SUSPEND_TARGET_HYBRID
)) {
20758 virReportError(VIR_ERR_INVALID_ARG
,
20759 _("Unknown suspend target: %u"),
20764 if (!(vm
= qemuDomObjFromDomain(dom
)))
20767 if (virDomainPMSuspendForDurationEnsureACL(dom
->conn
, vm
->def
) < 0)
20770 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
20773 if (virDomainObjCheckActive(vm
) < 0)
20776 if (vm
->def
->pm
.s3
|| vm
->def
->pm
.s4
) {
20777 if (vm
->def
->pm
.s3
== VIR_TRISTATE_BOOL_NO
&&
20778 (target
== VIR_NODE_SUSPEND_TARGET_MEM
||
20779 target
== VIR_NODE_SUSPEND_TARGET_HYBRID
)) {
20780 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
20781 _("S3 state is disabled for this domain"));
20785 if (vm
->def
->pm
.s4
== VIR_TRISTATE_BOOL_NO
&&
20786 target
== VIR_NODE_SUSPEND_TARGET_DISK
) {
20787 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
20788 _("S4 state is disabled for this domain"));
20793 if (!qemuDomainAgentAvailable(vm
, true))
20796 agent
= qemuDomainObjEnterAgent(vm
);
20797 ret
= qemuAgentSuspend(agent
, target
);
20798 qemuDomainObjExitAgent(vm
, agent
);
20801 qemuDomainObjEndAgentJob(vm
);
20804 virDomainObjEndAPI(&vm
);
20809 qemuDomainPMWakeup(virDomainPtr dom
,
20810 unsigned int flags
)
20812 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20813 virDomainObjPtr vm
;
20815 qemuDomainObjPrivatePtr priv
;
20817 virCheckFlags(0, -1);
20819 if (!(vm
= qemuDomObjFromDomain(dom
)))
20822 if (virDomainPMWakeupEnsureACL(dom
->conn
, vm
->def
) < 0)
20825 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
20828 if (virDomainObjCheckActive(vm
) < 0)
20831 priv
= vm
->privateData
;
20833 qemuDomainObjEnterMonitor(driver
, vm
);
20834 ret
= qemuMonitorSystemWakeup(priv
->mon
);
20835 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
20839 qemuDomainObjEndJob(driver
, vm
);
20842 virDomainObjEndAPI(&vm
);
20847 qemuConnectListAllDomains(virConnectPtr conn
,
20848 virDomainPtr
**domains
,
20849 unsigned int flags
)
20851 virQEMUDriverPtr driver
= conn
->privateData
;
20854 virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL
, -1);
20856 if (virConnectListAllDomainsEnsureACL(conn
) < 0)
20859 ret
= virDomainObjListExport(driver
->domains
, conn
, domains
,
20860 virConnectListAllDomainsCheckACL
, flags
);
20867 qemuDomainQemuAgentCommand(virDomainPtr domain
,
20870 unsigned int flags
)
20872 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
20873 virDomainObjPtr vm
;
20875 char *result
= NULL
;
20876 qemuAgentPtr agent
;
20878 virCheckFlags(0, NULL
);
20880 if (!(vm
= qemuDomObjFromDomain(domain
)))
20883 if (virDomainQemuAgentCommandEnsureACL(domain
->conn
, vm
->def
) < 0)
20886 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
20889 if (virDomainObjCheckActive(vm
) < 0)
20892 if (!qemuDomainAgentAvailable(vm
, true))
20895 qemuDomainObjTaint(driver
, vm
, VIR_DOMAIN_TAINT_CUSTOM_GA_COMMAND
, NULL
);
20897 agent
= qemuDomainObjEnterAgent(vm
);
20898 ret
= qemuAgentArbitraryCommand(agent
, cmd
, &result
, timeout
);
20899 qemuDomainObjExitAgent(vm
, agent
);
20904 qemuDomainObjEndAgentJob(vm
);
20907 virDomainObjEndAPI(&vm
);
20913 qemuConnectDomainQemuMonitorEventRegister(virConnectPtr conn
,
20916 virConnectDomainQemuMonitorEventCallback callback
,
20918 virFreeCallback freecb
,
20919 unsigned int flags
)
20921 virQEMUDriverPtr driver
= conn
->privateData
;
20924 if (virConnectDomainQemuMonitorEventRegisterEnsureACL(conn
) < 0)
20927 if (virDomainQemuMonitorEventStateRegisterID(conn
,
20928 driver
->domainEventState
,
20929 dom
, event
, callback
,
20930 opaque
, freecb
, flags
,
20940 qemuConnectDomainQemuMonitorEventDeregister(virConnectPtr conn
,
20943 virQEMUDriverPtr driver
= conn
->privateData
;
20946 if (virConnectDomainQemuMonitorEventDeregisterEnsureACL(conn
) < 0)
20949 if (virObjectEventStateDeregisterID(conn
, driver
->domainEventState
,
20950 callbackID
, true) < 0)
20961 qemuDomainFSTrim(virDomainPtr dom
,
20962 const char *mountPoint
,
20963 unsigned long long minimum
,
20964 unsigned int flags
)
20966 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20967 virDomainObjPtr vm
;
20968 qemuAgentPtr agent
;
20971 virCheckFlags(0, -1);
20974 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
20975 _("Specifying mount point "
20976 "is not supported for now"));
20980 if (!(vm
= qemuDomObjFromDomain(dom
)))
20983 if (virDomainFSTrimEnsureACL(dom
->conn
, vm
->def
) < 0)
20986 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
20989 if (!qemuDomainAgentAvailable(vm
, true))
20992 if (virDomainObjCheckActive(vm
) < 0)
20995 agent
= qemuDomainObjEnterAgent(vm
);
20996 ret
= qemuAgentFSTrim(agent
, minimum
);
20997 qemuDomainObjExitAgent(vm
, agent
);
21000 qemuDomainObjEndAgentJob(vm
);
21003 virDomainObjEndAPI(&vm
);
21009 qemuNodeGetInfo(virConnectPtr conn
,
21010 virNodeInfoPtr nodeinfo
)
21012 if (virNodeGetInfoEnsureACL(conn
) < 0)
21015 return virCapabilitiesGetNodeInfo(nodeinfo
);
21020 qemuNodeGetCPUStats(virConnectPtr conn
,
21022 virNodeCPUStatsPtr params
,
21024 unsigned int flags
)
21026 if (virNodeGetCPUStatsEnsureACL(conn
) < 0)
21029 return virHostCPUGetStats(cpuNum
, params
, nparams
, flags
);
21034 qemuNodeGetMemoryStats(virConnectPtr conn
,
21036 virNodeMemoryStatsPtr params
,
21038 unsigned int flags
)
21040 if (virNodeGetMemoryStatsEnsureACL(conn
) < 0)
21043 return virHostMemGetStats(cellNum
, params
, nparams
, flags
);
21048 qemuNodeGetCellsFreeMemory(virConnectPtr conn
,
21049 unsigned long long *freeMems
,
21053 if (virNodeGetCellsFreeMemoryEnsureACL(conn
) < 0)
21056 return virHostMemGetCellsFree(freeMems
, startCell
, maxCells
);
21060 static unsigned long long
21061 qemuNodeGetFreeMemory(virConnectPtr conn
)
21063 unsigned long long freeMem
;
21065 if (virNodeGetFreeMemoryEnsureACL(conn
) < 0)
21068 if (virHostMemGetInfo(NULL
, &freeMem
) < 0)
21076 qemuNodeGetMemoryParameters(virConnectPtr conn
,
21077 virTypedParameterPtr params
,
21079 unsigned int flags
)
21081 if (virNodeGetMemoryParametersEnsureACL(conn
) < 0)
21084 return virHostMemGetParameters(params
, nparams
, flags
);
21089 qemuNodeSetMemoryParameters(virConnectPtr conn
,
21090 virTypedParameterPtr params
,
21092 unsigned int flags
)
21094 if (virNodeSetMemoryParametersEnsureACL(conn
) < 0)
21097 return virHostMemSetParameters(params
, nparams
, flags
);
21102 qemuNodeGetCPUMap(virConnectPtr conn
,
21103 unsigned char **cpumap
,
21104 unsigned int *online
,
21105 unsigned int flags
)
21107 if (virNodeGetCPUMapEnsureACL(conn
) < 0)
21110 return virHostCPUGetMap(cpumap
, online
, flags
);
21115 qemuNodeSuspendForDuration(virConnectPtr conn
,
21116 unsigned int target
,
21117 unsigned long long duration
,
21118 unsigned int flags
)
21120 if (virNodeSuspendForDurationEnsureACL(conn
) < 0)
21123 return virNodeSuspend(target
, duration
, flags
);
21127 qemuConnectGetCPUModelNames(virConnectPtr conn
,
21128 const char *archName
,
21130 unsigned int flags
)
21134 virCheckFlags(0, -1);
21135 if (virConnectGetCPUModelNamesEnsureACL(conn
) < 0)
21138 if (!(arch
= virArchFromString(archName
))) {
21139 virReportError(VIR_ERR_INVALID_ARG
,
21140 _("cannot find architecture %s"),
21145 return virCPUGetModels(arch
, models
);
21150 qemuDomainGetHostname(virDomainPtr dom
,
21151 unsigned int flags
)
21153 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21154 virDomainObjPtr vm
= NULL
;
21155 qemuAgentPtr agent
;
21156 char *hostname
= NULL
;
21158 virCheckFlags(0, NULL
);
21160 if (!(vm
= qemuDomObjFromDomain(dom
)))
21163 if (virDomainGetHostnameEnsureACL(dom
->conn
, vm
->def
) < 0)
21166 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
21169 if (virDomainObjCheckActive(vm
) < 0)
21172 if (!qemuDomainAgentAvailable(vm
, true))
21175 agent
= qemuDomainObjEnterAgent(vm
);
21176 ignore_value(qemuAgentGetHostname(agent
, &hostname
));
21177 qemuDomainObjExitAgent(vm
, agent
);
21180 qemuDomainObjEndAgentJob(vm
);
21183 virDomainObjEndAPI(&vm
);
21189 qemuDomainGetTime(virDomainPtr dom
,
21190 long long *seconds
,
21191 unsigned int *nseconds
,
21192 unsigned int flags
)
21194 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21195 virDomainObjPtr vm
= NULL
;
21196 qemuAgentPtr agent
;
21200 virCheckFlags(0, ret
);
21202 if (!(vm
= qemuDomObjFromDomain(dom
)))
21205 if (virDomainGetTimeEnsureACL(dom
->conn
, vm
->def
) < 0)
21208 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
21211 if (virDomainObjCheckActive(vm
) < 0)
21214 if (!qemuDomainAgentAvailable(vm
, true))
21217 agent
= qemuDomainObjEnterAgent(vm
);
21218 rv
= qemuAgentGetTime(agent
, seconds
, nseconds
);
21219 qemuDomainObjExitAgent(vm
, agent
);
21227 qemuDomainObjEndAgentJob(vm
);
21230 virDomainObjEndAPI(&vm
);
21236 qemuDomainSetTime(virDomainPtr dom
,
21238 unsigned int nseconds
,
21239 unsigned int flags
)
21241 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21242 qemuDomainObjPrivatePtr priv
;
21243 virDomainObjPtr vm
;
21244 qemuAgentPtr agent
;
21245 bool rtcSync
= flags
& VIR_DOMAIN_TIME_SYNC
;
21249 virCheckFlags(VIR_DOMAIN_TIME_SYNC
, ret
);
21251 if (!(vm
= qemuDomObjFromDomain(dom
)))
21254 if (virDomainSetTimeEnsureACL(dom
->conn
, vm
->def
) < 0)
21257 priv
= vm
->privateData
;
21259 if (qemuDomainObjBeginJobWithAgent(driver
, vm
,
21261 QEMU_AGENT_JOB_MODIFY
) < 0)
21264 if (virDomainObjCheckActive(vm
) < 0)
21267 /* On x86, the rtc-reset-reinjection QMP command must be called after
21268 * setting the time to avoid trouble down the line. If the command is
21269 * not available, don't set the time at all and report an error */
21270 if (ARCH_IS_X86(vm
->def
->os
.arch
) &&
21271 !virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_RTC_RESET_REINJECTION
))
21273 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
21274 _("cannot set time: qemu doesn't support "
21275 "rtc-reset-reinjection command"));
21279 if (!qemuDomainAgentAvailable(vm
, true))
21282 agent
= qemuDomainObjEnterAgent(vm
);
21283 rv
= qemuAgentSetTime(agent
, seconds
, nseconds
, rtcSync
);
21284 qemuDomainObjExitAgent(vm
, agent
);
21289 if (virDomainObjCheckActive(vm
) < 0)
21292 /* Don't try to call rtc-reset-reinjection if it's not available */
21293 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_RTC_RESET_REINJECTION
)) {
21294 qemuDomainObjEnterMonitor(driver
, vm
);
21295 rv
= qemuMonitorRTCResetReinjection(priv
->mon
);
21296 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
21306 qemuDomainObjEndJobWithAgent(driver
, vm
);
21309 virDomainObjEndAPI(&vm
);
21315 qemuDomainFSFreeze(virDomainPtr dom
,
21316 const char **mountpoints
,
21317 unsigned int nmountpoints
,
21318 unsigned int flags
)
21320 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21321 virDomainObjPtr vm
;
21324 virCheckFlags(0, -1);
21326 if (!(vm
= qemuDomObjFromDomain(dom
)))
21329 if (virDomainFSFreezeEnsureACL(dom
->conn
, vm
->def
) < 0)
21332 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
21335 if (virDomainObjCheckActive(vm
) < 0)
21338 ret
= qemuDomainSnapshotFSFreeze(driver
, vm
, mountpoints
, nmountpoints
);
21341 qemuDomainObjEndAgentJob(vm
);
21344 virDomainObjEndAPI(&vm
);
21350 qemuDomainFSThaw(virDomainPtr dom
,
21351 const char **mountpoints
,
21352 unsigned int nmountpoints
,
21353 unsigned int flags
)
21355 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21356 virDomainObjPtr vm
;
21359 virCheckFlags(0, -1);
21361 if (mountpoints
|| nmountpoints
) {
21362 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
21363 _("specifying mountpoints is not supported"));
21367 if (!(vm
= qemuDomObjFromDomain(dom
)))
21370 if (virDomainFSThawEnsureACL(dom
->conn
, vm
->def
) < 0)
21373 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
21376 if (virDomainObjCheckActive(vm
) < 0)
21379 ret
= qemuDomainSnapshotFSThaw(driver
, vm
, true);
21382 qemuDomainObjEndAgentJob(vm
);
21385 virDomainObjEndAPI(&vm
);
21391 qemuNodeGetFreePages(virConnectPtr conn
,
21392 unsigned int npages
,
21393 unsigned int *pages
,
21395 unsigned int cellCount
,
21396 unsigned long long *counts
,
21397 unsigned int flags
)
21399 virCheckFlags(0, -1);
21401 if (virNodeGetFreePagesEnsureACL(conn
) < 0)
21404 return virHostMemGetFreePages(npages
, pages
, startCell
, cellCount
, counts
);
21409 qemuConnectGetDomainCapabilities(virConnectPtr conn
,
21410 const char *emulatorbin
,
21411 const char *arch_str
,
21412 const char *machine
,
21413 const char *virttype_str
,
21414 unsigned int flags
)
21417 virQEMUDriverPtr driver
= conn
->privateData
;
21418 virQEMUCapsPtr qemuCaps
= NULL
;
21420 virDomainVirtType virttype
;
21421 virDomainCapsPtr domCaps
= NULL
;
21422 virQEMUDriverConfigPtr cfg
= NULL
;
21423 virCapsPtr caps
= NULL
;
21425 virCheckFlags(0, ret
);
21427 if (virConnectGetDomainCapabilitiesEnsureACL(conn
) < 0)
21430 cfg
= virQEMUDriverGetConfig(driver
);
21432 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
21435 qemuCaps
= virQEMUCapsCacheLookupDefault(driver
->qemuCapsCache
,
21440 &arch
, &virttype
, &machine
);
21444 if (!(domCaps
= virDomainCapsNew(virQEMUCapsGetBinary(qemuCaps
), machine
,
21448 if (virQEMUCapsFillDomainCaps(caps
, domCaps
, qemuCaps
,
21449 cfg
->firmwares
, cfg
->nfirmwares
) < 0)
21452 ret
= virDomainCapsFormat(domCaps
);
21454 virObjectUnref(cfg
);
21455 virObjectUnref(caps
);
21456 virObjectUnref(domCaps
);
21457 virObjectUnref(qemuCaps
);
21463 qemuDomainGetStatsState(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
21464 virDomainObjPtr dom
,
21465 virDomainStatsRecordPtr record
,
21467 unsigned int privflags ATTRIBUTE_UNUSED
)
21469 if (virTypedParamsAddInt(&record
->params
,
21473 dom
->state
.state
) < 0)
21476 if (virTypedParamsAddInt(&record
->params
,
21480 dom
->state
.reason
) < 0)
21488 QEMU_DOMAIN_STATS_HAVE_JOB
= 1 << 0, /* job is entered, monitor can be
21490 QEMU_DOMAIN_STATS_BACKING
= 1 << 1, /* include backing chain in
21492 } qemuDomainStatsFlags
;
21495 #define HAVE_JOB(flags) ((flags) & QEMU_DOMAIN_STATS_HAVE_JOB)
21498 typedef struct _virQEMUResctrlMonData virQEMUResctrlMonData
;
21499 typedef virQEMUResctrlMonData
*virQEMUResctrlMonDataPtr
;
21500 struct _virQEMUResctrlMonData
{
21503 virResctrlMonitorStatsPtr
*stats
;
21509 qemuDomainFreeResctrlMonData(virQEMUResctrlMonDataPtr resdata
)
21511 VIR_FREE(resdata
->name
);
21512 VIR_FREE(resdata
->vcpus
);
21513 virResctrlMonitorFreeStats(resdata
->stats
, resdata
->nstats
);
21519 * qemuDomainGetResctrlMonData:
21520 * @dom: Pointer for the domain that the resctrl monitors reside in
21521 * @resdata: Pointer of virQEMUResctrlMonDataPtr pointer for receiving the
21522 * virQEMUResctrlMonDataPtr array. Caller is responsible for
21523 * freeing the array.
21524 * @nresdata: Pointer of size_t to report the size virQEMUResctrlMonDataPtr
21525 * array to caller. If *@nresdata is not 0, even if function
21526 * returns an error, the caller is also required to call
21527 * qemuDomainFreeResctrlMonData to free each element in the
21528 * *@resdata array and then the array itself.
21529 * @tag: Could be VIR_RESCTRL_MONITOR_TYPE_CACHE for getting cache statistics
21530 * from @dom cache monitors. VIR_RESCTRL_MONITOR_TYPE_MEMBW for
21531 * getting memory bandwidth statistics from memory bandwidth monitors.
21533 * Get cache or memory bandwidth statistics from @dom monitors.
21535 * Returns -1 on failure, or 0 on success.
21538 qemuDomainGetResctrlMonData(virDomainObjPtr dom
,
21539 virQEMUResctrlMonDataPtr
**resdata
,
21541 virResctrlMonitorType tag
)
21543 virDomainResctrlDefPtr resctrl
= NULL
;
21544 virQEMUResctrlMonDataPtr res
= NULL
;
21548 for (i
= 0; i
< dom
->def
->nresctrls
; i
++) {
21549 resctrl
= dom
->def
->resctrls
[i
];
21551 for (j
= 0; j
< resctrl
->nmonitors
; j
++) {
21552 virDomainResctrlMonDefPtr domresmon
= NULL
;
21553 virResctrlMonitorPtr monitor
= NULL
;
21555 domresmon
= resctrl
->monitors
[j
];
21556 monitor
= domresmon
->instance
;
21558 if (domresmon
->tag
!= tag
)
21561 if (VIR_ALLOC(res
) < 0)
21564 /* If virBitmapFormat successfully returns an vcpu string, then
21565 * res.vcpus is assigned with an memory space holding it,
21566 * let this newly allocated memory buffer to be freed along with
21567 * the free of 'res' */
21568 if (!(res
->vcpus
= virBitmapFormat(domresmon
->vcpus
)))
21571 if (VIR_STRDUP(res
->name
, virResctrlMonitorGetID(monitor
)) < 0)
21574 if (virResctrlMonitorGetCacheOccupancy(monitor
,
21579 if (VIR_APPEND_ELEMENT(*resdata
, *nresdata
, res
) < 0)
21587 qemuDomainFreeResctrlMonData(res
);
21593 qemuDomainGetStatsCpuCache(virDomainObjPtr dom
,
21594 virDomainStatsRecordPtr record
,
21597 char param_name
[VIR_TYPED_PARAM_FIELD_LENGTH
];
21598 virQEMUResctrlMonDataPtr
*resdata
= NULL
;
21599 size_t nresdata
= 0;
21604 if (!virDomainObjIsActive(dom
))
21607 if (qemuDomainGetResctrlMonData(dom
, &resdata
, &nresdata
,
21608 VIR_RESCTRL_MONITOR_TYPE_CACHE
) < 0)
21611 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21612 "cpu.cache.monitor.count");
21613 if (virTypedParamsAddUInt(&record
->params
, &record
->nparams
,
21614 maxparams
, param_name
, nresdata
) < 0)
21617 for (i
= 0; i
< nresdata
; i
++) {
21618 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21619 "cpu.cache.monitor.%zu.name", i
);
21620 if (virTypedParamsAddString(&record
->params
,
21624 resdata
[i
]->name
) < 0)
21627 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21628 "cpu.cache.monitor.%zu.vcpus", i
);
21629 if (virTypedParamsAddString(&record
->params
, &record
->nparams
,
21630 maxparams
, param_name
,
21631 resdata
[i
]->vcpus
) < 0)
21634 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21635 "cpu.cache.monitor.%zu.bank.count", i
);
21636 if (virTypedParamsAddUInt(&record
->params
, &record
->nparams
,
21637 maxparams
, param_name
,
21638 resdata
[i
]->nstats
) < 0)
21641 for (j
= 0; j
< resdata
[i
]->nstats
; j
++) {
21642 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21643 "cpu.cache.monitor.%zu.bank.%zu.id", i
, j
);
21644 if (virTypedParamsAddUInt(&record
->params
, &record
->nparams
,
21645 maxparams
, param_name
,
21646 resdata
[i
]->stats
[j
]->id
) < 0)
21649 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21650 "cpu.cache.monitor.%zu.bank.%zu.bytes", i
, j
);
21651 if (virTypedParamsAddUInt(&record
->params
, &record
->nparams
,
21652 maxparams
, param_name
,
21653 resdata
[i
]->stats
[j
]->val
) < 0)
21660 for (i
= 0; i
< nresdata
; i
++)
21661 qemuDomainFreeResctrlMonData(resdata
[i
]);
21668 qemuDomainGetStatsCpuCgroup(virDomainObjPtr dom
,
21669 virDomainStatsRecordPtr record
,
21672 qemuDomainObjPrivatePtr priv
= dom
->privateData
;
21673 unsigned long long cpu_time
= 0;
21674 unsigned long long user_time
= 0;
21675 unsigned long long sys_time
= 0;
21681 err
= virCgroupGetCpuacctUsage(priv
->cgroup
, &cpu_time
);
21682 if (!err
&& virTypedParamsAddULLong(&record
->params
,
21689 err
= virCgroupGetCpuacctStat(priv
->cgroup
, &user_time
, &sys_time
);
21690 if (!err
&& virTypedParamsAddULLong(&record
->params
,
21696 if (!err
&& virTypedParamsAddULLong(&record
->params
,
21708 qemuDomainGetStatsCpu(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
21709 virDomainObjPtr dom
,
21710 virDomainStatsRecordPtr record
,
21712 unsigned int privflags ATTRIBUTE_UNUSED
)
21714 if (qemuDomainGetStatsCpuCgroup(dom
, record
, maxparams
) < 0)
21717 if (qemuDomainGetStatsCpuCache(dom
, record
, maxparams
) < 0)
21725 qemuDomainGetStatsBalloon(virQEMUDriverPtr driver
,
21726 virDomainObjPtr dom
,
21727 virDomainStatsRecordPtr record
,
21729 unsigned int privflags
)
21731 virDomainMemoryStatStruct stats
[VIR_DOMAIN_MEMORY_STAT_NR
];
21733 unsigned long long cur_balloon
= 0;
21736 if (!virDomainDefHasMemballoon(dom
->def
)) {
21737 cur_balloon
= virDomainDefGetMemoryTotal(dom
->def
);
21739 cur_balloon
= dom
->def
->mem
.cur_balloon
;
21742 if (virTypedParamsAddULLong(&record
->params
,
21749 if (virTypedParamsAddULLong(&record
->params
,
21753 virDomainDefGetMemoryTotal(dom
->def
)) < 0)
21756 if (!HAVE_JOB(privflags
) || !virDomainObjIsActive(dom
))
21759 nr_stats
= qemuDomainMemoryStatsInternal(driver
, dom
, stats
,
21760 VIR_DOMAIN_MEMORY_STAT_NR
);
21764 #define STORE_MEM_RECORD(TAG, NAME) \
21765 if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_ ##TAG) \
21766 if (virTypedParamsAddULLong(&record->params, \
21767 &record->nparams, \
21770 stats[i].val) < 0) \
21773 for (i
= 0; i
< nr_stats
; i
++) {
21774 STORE_MEM_RECORD(SWAP_IN
, "swap_in")
21775 STORE_MEM_RECORD(SWAP_OUT
, "swap_out")
21776 STORE_MEM_RECORD(MAJOR_FAULT
, "major_fault")
21777 STORE_MEM_RECORD(MINOR_FAULT
, "minor_fault")
21778 STORE_MEM_RECORD(UNUSED
, "unused")
21779 STORE_MEM_RECORD(AVAILABLE
, "available")
21780 STORE_MEM_RECORD(RSS
, "rss")
21781 STORE_MEM_RECORD(LAST_UPDATE
, "last-update")
21782 STORE_MEM_RECORD(USABLE
, "usable")
21783 STORE_MEM_RECORD(DISK_CACHES
, "disk_caches")
21786 #undef STORE_MEM_RECORD
21793 qemuDomainGetStatsVcpu(virQEMUDriverPtr driver
,
21794 virDomainObjPtr dom
,
21795 virDomainStatsRecordPtr record
,
21797 unsigned int privflags
)
21799 virDomainVcpuDefPtr vcpu
;
21800 qemuDomainVcpuPrivatePtr vcpupriv
;
21803 char param_name
[VIR_TYPED_PARAM_FIELD_LENGTH
];
21804 virVcpuInfoPtr cpuinfo
= NULL
;
21805 unsigned long long *cpuwait
= NULL
;
21807 if (virTypedParamsAddUInt(&record
->params
,
21811 virDomainDefGetVcpus(dom
->def
)) < 0)
21814 if (virTypedParamsAddUInt(&record
->params
,
21818 virDomainDefGetVcpusMax(dom
->def
)) < 0)
21821 if (VIR_ALLOC_N(cpuinfo
, virDomainDefGetVcpus(dom
->def
)) < 0 ||
21822 VIR_ALLOC_N(cpuwait
, virDomainDefGetVcpus(dom
->def
)) < 0)
21825 if (HAVE_JOB(privflags
) && virDomainObjIsActive(dom
) &&
21826 qemuDomainRefreshVcpuHalted(driver
, dom
, QEMU_ASYNC_JOB_NONE
) < 0) {
21827 /* it's ok to be silent and go ahead, because halted vcpu info
21828 * wasn't here from the beginning */
21829 virResetLastError();
21832 if (qemuDomainHelperGetVcpus(dom
, cpuinfo
, cpuwait
,
21833 virDomainDefGetVcpus(dom
->def
),
21835 virResetLastError();
21836 ret
= 0; /* it's ok to be silent and go ahead */
21840 for (i
= 0; i
< virDomainDefGetVcpus(dom
->def
); i
++) {
21841 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21842 "vcpu.%u.state", cpuinfo
[i
].number
);
21843 if (virTypedParamsAddInt(&record
->params
,
21847 cpuinfo
[i
].state
) < 0)
21850 /* stats below are available only if the VM is alive */
21851 if (!virDomainObjIsActive(dom
))
21854 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21855 "vcpu.%u.time", cpuinfo
[i
].number
);
21856 if (virTypedParamsAddULLong(&record
->params
,
21860 cpuinfo
[i
].cpuTime
) < 0)
21862 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21863 "vcpu.%u.wait", cpuinfo
[i
].number
);
21864 if (virTypedParamsAddULLong(&record
->params
,
21871 /* state below is extracted from the individual vcpu structs */
21872 if (!(vcpu
= virDomainDefGetVcpu(dom
->def
, cpuinfo
[i
].number
)))
21875 vcpupriv
= QEMU_DOMAIN_VCPU_PRIVATE(vcpu
);
21877 if (vcpupriv
->halted
!= VIR_TRISTATE_BOOL_ABSENT
) {
21878 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21879 "vcpu.%u.halted", cpuinfo
[i
].number
);
21880 if (virTypedParamsAddBoolean(&record
->params
,
21884 vcpupriv
->halted
== VIR_TRISTATE_BOOL_YES
) < 0)
21897 #define QEMU_ADD_COUNT_PARAM(record, maxparams, type, count) \
21899 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
21900 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "%s.count", type); \
21901 if (virTypedParamsAddUInt(&(record)->params, \
21902 &(record)->nparams, \
21909 #define QEMU_ADD_NAME_PARAM(record, maxparams, type, subtype, num, name) \
21911 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
21912 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
21913 "%s.%zu.%s", type, num, subtype); \
21914 if (virTypedParamsAddString(&(record)->params, \
21915 &(record)->nparams, \
21922 #define QEMU_ADD_NET_PARAM(record, maxparams, num, name, value) \
21924 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
21925 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
21926 "net.%zu.%s", num, name); \
21927 if (value >= 0 && virTypedParamsAddULLong(&(record)->params, \
21928 &(record)->nparams, \
21936 qemuDomainGetStatsInterface(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
21937 virDomainObjPtr dom
,
21938 virDomainStatsRecordPtr record
,
21940 unsigned int privflags ATTRIBUTE_UNUSED
)
21943 struct _virDomainInterfaceStats tmp
;
21946 if (!virDomainObjIsActive(dom
))
21949 QEMU_ADD_COUNT_PARAM(record
, maxparams
, "net", dom
->def
->nnets
);
21951 /* Check the path is one of the domain's network interfaces. */
21952 for (i
= 0; i
< dom
->def
->nnets
; i
++) {
21953 virDomainNetDefPtr net
= dom
->def
->nets
[i
];
21954 virDomainNetType actualType
;
21959 memset(&tmp
, 0, sizeof(tmp
));
21961 actualType
= virDomainNetGetActualType(net
);
21963 QEMU_ADD_NAME_PARAM(record
, maxparams
,
21964 "net", "name", i
, net
->ifname
);
21966 if (actualType
== VIR_DOMAIN_NET_TYPE_VHOSTUSER
) {
21967 if (virNetDevOpenvswitchInterfaceStats(net
->ifname
, &tmp
) < 0) {
21968 virResetLastError();
21972 if (virNetDevTapInterfaceStats(net
->ifname
, &tmp
,
21973 !virDomainNetTypeSharesHostView(net
)) < 0) {
21974 virResetLastError();
21979 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
21980 "rx.bytes", tmp
.rx_bytes
);
21981 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
21982 "rx.pkts", tmp
.rx_packets
);
21983 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
21984 "rx.errs", tmp
.rx_errs
);
21985 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
21986 "rx.drop", tmp
.rx_drop
);
21987 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
21988 "tx.bytes", tmp
.tx_bytes
);
21989 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
21990 "tx.pkts", tmp
.tx_packets
);
21991 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
21992 "tx.errs", tmp
.tx_errs
);
21993 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
21994 "tx.drop", tmp
.tx_drop
);
22002 #undef QEMU_ADD_NET_PARAM
22004 #define QEMU_ADD_BLOCK_PARAM_UI(record, maxparams, num, name, value) \
22006 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22007 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22008 "block.%zu.%s", num, name); \
22009 if (virTypedParamsAddUInt(&(record)->params, \
22010 &(record)->nparams, \
22017 /* expects a LL, but typed parameter must be ULL */
22018 #define QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, num, name, value) \
22020 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22021 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22022 "block.%zu.%s", num, name); \
22023 if (value >= 0 && virTypedParamsAddULLong(&(record)->params, \
22024 &(record)->nparams, \
22031 #define QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, num, name, value) \
22033 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22034 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22035 "block.%zu.%s", num, name); \
22036 if (virTypedParamsAddULLong(&(record)->params, \
22037 &(record)->nparams, \
22044 /* refresh information by opening images on the disk */
22046 qemuDomainGetStatsOneBlockFallback(virQEMUDriverPtr driver
,
22047 virQEMUDriverConfigPtr cfg
,
22048 virDomainObjPtr dom
,
22049 virDomainStatsRecordPtr record
,
22051 virStorageSourcePtr src
,
22056 if (virStorageSourceIsEmpty(src
))
22059 if (qemuStorageLimitsRefresh(driver
, cfg
, dom
, src
) < 0) {
22060 virResetLastError();
22064 if (src
->allocation
)
22065 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22066 "allocation", src
->allocation
);
22068 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22069 "capacity", src
->capacity
);
22071 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22072 "physical", src
->physical
);
22080 * qemuDomainGetStatsOneBlockRefreshNamed:
22081 * @src: disk source structure
22082 * @alias: disk alias
22083 * @stats: hash table containing stats for all disks
22084 * @nodedata: reply containing 'query-named-block-nodes' data
22086 * Refresh disk block stats data (qemuBlockStatsPtr) which are present only
22087 * in the reply of 'query-named-block-nodes' in cases when the data was gathered
22088 * by using query-block originally.
22091 qemuDomainGetStatsOneBlockRefreshNamed(virStorageSourcePtr src
,
22093 virHashTablePtr stats
,
22094 virHashTablePtr nodedata
)
22096 qemuBlockStatsPtr entry
;
22098 virJSONValuePtr data
;
22099 unsigned long long tmp
;
22101 if (!nodedata
|| !src
->nodestorage
)
22104 if (!(entry
= virHashLookup(stats
, alias
)))
22107 if (!(data
= virHashLookup(nodedata
, src
->nodestorage
)))
22110 if (virJSONValueObjectGetNumberUlong(data
, "write_threshold", &tmp
) == 0)
22111 entry
->write_threshold
= tmp
;
22116 qemuDomainGetStatsOneBlock(virQEMUDriverPtr driver
,
22117 virQEMUDriverConfigPtr cfg
,
22118 virDomainObjPtr dom
,
22119 virDomainStatsRecordPtr record
,
22121 const char *entryname
,
22122 virStorageSourcePtr src
,
22124 virHashTablePtr stats
)
22126 qemuBlockStats
*entry
;
22129 /* the VM is offline so we have to go and load the stast from the disk by
22131 if (!virDomainObjIsActive(dom
)) {
22132 ret
= qemuDomainGetStatsOneBlockFallback(driver
, cfg
, dom
, record
,
22133 maxparams
, src
, block_idx
);
22137 /* In case where qemu didn't provide the stats we stop here rather than
22138 * trying to refresh the stats from the disk. Inability to provide stats is
22139 * usually caused by blocked storage so this would make libvirtd hang */
22140 if (!stats
|| !entryname
|| !(entry
= virHashLookup(stats
, entryname
))) {
22145 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22146 "allocation", entry
->wr_highest_offset
);
22148 if (entry
->capacity
)
22149 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22150 "capacity", entry
->capacity
);
22151 if (entry
->physical
) {
22152 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22153 "physical", entry
->physical
);
22155 if (qemuDomainStorageUpdatePhysical(driver
, cfg
, dom
, src
) == 0) {
22156 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22157 "physical", src
->physical
);
22159 virResetLastError();
22170 qemuDomainGetStatsBlockExportBackendStorage(const char *entryname
,
22171 virHashTablePtr stats
,
22173 virDomainStatsRecordPtr records
,
22176 qemuBlockStats
*entry
;
22179 if (!stats
|| !entryname
|| !(entry
= virHashLookup(stats
, entryname
))) {
22184 if (entry
->write_threshold
)
22185 QEMU_ADD_BLOCK_PARAM_ULL(records
, nrecords
, recordnr
, "threshold",
22186 entry
->write_threshold
);
22195 qemuDomainGetStatsBlockExportFrontend(const char *frontendname
,
22196 virHashTablePtr stats
,
22198 virDomainStatsRecordPtr records
,
22201 qemuBlockStats
*entry
;
22204 /* In case where qemu didn't provide the stats we stop here rather than
22205 * trying to refresh the stats from the disk. Inability to provide stats is
22206 * usually caused by blocked storage so this would make libvirtd hang */
22207 if (!stats
|| !frontendname
|| !(entry
= virHashLookup(stats
, frontendname
))) {
22212 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "rd.reqs", entry
->rd_req
);
22213 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "rd.bytes", entry
->rd_bytes
);
22214 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "rd.times", entry
->rd_total_times
);
22215 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "wr.reqs", entry
->wr_req
);
22216 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "wr.bytes", entry
->wr_bytes
);
22217 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "wr.times", entry
->wr_total_times
);
22218 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "fl.reqs", entry
->flush_req
);
22219 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "fl.times", entry
->flush_total_times
);
22228 qemuDomainGetStatsBlockExportHeader(virDomainDiskDefPtr disk
,
22229 virStorageSourcePtr src
,
22231 virDomainStatsRecordPtr records
,
22236 QEMU_ADD_NAME_PARAM(records
, nrecords
, "block", "name", recordnr
, disk
->dst
);
22238 if (virStorageSourceIsLocalStorage(src
) && src
->path
)
22239 QEMU_ADD_NAME_PARAM(records
, nrecords
, "block", "path", recordnr
, src
->path
);
22241 QEMU_ADD_BLOCK_PARAM_UI(records
, nrecords
, recordnr
, "backingIndex",
22251 qemuDomainGetStatsBlockExportDisk(virDomainDiskDefPtr disk
,
22252 virHashTablePtr stats
,
22253 virHashTablePtr nodestats
,
22254 virDomainStatsRecordPtr records
,
22258 virQEMUDriverPtr driver
,
22259 virQEMUDriverConfigPtr cfg
,
22260 virDomainObjPtr dom
,
22264 char *alias
= NULL
;
22265 virStorageSourcePtr n
;
22266 const char *frontendalias
;
22267 const char *backendalias
;
22268 const char *backendstoragealias
;
22272 * This helps to keep logs clean from error messages on getting stats
22273 * for optional disk with nonexistent source file. We won't get any
22274 * stats for such a disk anyway in below code.
22276 if (!virDomainObjIsActive(dom
) &&
22277 qemuDomainDiskIsMissingLocalOptional(disk
)) {
22278 VIR_INFO("optional disk '%s' source file is missing, "
22279 "skip getting stats", disk
->dst
);
22281 return qemuDomainGetStatsBlockExportHeader(disk
, disk
->src
, *recordnr
,
22282 records
, nrecords
);
22285 for (n
= disk
->src
; virStorageSourceIsBacking(n
); n
= n
->backingStore
) {
22287 frontendalias
= QEMU_DOMAIN_DISK_PRIVATE(disk
)->qomName
;
22288 backendalias
= n
->nodeformat
;
22289 backendstoragealias
= n
->nodestorage
;
22291 /* alias may be NULL if the VM is not running */
22292 if (disk
->info
.alias
&&
22293 !(alias
= qemuDomainStorageAlias(disk
->info
.alias
, n
->id
)))
22296 qemuDomainGetStatsOneBlockRefreshNamed(n
, alias
, stats
, nodestats
);
22298 frontendalias
= alias
;
22299 backendalias
= alias
;
22300 backendstoragealias
= alias
;
22303 if (qemuDomainGetStatsBlockExportHeader(disk
, n
, *recordnr
,
22304 records
, nrecords
) < 0)
22307 /* The following stats make sense only for the frontend device */
22308 if (n
== disk
->src
) {
22309 if (qemuDomainGetStatsBlockExportFrontend(frontendalias
, stats
, *recordnr
,
22310 records
, nrecords
) < 0)
22314 if (qemuDomainGetStatsOneBlock(driver
, cfg
, dom
, records
, nrecords
,
22315 backendalias
, n
, *recordnr
,
22319 if (qemuDomainGetStatsBlockExportBackendStorage(backendstoragealias
,
22321 records
, nrecords
) < 0)
22340 qemuDomainGetStatsBlock(virQEMUDriverPtr driver
,
22341 virDomainObjPtr dom
,
22342 virDomainStatsRecordPtr record
,
22344 unsigned int privflags
)
22349 virHashTablePtr stats
= NULL
;
22350 virHashTablePtr nodestats
= NULL
;
22351 virJSONValuePtr nodedata
= NULL
;
22352 qemuDomainObjPrivatePtr priv
= dom
->privateData
;
22353 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
22354 bool blockdev
= virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
);
22355 bool fetchnodedata
= virQEMUCapsGet(priv
->qemuCaps
,
22356 QEMU_CAPS_QUERY_NAMED_BLOCK_NODES
) && !blockdev
;
22357 int count_index
= -1;
22358 size_t visited
= 0;
22359 bool visitBacking
= !!(privflags
& QEMU_DOMAIN_STATS_BACKING
);
22361 if (HAVE_JOB(privflags
) && virDomainObjIsActive(dom
)) {
22362 qemuDomainObjEnterMonitor(driver
, dom
);
22364 rc
= qemuMonitorGetAllBlockStatsInfo(priv
->mon
, &stats
, visitBacking
);
22368 rc
= qemuMonitorBlockStatsUpdateCapacityBlockdev(priv
->mon
, stats
);
22370 ignore_value(qemuMonitorBlockStatsUpdateCapacity(priv
->mon
, stats
,
22375 nodedata
= qemuMonitorQueryNamedBlockNodes(priv
->mon
);
22377 if (qemuDomainObjExitMonitor(driver
, dom
) < 0)
22380 /* failure to retrieve stats is fine at this point */
22381 if (rc
< 0 || (fetchnodedata
&& !nodedata
))
22382 virResetLastError();
22386 !(nodestats
= qemuBlockGetNodeData(nodedata
)))
22389 /* When listing backing chains, it's easier to fix up the count
22390 * after the iteration than it is to iterate twice; but we still
22391 * want count listed first. */
22392 count_index
= record
->nparams
;
22393 QEMU_ADD_COUNT_PARAM(record
, maxparams
, "block", 0);
22395 for (i
= 0; i
< dom
->def
->ndisks
; i
++) {
22396 if (qemuDomainGetStatsBlockExportDisk(dom
->def
->disks
[i
], stats
, nodestats
,
22397 record
, maxparams
, &visited
,
22398 visitBacking
, driver
, cfg
, dom
,
22403 record
->params
[count_index
].value
.ui
= visited
;
22407 virHashFree(stats
);
22408 virHashFree(nodestats
);
22409 virJSONValueFree(nodedata
);
22410 virObjectUnref(cfg
);
22414 #undef QEMU_ADD_BLOCK_PARAM_LL
22416 #undef QEMU_ADD_BLOCK_PARAM_ULL
22418 #undef QEMU_ADD_NAME_PARAM
22420 #define QEMU_ADD_IOTHREAD_PARAM_UI(record, maxparams, id, name, value) \
22422 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22423 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22424 "iothread.%u.%s", id, name); \
22425 if (virTypedParamsAddUInt(&(record)->params, \
22426 &(record)->nparams, \
22433 #define QEMU_ADD_IOTHREAD_PARAM_ULL(record, maxparams, id, name, value) \
22435 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22436 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22437 "iothread.%u.%s", id, name); \
22438 if (virTypedParamsAddULLong(&(record)->params, \
22439 &(record)->nparams, \
22447 qemuDomainGetStatsIOThread(virQEMUDriverPtr driver
,
22448 virDomainObjPtr dom
,
22449 virDomainStatsRecordPtr record
,
22451 unsigned int privflags ATTRIBUTE_UNUSED
)
22453 qemuDomainObjPrivatePtr priv
= dom
->privateData
;
22455 qemuMonitorIOThreadInfoPtr
*iothreads
= NULL
;
22459 if (!virDomainObjIsActive(dom
))
22462 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_OBJECT_IOTHREAD
))
22465 if ((niothreads
= qemuDomainGetIOThreadsMon(driver
, dom
, &iothreads
)) < 0)
22468 if (niothreads
== 0)
22471 QEMU_ADD_COUNT_PARAM(record
, maxparams
, "iothread", niothreads
);
22473 for (i
= 0; i
< niothreads
; i
++) {
22474 if (iothreads
[i
]->poll_valid
) {
22475 QEMU_ADD_IOTHREAD_PARAM_ULL(record
, maxparams
,
22476 iothreads
[i
]->iothread_id
,
22478 iothreads
[i
]->poll_max_ns
);
22479 QEMU_ADD_IOTHREAD_PARAM_UI(record
, maxparams
,
22480 iothreads
[i
]->iothread_id
,
22482 iothreads
[i
]->poll_grow
);
22483 QEMU_ADD_IOTHREAD_PARAM_UI(record
, maxparams
,
22484 iothreads
[i
]->iothread_id
,
22486 iothreads
[i
]->poll_shrink
);
22493 for (i
= 0; i
< niothreads
; i
++)
22494 VIR_FREE(iothreads
[i
]);
22495 VIR_FREE(iothreads
);
22500 #undef QEMU_ADD_IOTHREAD_PARAM_UI
22502 #undef QEMU_ADD_IOTHREAD_PARAM_ULL
22504 #undef QEMU_ADD_COUNT_PARAM
22507 qemuDomainGetStatsPerfOneEvent(virPerfPtr perf
,
22508 virPerfEventType type
,
22509 virDomainStatsRecordPtr record
,
22512 char param_name
[VIR_TYPED_PARAM_FIELD_LENGTH
];
22513 uint64_t value
= 0;
22515 if (virPerfReadEvent(perf
, type
, &value
) < 0)
22518 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
, "perf.%s",
22519 virPerfEventTypeToString(type
));
22521 if (virTypedParamsAddULLong(&record
->params
,
22532 qemuDomainGetStatsPerf(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
22533 virDomainObjPtr dom
,
22534 virDomainStatsRecordPtr record
,
22536 unsigned int privflags ATTRIBUTE_UNUSED
)
22539 qemuDomainObjPrivatePtr priv
= dom
->privateData
;
22542 for (i
= 0; i
< VIR_PERF_EVENT_LAST
; i
++) {
22543 if (!virPerfEventIsEnabled(priv
->perf
, i
))
22546 if (qemuDomainGetStatsPerfOneEvent(priv
->perf
, i
,
22547 record
, maxparams
) < 0)
22558 (*qemuDomainGetStatsFunc
)(virQEMUDriverPtr driver
,
22559 virDomainObjPtr dom
,
22560 virDomainStatsRecordPtr record
,
22562 unsigned int flags
);
22564 struct qemuDomainGetStatsWorker
{
22565 qemuDomainGetStatsFunc func
;
22566 unsigned int stats
;
22570 static struct qemuDomainGetStatsWorker qemuDomainGetStatsWorkers
[] = {
22571 { qemuDomainGetStatsState
, VIR_DOMAIN_STATS_STATE
, false },
22572 { qemuDomainGetStatsCpu
, VIR_DOMAIN_STATS_CPU_TOTAL
, false },
22573 { qemuDomainGetStatsBalloon
, VIR_DOMAIN_STATS_BALLOON
, true },
22574 { qemuDomainGetStatsVcpu
, VIR_DOMAIN_STATS_VCPU
, true },
22575 { qemuDomainGetStatsInterface
, VIR_DOMAIN_STATS_INTERFACE
, false },
22576 { qemuDomainGetStatsBlock
, VIR_DOMAIN_STATS_BLOCK
, true },
22577 { qemuDomainGetStatsPerf
, VIR_DOMAIN_STATS_PERF
, false },
22578 { qemuDomainGetStatsIOThread
, VIR_DOMAIN_STATS_IOTHREAD
, true },
22584 qemuDomainGetStatsCheckSupport(unsigned int *stats
,
22587 unsigned int supportedstats
= 0;
22590 for (i
= 0; qemuDomainGetStatsWorkers
[i
].func
; i
++)
22591 supportedstats
|= qemuDomainGetStatsWorkers
[i
].stats
;
22594 *stats
= supportedstats
;
22599 *stats
& ~supportedstats
) {
22600 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
,
22601 _("Stats types bits 0x%x are not supported by this daemon"),
22602 *stats
& ~supportedstats
);
22606 *stats
&= supportedstats
;
22612 qemuDomainGetStatsNeedMonitor(unsigned int stats
)
22616 for (i
= 0; qemuDomainGetStatsWorkers
[i
].func
; i
++)
22617 if (stats
& qemuDomainGetStatsWorkers
[i
].stats
&&
22618 qemuDomainGetStatsWorkers
[i
].monitor
)
22626 qemuDomainGetStats(virConnectPtr conn
,
22627 virDomainObjPtr dom
,
22628 unsigned int stats
,
22629 virDomainStatsRecordPtr
*record
,
22630 unsigned int flags
)
22633 virDomainStatsRecordPtr tmp
;
22637 if (VIR_ALLOC(tmp
) < 0)
22640 for (i
= 0; qemuDomainGetStatsWorkers
[i
].func
; i
++) {
22641 if (stats
& qemuDomainGetStatsWorkers
[i
].stats
) {
22642 if (qemuDomainGetStatsWorkers
[i
].func(conn
->privateData
, dom
, tmp
,
22643 &maxparams
, flags
) < 0)
22648 if (!(tmp
->dom
= virGetDomain(conn
, dom
->def
->name
,
22649 dom
->def
->uuid
, dom
->def
->id
)))
22658 virTypedParamsFree(tmp
->params
, tmp
->nparams
);
22667 qemuConnectGetAllDomainStats(virConnectPtr conn
,
22668 virDomainPtr
*doms
,
22669 unsigned int ndoms
,
22670 unsigned int stats
,
22671 virDomainStatsRecordPtr
**retStats
,
22672 unsigned int flags
)
22674 virQEMUDriverPtr driver
= conn
->privateData
;
22675 virErrorPtr orig_err
= NULL
;
22676 virDomainObjPtr
*vms
= NULL
;
22677 virDomainObjPtr vm
;
22679 virDomainStatsRecordPtr
*tmpstats
= NULL
;
22680 bool enforce
= !!(flags
& VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS
);
22684 unsigned int privflags
= 0;
22685 unsigned int domflags
= 0;
22686 unsigned int lflags
= flags
& (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE
|
22687 VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT
|
22688 VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE
);
22690 virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE
|
22691 VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT
|
22692 VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE
|
22693 VIR_CONNECT_GET_ALL_DOMAINS_STATS_NOWAIT
|
22694 VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING
|
22695 VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS
, -1);
22697 if (virConnectGetAllDomainStatsEnsureACL(conn
) < 0)
22700 if (qemuDomainGetStatsCheckSupport(&stats
, enforce
) < 0)
22704 if (virDomainObjListConvert(driver
->domains
, conn
, doms
, ndoms
, &vms
,
22705 &nvms
, virConnectGetAllDomainStatsCheckACL
,
22709 if (virDomainObjListCollect(driver
->domains
, conn
, &vms
, &nvms
,
22710 virConnectGetAllDomainStatsCheckACL
,
22715 if (VIR_ALLOC_N(tmpstats
, nvms
+ 1) < 0)
22718 if (qemuDomainGetStatsNeedMonitor(stats
))
22719 privflags
|= QEMU_DOMAIN_STATS_HAVE_JOB
;
22721 for (i
= 0; i
< nvms
; i
++) {
22722 virDomainStatsRecordPtr tmp
= NULL
;
22728 if (HAVE_JOB(privflags
)) {
22731 if (flags
& VIR_CONNECT_GET_ALL_DOMAINS_STATS_NOWAIT
)
22732 rv
= qemuDomainObjBeginJobNowait(driver
, vm
, QEMU_JOB_QUERY
);
22734 rv
= qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
);
22737 domflags
|= QEMU_DOMAIN_STATS_HAVE_JOB
;
22739 /* else: without a job it's still possible to gather some data */
22741 if (flags
& VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING
)
22742 domflags
|= QEMU_DOMAIN_STATS_BACKING
;
22743 if (qemuDomainGetStats(conn
, vm
, stats
, &tmp
, domflags
) < 0) {
22744 if (HAVE_JOB(domflags
) && vm
)
22745 qemuDomainObjEndJob(driver
, vm
);
22747 virObjectUnlock(vm
);
22752 tmpstats
[nstats
++] = tmp
;
22754 if (HAVE_JOB(domflags
))
22755 qemuDomainObjEndJob(driver
, vm
);
22757 virObjectUnlock(vm
);
22760 *retStats
= tmpstats
;
22766 virErrorPreserveLast(&orig_err
);
22767 virDomainStatsRecordListFree(tmpstats
);
22768 virObjectListFreeCount(vms
, nvms
);
22769 virErrorRestore(&orig_err
);
22776 qemuNodeAllocPages(virConnectPtr conn
,
22777 unsigned int npages
,
22778 unsigned int *pageSizes
,
22779 unsigned long long *pageCounts
,
22781 unsigned int cellCount
,
22782 unsigned int flags
)
22784 bool add
= !(flags
& VIR_NODE_ALLOC_PAGES_SET
);
22786 virCheckFlags(VIR_NODE_ALLOC_PAGES_SET
, -1);
22788 if (virNodeAllocPagesEnsureACL(conn
) < 0)
22791 return virHostMemAllocPages(npages
, pageSizes
, pageCounts
,
22792 startCell
, cellCount
, add
);
22797 qemuDomainGetFSInfo(virDomainPtr dom
,
22798 virDomainFSInfoPtr
**info
,
22799 unsigned int flags
)
22801 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
22802 virDomainObjPtr vm
;
22803 qemuAgentPtr agent
;
22804 virCapsPtr caps
= NULL
;
22805 virDomainDefPtr def
= NULL
;
22808 virCheckFlags(0, ret
);
22810 if (!(vm
= qemuDomObjFromDomain(dom
)))
22813 if (virDomainGetFSInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
22816 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
22819 if (virDomainObjCheckActive(vm
) < 0)
22822 if (!qemuDomainAgentAvailable(vm
, true))
22825 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
22828 if (!(def
= virDomainDefCopy(vm
->def
, caps
, driver
->xmlopt
, NULL
, false)))
22831 agent
= qemuDomainObjEnterAgent(vm
);
22832 ret
= qemuAgentGetFSInfo(agent
, info
, def
);
22833 qemuDomainObjExitAgent(vm
, agent
);
22836 qemuDomainObjEndAgentJob(vm
);
22839 virDomainObjEndAPI(&vm
);
22840 virDomainDefFree(def
);
22841 virObjectUnref(caps
);
22846 qemuDomainInterfaceAddresses(virDomainPtr dom
,
22847 virDomainInterfacePtr
**ifaces
,
22848 unsigned int source
,
22849 unsigned int flags
)
22851 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
22852 virDomainObjPtr vm
= NULL
;
22853 qemuAgentPtr agent
;
22856 virCheckFlags(0, -1);
22858 if (!(vm
= qemuDomObjFromDomain(dom
)))
22861 if (virDomainInterfaceAddressesEnsureACL(dom
->conn
, vm
->def
) < 0)
22864 if (virDomainObjCheckActive(vm
) < 0)
22868 case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE
:
22869 ret
= qemuGetDHCPInterfaces(dom
, vm
, ifaces
);
22872 case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT
:
22873 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
22876 if (!qemuDomainAgentAvailable(vm
, true))
22879 agent
= qemuDomainObjEnterAgent(vm
);
22880 ret
= qemuAgentGetInterfaces(agent
, ifaces
);
22881 qemuDomainObjExitAgent(vm
, agent
);
22884 qemuDomainObjEndAgentJob(vm
);
22888 case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP
:
22889 ret
= qemuARPGetInterfaces(vm
, ifaces
);
22893 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
,
22894 _("Unknown IP address data source %d"),
22900 virDomainObjEndAPI(&vm
);
22905 qemuGetDHCPInterfaces(virDomainPtr dom
,
22906 virDomainObjPtr vm
,
22907 virDomainInterfacePtr
**ifaces
)
22912 size_t ifaces_count
= 0;
22913 virNetworkPtr network
= NULL
;
22914 char macaddr
[VIR_MAC_STRING_BUFLEN
];
22915 virDomainInterfacePtr iface
= NULL
;
22916 virNetworkDHCPLeasePtr
*leases
= NULL
;
22917 virDomainInterfacePtr
*ifaces_ret
= NULL
;
22919 if (!dom
->conn
->networkDriver
||
22920 !dom
->conn
->networkDriver
->networkGetDHCPLeases
) {
22921 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
22922 _("Network driver does not support DHCP lease query"));
22926 for (i
= 0; i
< vm
->def
->nnets
; i
++) {
22927 if (vm
->def
->nets
[i
]->type
!= VIR_DOMAIN_NET_TYPE_NETWORK
)
22930 virMacAddrFormat(&(vm
->def
->nets
[i
]->mac
), macaddr
);
22931 virObjectUnref(network
);
22932 network
= virNetworkLookupByName(dom
->conn
,
22933 vm
->def
->nets
[i
]->data
.network
.name
);
22935 if ((n_leases
= virNetworkGetDHCPLeases(network
, macaddr
,
22940 if (VIR_EXPAND_N(ifaces_ret
, ifaces_count
, 1) < 0)
22943 if (VIR_ALLOC(ifaces_ret
[ifaces_count
- 1]) < 0)
22946 iface
= ifaces_ret
[ifaces_count
- 1];
22947 /* Assuming each lease corresponds to a separate IP */
22948 iface
->naddrs
= n_leases
;
22950 if (VIR_ALLOC_N(iface
->addrs
, iface
->naddrs
) < 0)
22953 if (VIR_STRDUP(iface
->name
, vm
->def
->nets
[i
]->ifname
) < 0)
22956 if (VIR_STRDUP(iface
->hwaddr
, macaddr
) < 0)
22960 for (j
= 0; j
< n_leases
; j
++) {
22961 virNetworkDHCPLeasePtr lease
= leases
[j
];
22962 virDomainIPAddressPtr ip_addr
= &iface
->addrs
[j
];
22964 if (VIR_STRDUP(ip_addr
->addr
, lease
->ipaddr
) < 0)
22967 ip_addr
->type
= lease
->type
;
22968 ip_addr
->prefix
= lease
->prefix
;
22971 for (j
= 0; j
< n_leases
; j
++)
22972 virNetworkDHCPLeaseFree(leases
[j
]);
22977 VIR_STEAL_PTR(*ifaces
, ifaces_ret
);
22981 virObjectUnref(network
);
22983 for (i
= 0; i
< n_leases
; i
++)
22984 virNetworkDHCPLeaseFree(leases
[i
]);
22992 for (i
= 0; i
< ifaces_count
; i
++)
22993 virDomainInterfaceFree(ifaces_ret
[i
]);
22995 VIR_FREE(ifaces_ret
);
23002 qemuARPGetInterfaces(virDomainObjPtr vm
,
23003 virDomainInterfacePtr
**ifaces
)
23006 size_t ifaces_count
= 0;
23008 char macaddr
[VIR_MAC_STRING_BUFLEN
];
23009 virDomainInterfacePtr
*ifaces_ret
= NULL
;
23010 virDomainInterfacePtr iface
= NULL
;
23011 virArpTablePtr table
;
23013 table
= virArpTableGet();
23017 for (i
= 0; i
< vm
->def
->nnets
; i
++) {
23018 virMacAddrFormat(&(vm
->def
->nets
[i
]->mac
), macaddr
);
23019 for (j
= 0; j
< table
->n
; j
++) {
23020 virArpTableEntry entry
= table
->t
[j
];
23022 if (STREQ(entry
.mac
, macaddr
)) {
23023 if (VIR_ALLOC(iface
) < 0)
23026 if (VIR_STRDUP(iface
->name
, vm
->def
->nets
[i
]->ifname
) < 0)
23029 if (VIR_STRDUP(iface
->hwaddr
, macaddr
) < 0)
23032 if (VIR_ALLOC(iface
->addrs
) < 0)
23036 if (VIR_STRDUP(iface
->addrs
->addr
, entry
.ipaddr
) < 0)
23039 if (VIR_APPEND_ELEMENT(ifaces_ret
, ifaces_count
, iface
) < 0)
23045 VIR_STEAL_PTR(*ifaces
, ifaces_ret
);
23046 ret
= ifaces_count
;
23049 virArpTableFree(table
);
23050 virDomainInterfaceFree(iface
);
23053 for (i
= 0; i
< ifaces_count
; i
++)
23054 virDomainInterfaceFree(ifaces_ret
[i
]);
23056 VIR_FREE(ifaces_ret
);
23063 qemuDomainSetUserPassword(virDomainPtr dom
,
23065 const char *password
,
23066 unsigned int flags
)
23068 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23069 virDomainObjPtr vm
;
23070 qemuAgentPtr agent
;
23074 virCheckFlags(VIR_DOMAIN_PASSWORD_ENCRYPTED
, -1);
23076 if (!(vm
= qemuDomObjFromDomain(dom
)))
23079 if (virDomainSetUserPasswordEnsureACL(dom
->conn
, vm
->def
) < 0)
23082 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
23085 if (virDomainObjCheckActive(vm
) < 0)
23088 if (!qemuDomainAgentAvailable(vm
, true))
23091 agent
= qemuDomainObjEnterAgent(vm
);
23092 rv
= qemuAgentSetUserPassword(agent
, user
, password
,
23093 flags
& VIR_DOMAIN_PASSWORD_ENCRYPTED
);
23094 qemuDomainObjExitAgent(vm
, agent
);
23102 qemuDomainObjEndAgentJob(vm
);
23105 virDomainObjEndAPI(&vm
);
23111 qemuDomainRenameCallback(virDomainObjPtr vm
,
23112 const char *new_name
,
23113 unsigned int flags
,
23116 virQEMUDriverPtr driver
= opaque
;
23117 virQEMUDriverConfigPtr cfg
= NULL
;
23118 virObjectEventPtr event_new
= NULL
;
23119 virObjectEventPtr event_old
= NULL
;
23121 char *new_dom_name
= NULL
;
23122 char *old_dom_name
= NULL
;
23123 char *new_dom_cfg_file
= NULL
;
23124 char *old_dom_cfg_file
= NULL
;
23125 char *new_dom_autostart_link
= NULL
;
23126 char *old_dom_autostart_link
= NULL
;
23128 virCheckFlags(0, ret
);
23130 if (strchr(new_name
, '/')) {
23131 virReportError(VIR_ERR_XML_ERROR
,
23132 _("name %s cannot contain '/'"), new_name
);
23136 cfg
= virQEMUDriverGetConfig(driver
);
23138 if (VIR_STRDUP(new_dom_name
, new_name
) < 0)
23141 if (!(new_dom_cfg_file
= virDomainConfigFile(cfg
->configDir
,
23143 !(old_dom_cfg_file
= virDomainConfigFile(cfg
->configDir
,
23147 if (vm
->autostart
) {
23148 if (!(new_dom_autostart_link
= virDomainConfigFile(cfg
->autostartDir
,
23150 !(old_dom_autostart_link
= virDomainConfigFile(cfg
->autostartDir
,
23154 if (symlink(new_dom_cfg_file
, new_dom_autostart_link
) < 0) {
23155 virReportSystemError(errno
,
23156 _("Failed to create symlink '%s to '%s'"),
23157 new_dom_autostart_link
, new_dom_cfg_file
);
23162 event_old
= virDomainEventLifecycleNewFromObj(vm
,
23163 VIR_DOMAIN_EVENT_UNDEFINED
,
23164 VIR_DOMAIN_EVENT_UNDEFINED_RENAMED
);
23166 /* Switch name in domain definition. */
23167 old_dom_name
= vm
->def
->name
;
23168 vm
->def
->name
= new_dom_name
;
23169 new_dom_name
= NULL
;
23171 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, vm
->def
) < 0)
23174 if (virFileExists(old_dom_cfg_file
) &&
23175 unlink(old_dom_cfg_file
) < 0) {
23176 virReportSystemError(errno
,
23177 _("cannot remove old domain config file %s"),
23182 if (vm
->autostart
) {
23183 if (virFileIsLink(old_dom_autostart_link
) &&
23184 unlink(old_dom_autostart_link
) < 0) {
23185 virReportSystemError(errno
,
23186 _("Failed to delete symlink '%s'"),
23187 old_dom_autostart_link
);
23192 event_new
= virDomainEventLifecycleNewFromObj(vm
,
23193 VIR_DOMAIN_EVENT_DEFINED
,
23194 VIR_DOMAIN_EVENT_DEFINED_RENAMED
);
23198 VIR_FREE(old_dom_autostart_link
);
23199 VIR_FREE(new_dom_autostart_link
);
23200 VIR_FREE(old_dom_cfg_file
);
23201 VIR_FREE(new_dom_cfg_file
);
23202 VIR_FREE(old_dom_name
);
23203 VIR_FREE(new_dom_name
);
23204 virObjectEventStateQueue(driver
->domainEventState
, event_old
);
23205 virObjectEventStateQueue(driver
->domainEventState
, event_new
);
23206 virObjectUnref(cfg
);
23210 if (old_dom_name
) {
23211 new_dom_name
= vm
->def
->name
;
23212 vm
->def
->name
= old_dom_name
;
23213 old_dom_name
= NULL
;
23216 if (virFileExists(new_dom_cfg_file
))
23217 unlink(new_dom_cfg_file
);
23219 if (vm
->autostart
&&
23220 virFileExists(new_dom_autostart_link
))
23221 unlink(new_dom_autostart_link
);
23226 static int qemuDomainRename(virDomainPtr dom
,
23227 const char *new_name
,
23228 unsigned int flags
)
23230 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23231 virDomainObjPtr vm
= NULL
;
23234 virCheckFlags(0, ret
);
23236 if (!(vm
= qemuDomObjFromDomain(dom
)))
23239 if (virDomainRenameEnsureACL(dom
->conn
, vm
->def
) < 0)
23242 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
23245 if (virDomainObjIsActive(vm
)) {
23246 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
23247 _("cannot rename active domain"));
23251 if (!vm
->persistent
) {
23252 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
23253 _("cannot rename a transient domain"));
23257 if (vm
->hasManagedSave
) {
23258 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
23259 _("domain with a managed saved state can't be renamed"));
23263 if (virDomainObjGetState(vm
, NULL
) != VIR_DOMAIN_SHUTOFF
) {
23264 virReportError(VIR_ERR_OPERATION_INVALID
,
23265 "%s", _("domain has to be shutoff before renaming"));
23269 if (virDomainSnapshotObjListNum(vm
->snapshots
, NULL
, 0) > 0) {
23270 virReportError(VIR_ERR_OPERATION_INVALID
,
23271 "%s", _("cannot rename domain with snapshots"));
23275 if (virDomainListCheckpoints(vm
->checkpoints
, NULL
, dom
, NULL
, flags
) > 0) {
23276 virReportError(VIR_ERR_OPERATION_INVALID
,
23277 "%s", _("cannot rename domain with checkpoints"));
23281 if (virDomainObjListRename(driver
->domains
, vm
, new_name
, flags
,
23282 qemuDomainRenameCallback
, driver
) < 0)
23285 /* Success, domain has been renamed. */
23289 qemuDomainObjEndJob(driver
, vm
);
23292 virDomainObjEndAPI(&vm
);
23298 qemuDomainGetGuestVcpusParams(virTypedParameterPtr
*params
,
23299 unsigned int *nparams
,
23300 qemuAgentCPUInfoPtr info
,
23303 virTypedParameterPtr par
= NULL
;
23306 virBitmapPtr vcpus
= NULL
;
23307 virBitmapPtr online
= NULL
;
23308 virBitmapPtr offlinable
= NULL
;
23313 if (!(vcpus
= virBitmapNew(QEMU_GUEST_VCPU_MAX_ID
)) ||
23314 !(online
= virBitmapNew(QEMU_GUEST_VCPU_MAX_ID
)) ||
23315 !(offlinable
= virBitmapNew(QEMU_GUEST_VCPU_MAX_ID
)))
23318 for (i
= 0; i
< ninfo
; i
++) {
23319 if (virBitmapSetBit(vcpus
, info
[i
].id
) < 0) {
23320 virReportError(VIR_ERR_INTERNAL_ERROR
,
23321 _("vcpu id '%u' reported by guest agent is out of "
23322 "range"), info
[i
].id
);
23326 if (info
[i
].online
)
23327 ignore_value(virBitmapSetBit(online
, info
[i
].id
));
23329 if (info
[i
].offlinable
)
23330 ignore_value(virBitmapSetBit(offlinable
, info
[i
].id
));
23333 #define ADD_BITMAP(name) \
23334 if (!(tmp = virBitmapFormat(name))) \
23336 if (virTypedParamsAddString(&par, &npar, &maxpar, #name, tmp) < 0) \
23341 ADD_BITMAP(online
);
23342 ADD_BITMAP(offlinable
);
23353 virBitmapFree(vcpus
);
23354 virBitmapFree(online
);
23355 virBitmapFree(offlinable
);
23356 virTypedParamsFree(par
, npar
);
23362 qemuDomainGetGuestVcpus(virDomainPtr dom
,
23363 virTypedParameterPtr
*params
,
23364 unsigned int *nparams
,
23365 unsigned int flags
)
23367 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23368 virDomainObjPtr vm
= NULL
;
23369 qemuAgentPtr agent
;
23370 qemuAgentCPUInfoPtr info
= NULL
;
23374 virCheckFlags(0, ret
);
23376 if (!(vm
= qemuDomObjFromDomain(dom
)))
23379 if (virDomainGetGuestVcpusEnsureACL(dom
->conn
, vm
->def
) < 0)
23382 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
23385 if (!qemuDomainAgentAvailable(vm
, true))
23388 agent
= qemuDomainObjEnterAgent(vm
);
23389 ninfo
= qemuAgentGetVCPUs(agent
, &info
);
23390 qemuDomainObjExitAgent(vm
, agent
);
23395 if (qemuDomainGetGuestVcpusParams(params
, nparams
, info
, ninfo
) < 0)
23401 qemuDomainObjEndAgentJob(vm
);
23405 virDomainObjEndAPI(&vm
);
23411 qemuDomainSetGuestVcpus(virDomainPtr dom
,
23412 const char *cpumap
,
23414 unsigned int flags
)
23416 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23417 virDomainObjPtr vm
= NULL
;
23418 virBitmapPtr map
= NULL
;
23419 qemuAgentCPUInfoPtr info
= NULL
;
23420 qemuAgentPtr agent
;
23425 virCheckFlags(0, -1);
23427 if (state
!= 0 && state
!= 1) {
23428 virReportInvalidArg(state
, "%s", _("unsupported state value"));
23432 if (virBitmapParse(cpumap
, &map
, QEMU_GUEST_VCPU_MAX_ID
) < 0)
23435 if (!(vm
= qemuDomObjFromDomain(dom
)))
23438 if (virDomainSetGuestVcpusEnsureACL(dom
->conn
, vm
->def
) < 0)
23441 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
23444 if (!qemuDomainAgentAvailable(vm
, true))
23447 agent
= qemuDomainObjEnterAgent(vm
);
23448 ninfo
= qemuAgentGetVCPUs(agent
, &info
);
23449 qemuDomainObjExitAgent(vm
, agent
);
23455 for (i
= 0; i
< ninfo
; i
++) {
23456 if (!virBitmapIsBitSet(map
, info
[i
].id
))
23459 if (!state
&& !info
[i
].offlinable
) {
23460 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
23461 _("vCPU '%u' is not offlinable"), info
[i
].id
);
23465 info
[i
].online
= !!state
;
23466 info
[i
].modified
= true;
23468 ignore_value(virBitmapClearBit(map
, info
[i
].id
));
23471 if (!virBitmapIsAllClear(map
)) {
23472 char *tmp
= virBitmapFormat(map
);
23473 virReportError(VIR_ERR_INVALID_ARG
,
23474 _("guest is missing vCPUs '%s'"), NULLSTR(tmp
));
23479 if (!qemuDomainAgentAvailable(vm
, true))
23482 agent
= qemuDomainObjEnterAgent(vm
);
23483 ret
= qemuAgentSetVCPUs(agent
, info
, ninfo
);
23484 qemuDomainObjExitAgent(vm
, agent
);
23487 qemuDomainObjEndAgentJob(vm
);
23491 virBitmapFree(map
);
23492 virDomainObjEndAPI(&vm
);
23498 qemuDomainSetVcpu(virDomainPtr dom
,
23499 const char *cpumap
,
23501 unsigned int flags
)
23503 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23504 virDomainObjPtr vm
= NULL
;
23505 virDomainDefPtr def
= NULL
;
23506 virDomainDefPtr persistentDef
= NULL
;
23507 virBitmapPtr map
= NULL
;
23511 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
23512 VIR_DOMAIN_AFFECT_CONFIG
, -1);
23514 if (state
!= 0 && state
!= 1) {
23515 virReportInvalidArg(state
, "%s", _("unsupported state value"));
23519 if (virBitmapParse(cpumap
, &map
, QEMU_GUEST_VCPU_MAX_ID
) < 0)
23522 if ((lastvcpu
= virBitmapLastSetBit(map
)) < 0) {
23523 virReportError(VIR_ERR_INVALID_ARG
, "%s",
23524 _("no vcpus selected for modification"));
23528 if (!(vm
= qemuDomObjFromDomain(dom
)))
23531 if (virDomainSetVcpuEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
23534 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
23537 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
23540 if (persistentDef
) {
23541 if (lastvcpu
>= virDomainDefGetVcpusMax(persistentDef
)) {
23542 virReportError(VIR_ERR_INVALID_ARG
,
23543 _("vcpu %zd is not present in persistent config"),
23550 if (lastvcpu
>= virDomainDefGetVcpusMax(def
)) {
23551 virReportError(VIR_ERR_INVALID_ARG
,
23552 _("vcpu %zd is not present in live config"),
23558 ret
= qemuDomainSetVcpuInternal(driver
, vm
, def
, persistentDef
, map
, !!state
);
23561 qemuDomainObjEndJob(driver
, vm
);
23564 virBitmapFree(map
);
23565 virDomainObjEndAPI(&vm
);
23571 qemuDomainSetBlockThreshold(virDomainPtr dom
,
23573 unsigned long long threshold
,
23574 unsigned int flags
)
23576 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23577 qemuDomainObjPrivatePtr priv
;
23578 virDomainObjPtr vm
= NULL
;
23579 virStorageSourcePtr src
;
23580 char *nodename
= NULL
;
23584 virCheckFlags(0, -1);
23586 if (!(vm
= qemuDomObjFromDomain(dom
)))
23589 priv
= vm
->privateData
;
23591 if (virDomainSetBlockThresholdEnsureACL(dom
->conn
, vm
->def
) < 0)
23594 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
23597 if (virDomainObjCheckActive(vm
) < 0)
23600 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCK_WRITE_THRESHOLD
)) {
23601 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
23602 _("this qemu does not support setting device threshold"));
23606 if (!(src
= qemuDomainGetStorageSourceByDevstr(dev
, vm
->def
)))
23609 if (!src
->nodestorage
&&
23610 qemuBlockNodeNamesDetect(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
23613 if (!src
->nodestorage
) {
23614 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
23615 _("threshold currently can't be set for block device '%s'"),
23620 if (VIR_STRDUP(nodename
, src
->nodestorage
) < 0)
23623 qemuDomainObjEnterMonitor(driver
, vm
);
23624 rc
= qemuMonitorSetBlockThreshold(priv
->mon
, nodename
, threshold
);
23625 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || rc
< 0)
23631 qemuDomainObjEndJob(driver
, vm
);
23634 VIR_FREE(nodename
);
23635 virDomainObjEndAPI(&vm
);
23641 qemuDomainModifyLifecycleAction(virDomainDefPtr def
,
23642 virDomainLifecycle type
,
23643 virDomainLifecycleAction action
)
23646 case VIR_DOMAIN_LIFECYCLE_POWEROFF
:
23647 def
->onPoweroff
= action
;
23649 case VIR_DOMAIN_LIFECYCLE_REBOOT
:
23650 def
->onReboot
= action
;
23652 case VIR_DOMAIN_LIFECYCLE_CRASH
:
23653 def
->onCrash
= action
;
23655 case VIR_DOMAIN_LIFECYCLE_LAST
:
23663 qemuDomainSetLifecycleAction(virDomainPtr dom
,
23665 unsigned int action
,
23666 unsigned int flags
)
23668 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23669 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
23670 qemuDomainObjPrivatePtr priv
;
23671 virDomainObjPtr vm
= NULL
;
23672 virDomainDefPtr def
= NULL
;
23673 virDomainDefPtr persistentDef
= NULL
;
23676 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
23677 VIR_DOMAIN_AFFECT_CONFIG
, -1);
23679 if (!virDomainDefLifecycleActionAllowed(type
, action
))
23682 if (!(vm
= qemuDomObjFromDomain(dom
)))
23685 priv
= vm
->privateData
;
23687 if (virDomainSetLifecycleActionEnsureACL(dom
->conn
, vm
->def
) < 0)
23690 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
23693 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
23697 if (priv
->allowReboot
== VIR_TRISTATE_BOOL_NO
) {
23698 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
23699 _("cannot update lifecycle action because QEMU "
23700 "was started with -no-reboot option"));
23704 qemuDomainModifyLifecycleAction(def
, type
, action
);
23706 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
,
23707 vm
, driver
->caps
) < 0)
23711 if (persistentDef
) {
23712 qemuDomainModifyLifecycleAction(persistentDef
, type
, action
);
23714 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
23715 persistentDef
) < 0)
23722 qemuDomainObjEndJob(driver
, vm
);
23725 virDomainObjEndAPI(&vm
);
23726 virObjectUnref(cfg
);
23732 qemuGetSEVInfoToParams(virQEMUCapsPtr qemuCaps
,
23733 virTypedParameterPtr
*params
,
23735 unsigned int flags
)
23739 virSEVCapabilityPtr sev
= virQEMUCapsGetSEVCapabilities(qemuCaps
);
23740 virTypedParameterPtr sevParams
= NULL
;
23742 virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY
, -1);
23744 if (virTypedParamsAddString(&sevParams
, &n
, &maxpar
,
23745 VIR_NODE_SEV_PDH
, sev
->pdh
) < 0)
23748 if (virTypedParamsAddString(&sevParams
, &n
, &maxpar
,
23749 VIR_NODE_SEV_CERT_CHAIN
, sev
->cert_chain
) < 0)
23752 if (virTypedParamsAddUInt(&sevParams
, &n
, &maxpar
,
23753 VIR_NODE_SEV_CBITPOS
, sev
->cbitpos
) < 0)
23756 if (virTypedParamsAddUInt(&sevParams
, &n
, &maxpar
,
23757 VIR_NODE_SEV_REDUCED_PHYS_BITS
,
23758 sev
->reduced_phys_bits
) < 0)
23761 VIR_STEAL_PTR(*params
, sevParams
);
23766 virTypedParamsFree(sevParams
, n
);
23772 qemuNodeGetSEVInfo(virConnectPtr conn
,
23773 virTypedParameterPtr
*params
,
23775 unsigned int flags
)
23777 virQEMUDriverPtr driver
= conn
->privateData
;
23778 virQEMUCapsPtr qemucaps
= NULL
;
23781 if (virNodeGetSevInfoEnsureACL(conn
) < 0)
23784 qemucaps
= virQEMUCapsCacheLookupByArch(driver
->qemuCapsCache
,
23785 virArchFromHost());
23789 if (!virQEMUCapsGet(qemucaps
, QEMU_CAPS_SEV_GUEST
)) {
23790 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
23791 _("QEMU does not support SEV guest"));
23795 if (qemuGetSEVInfoToParams(qemucaps
, params
, nparams
, flags
) < 0)
23801 virObjectUnref(qemucaps
);
23808 qemuDomainGetSEVMeasurement(virQEMUDriverPtr driver
,
23809 virDomainObjPtr vm
,
23810 virTypedParameterPtr
*params
,
23812 unsigned int flags
)
23818 virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY
, -1);
23820 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
23823 qemuDomainObjEnterMonitor(driver
, vm
);
23824 tmp
= qemuMonitorGetSEVMeasurement(QEMU_DOMAIN_PRIVATE(vm
)->mon
);
23826 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
23832 if (virTypedParamsAddString(params
, nparams
, &maxpar
,
23833 VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT
,
23841 qemuDomainObjEndJob(driver
, vm
);
23847 qemuDomainGetLaunchSecurityInfo(virDomainPtr domain
,
23848 virTypedParameterPtr
*params
,
23850 unsigned int flags
)
23852 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
23853 virDomainObjPtr vm
;
23856 if (!(vm
= qemuDomObjFromDomain(domain
)))
23859 if (virDomainGetLaunchSecurityInfoEnsureACL(domain
->conn
, vm
->def
) < 0)
23862 if (vm
->def
->sev
) {
23863 if (qemuDomainGetSEVMeasurement(driver
, vm
, params
, nparams
, flags
) < 0)
23870 virDomainObjEndAPI(&vm
);
23874 static virHypervisorDriver qemuHypervisorDriver
= {
23875 .name
= QEMU_DRIVER_NAME
,
23876 .connectURIProbe
= qemuConnectURIProbe
,
23877 .connectOpen
= qemuConnectOpen
, /* 0.2.0 */
23878 .connectClose
= qemuConnectClose
, /* 0.2.0 */
23879 .connectSupportsFeature
= qemuConnectSupportsFeature
, /* 0.5.0 */
23880 .connectGetType
= qemuConnectGetType
, /* 0.2.0 */
23881 .connectGetVersion
= qemuConnectGetVersion
, /* 0.2.0 */
23882 .connectGetHostname
= qemuConnectGetHostname
, /* 0.3.3 */
23883 .connectGetSysinfo
= qemuConnectGetSysinfo
, /* 0.8.8 */
23884 .connectGetMaxVcpus
= qemuConnectGetMaxVcpus
, /* 0.2.1 */
23885 .nodeGetInfo
= qemuNodeGetInfo
, /* 0.2.0 */
23886 .connectGetCapabilities
= qemuConnectGetCapabilities
, /* 0.2.1 */
23887 .connectListDomains
= qemuConnectListDomains
, /* 0.2.0 */
23888 .connectNumOfDomains
= qemuConnectNumOfDomains
, /* 0.2.0 */
23889 .connectListAllDomains
= qemuConnectListAllDomains
, /* 0.9.13 */
23890 .domainCreateXML
= qemuDomainCreateXML
, /* 0.2.0 */
23891 .domainLookupByID
= qemuDomainLookupByID
, /* 0.2.0 */
23892 .domainLookupByUUID
= qemuDomainLookupByUUID
, /* 0.2.0 */
23893 .domainLookupByName
= qemuDomainLookupByName
, /* 0.2.0 */
23894 .domainSuspend
= qemuDomainSuspend
, /* 0.2.0 */
23895 .domainResume
= qemuDomainResume
, /* 0.2.0 */
23896 .domainShutdown
= qemuDomainShutdown
, /* 0.2.0 */
23897 .domainShutdownFlags
= qemuDomainShutdownFlags
, /* 0.9.10 */
23898 .domainReboot
= qemuDomainReboot
, /* 0.9.3 */
23899 .domainReset
= qemuDomainReset
, /* 0.9.7 */
23900 .domainDestroy
= qemuDomainDestroy
, /* 0.2.0 */
23901 .domainDestroyFlags
= qemuDomainDestroyFlags
, /* 0.9.4 */
23902 .domainGetOSType
= qemuDomainGetOSType
, /* 0.2.2 */
23903 .domainGetMaxMemory
= qemuDomainGetMaxMemory
, /* 0.4.2 */
23904 .domainSetMaxMemory
= qemuDomainSetMaxMemory
, /* 0.4.2 */
23905 .domainSetMemory
= qemuDomainSetMemory
, /* 0.4.2 */
23906 .domainSetMemoryFlags
= qemuDomainSetMemoryFlags
, /* 0.9.0 */
23907 .domainSetMemoryParameters
= qemuDomainSetMemoryParameters
, /* 0.8.5 */
23908 .domainGetMemoryParameters
= qemuDomainGetMemoryParameters
, /* 0.8.5 */
23909 .domainSetMemoryStatsPeriod
= qemuDomainSetMemoryStatsPeriod
, /* 1.1.1 */
23910 .domainSetBlkioParameters
= qemuDomainSetBlkioParameters
, /* 0.9.0 */
23911 .domainGetBlkioParameters
= qemuDomainGetBlkioParameters
, /* 0.9.0 */
23912 .domainGetInfo
= qemuDomainGetInfo
, /* 0.2.0 */
23913 .domainGetState
= qemuDomainGetState
, /* 0.9.2 */
23914 .domainGetControlInfo
= qemuDomainGetControlInfo
, /* 0.9.3 */
23915 .domainSave
= qemuDomainSave
, /* 0.2.0 */
23916 .domainSaveFlags
= qemuDomainSaveFlags
, /* 0.9.4 */
23917 .domainRestore
= qemuDomainRestore
, /* 0.2.0 */
23918 .domainRestoreFlags
= qemuDomainRestoreFlags
, /* 0.9.4 */
23919 .domainSaveImageGetXMLDesc
= qemuDomainSaveImageGetXMLDesc
, /* 0.9.4 */
23920 .domainSaveImageDefineXML
= qemuDomainSaveImageDefineXML
, /* 0.9.4 */
23921 .domainCoreDump
= qemuDomainCoreDump
, /* 0.7.0 */
23922 .domainCoreDumpWithFormat
= qemuDomainCoreDumpWithFormat
, /* 1.2.3 */
23923 .domainScreenshot
= qemuDomainScreenshot
, /* 0.9.2 */
23924 .domainSetVcpus
= qemuDomainSetVcpus
, /* 0.4.4 */
23925 .domainSetVcpusFlags
= qemuDomainSetVcpusFlags
, /* 0.8.5 */
23926 .domainGetVcpusFlags
= qemuDomainGetVcpusFlags
, /* 0.8.5 */
23927 .domainPinVcpu
= qemuDomainPinVcpu
, /* 0.4.4 */
23928 .domainPinVcpuFlags
= qemuDomainPinVcpuFlags
, /* 0.9.3 */
23929 .domainGetVcpuPinInfo
= qemuDomainGetVcpuPinInfo
, /* 0.9.3 */
23930 .domainPinEmulator
= qemuDomainPinEmulator
, /* 0.10.0 */
23931 .domainGetEmulatorPinInfo
= qemuDomainGetEmulatorPinInfo
, /* 0.10.0 */
23932 .domainGetVcpus
= qemuDomainGetVcpus
, /* 0.4.4 */
23933 .domainGetMaxVcpus
= qemuDomainGetMaxVcpus
, /* 0.4.4 */
23934 .domainGetIOThreadInfo
= qemuDomainGetIOThreadInfo
, /* 1.2.14 */
23935 .domainPinIOThread
= qemuDomainPinIOThread
, /* 1.2.14 */
23936 .domainAddIOThread
= qemuDomainAddIOThread
, /* 1.2.15 */
23937 .domainDelIOThread
= qemuDomainDelIOThread
, /* 1.2.15 */
23938 .domainSetIOThreadParams
= qemuDomainSetIOThreadParams
, /* 4.10.0 */
23939 .domainGetSecurityLabel
= qemuDomainGetSecurityLabel
, /* 0.6.1 */
23940 .domainGetSecurityLabelList
= qemuDomainGetSecurityLabelList
, /* 0.10.0 */
23941 .nodeGetSecurityModel
= qemuNodeGetSecurityModel
, /* 0.6.1 */
23942 .domainGetXMLDesc
= qemuDomainGetXMLDesc
, /* 0.2.0 */
23943 .connectDomainXMLFromNative
= qemuConnectDomainXMLFromNative
, /* 0.6.4 */
23944 .connectDomainXMLToNative
= qemuConnectDomainXMLToNative
, /* 0.6.4 */
23945 .connectListDefinedDomains
= qemuConnectListDefinedDomains
, /* 0.2.0 */
23946 .connectNumOfDefinedDomains
= qemuConnectNumOfDefinedDomains
, /* 0.2.0 */
23947 .domainCreate
= qemuDomainCreate
, /* 0.2.0 */
23948 .domainCreateWithFlags
= qemuDomainCreateWithFlags
, /* 0.8.2 */
23949 .domainDefineXML
= qemuDomainDefineXML
, /* 0.2.0 */
23950 .domainDefineXMLFlags
= qemuDomainDefineXMLFlags
, /* 1.2.12 */
23951 .domainUndefine
= qemuDomainUndefine
, /* 0.2.0 */
23952 .domainUndefineFlags
= qemuDomainUndefineFlags
, /* 0.9.4 */
23953 .domainAttachDevice
= qemuDomainAttachDevice
, /* 0.4.1 */
23954 .domainAttachDeviceFlags
= qemuDomainAttachDeviceFlags
, /* 0.7.7 */
23955 .domainDetachDevice
= qemuDomainDetachDevice
, /* 0.5.0 */
23956 .domainDetachDeviceFlags
= qemuDomainDetachDeviceFlags
, /* 0.7.7 */
23957 .domainUpdateDeviceFlags
= qemuDomainUpdateDeviceFlags
, /* 0.8.0 */
23958 .domainDetachDeviceAlias
= qemuDomainDetachDeviceAlias
, /* 4.4.0 */
23959 .domainGetAutostart
= qemuDomainGetAutostart
, /* 0.2.1 */
23960 .domainSetAutostart
= qemuDomainSetAutostart
, /* 0.2.1 */
23961 .domainGetSchedulerType
= qemuDomainGetSchedulerType
, /* 0.7.0 */
23962 .domainGetSchedulerParameters
= qemuDomainGetSchedulerParameters
, /* 0.7.0 */
23963 .domainGetSchedulerParametersFlags
= qemuDomainGetSchedulerParametersFlags
, /* 0.9.2 */
23964 .domainSetSchedulerParameters
= qemuDomainSetSchedulerParameters
, /* 0.7.0 */
23965 .domainSetSchedulerParametersFlags
= qemuDomainSetSchedulerParametersFlags
, /* 0.9.2 */
23966 .domainMigratePerform
= qemuDomainMigratePerform
, /* 0.5.0 */
23967 .domainBlockResize
= qemuDomainBlockResize
, /* 0.9.8 */
23968 .domainBlockStats
= qemuDomainBlockStats
, /* 0.4.1 */
23969 .domainBlockStatsFlags
= qemuDomainBlockStatsFlags
, /* 0.9.5 */
23970 .domainInterfaceStats
= qemuDomainInterfaceStats
, /* 0.4.1 */
23971 .domainMemoryStats
= qemuDomainMemoryStats
, /* 0.7.5 */
23972 .domainBlockPeek
= qemuDomainBlockPeek
, /* 0.4.4 */
23973 .domainMemoryPeek
= qemuDomainMemoryPeek
, /* 0.4.4 */
23974 .domainGetBlockInfo
= qemuDomainGetBlockInfo
, /* 0.8.1 */
23975 .nodeGetCPUStats
= qemuNodeGetCPUStats
, /* 0.9.3 */
23976 .nodeGetMemoryStats
= qemuNodeGetMemoryStats
, /* 0.9.3 */
23977 .nodeGetCellsFreeMemory
= qemuNodeGetCellsFreeMemory
, /* 0.4.4 */
23978 .nodeGetFreeMemory
= qemuNodeGetFreeMemory
, /* 0.4.4 */
23979 .connectDomainEventRegister
= qemuConnectDomainEventRegister
, /* 0.5.0 */
23980 .connectDomainEventDeregister
= qemuConnectDomainEventDeregister
, /* 0.5.0 */
23981 .domainMigratePrepare2
= qemuDomainMigratePrepare2
, /* 0.5.0 */
23982 .domainMigrateFinish2
= qemuDomainMigrateFinish2
, /* 0.5.0 */
23983 .nodeDeviceDettach
= qemuNodeDeviceDettach
, /* 0.6.1 */
23984 .nodeDeviceDetachFlags
= qemuNodeDeviceDetachFlags
, /* 1.0.5 */
23985 .nodeDeviceReAttach
= qemuNodeDeviceReAttach
, /* 0.6.1 */
23986 .nodeDeviceReset
= qemuNodeDeviceReset
, /* 0.6.1 */
23987 .domainMigratePrepareTunnel
= qemuDomainMigratePrepareTunnel
, /* 0.7.2 */
23988 .connectIsEncrypted
= qemuConnectIsEncrypted
, /* 0.7.3 */
23989 .connectIsSecure
= qemuConnectIsSecure
, /* 0.7.3 */
23990 .domainIsActive
= qemuDomainIsActive
, /* 0.7.3 */
23991 .domainIsPersistent
= qemuDomainIsPersistent
, /* 0.7.3 */
23992 .domainIsUpdated
= qemuDomainIsUpdated
, /* 0.8.6 */
23993 .connectCompareCPU
= qemuConnectCompareCPU
, /* 0.7.5 */
23994 .connectBaselineCPU
= qemuConnectBaselineCPU
, /* 0.7.7 */
23995 .domainGetJobInfo
= qemuDomainGetJobInfo
, /* 0.7.7 */
23996 .domainGetJobStats
= qemuDomainGetJobStats
, /* 1.0.3 */
23997 .domainAbortJob
= qemuDomainAbortJob
, /* 0.7.7 */
23998 .domainMigrateGetMaxDowntime
= qemuDomainMigrateGetMaxDowntime
, /* 3.7.0 */
23999 .domainMigrateSetMaxDowntime
= qemuDomainMigrateSetMaxDowntime
, /* 0.8.0 */
24000 .domainMigrateGetCompressionCache
= qemuDomainMigrateGetCompressionCache
, /* 1.0.3 */
24001 .domainMigrateSetCompressionCache
= qemuDomainMigrateSetCompressionCache
, /* 1.0.3 */
24002 .domainMigrateSetMaxSpeed
= qemuDomainMigrateSetMaxSpeed
, /* 0.9.0 */
24003 .domainMigrateGetMaxSpeed
= qemuDomainMigrateGetMaxSpeed
, /* 0.9.5 */
24004 .connectDomainEventRegisterAny
= qemuConnectDomainEventRegisterAny
, /* 0.8.0 */
24005 .connectDomainEventDeregisterAny
= qemuConnectDomainEventDeregisterAny
, /* 0.8.0 */
24006 .domainManagedSave
= qemuDomainManagedSave
, /* 0.8.0 */
24007 .domainHasManagedSaveImage
= qemuDomainHasManagedSaveImage
, /* 0.8.0 */
24008 .domainManagedSaveRemove
= qemuDomainManagedSaveRemove
, /* 0.8.0 */
24009 .domainManagedSaveGetXMLDesc
= qemuDomainManagedSaveGetXMLDesc
, /* 3.7.0 */
24010 .domainManagedSaveDefineXML
= qemuDomainManagedSaveDefineXML
, /* 3.7.0 */
24011 .domainSnapshotCreateXML
= qemuDomainSnapshotCreateXML
, /* 0.8.0 */
24012 .domainSnapshotGetXMLDesc
= qemuDomainSnapshotGetXMLDesc
, /* 0.8.0 */
24013 .domainSnapshotNum
= qemuDomainSnapshotNum
, /* 0.8.0 */
24014 .domainSnapshotListNames
= qemuDomainSnapshotListNames
, /* 0.8.0 */
24015 .domainListAllSnapshots
= qemuDomainListAllSnapshots
, /* 0.9.13 */
24016 .domainSnapshotNumChildren
= qemuDomainSnapshotNumChildren
, /* 0.9.7 */
24017 .domainSnapshotListChildrenNames
= qemuDomainSnapshotListChildrenNames
, /* 0.9.7 */
24018 .domainSnapshotListAllChildren
= qemuDomainSnapshotListAllChildren
, /* 0.9.13 */
24019 .domainSnapshotLookupByName
= qemuDomainSnapshotLookupByName
, /* 0.8.0 */
24020 .domainHasCurrentSnapshot
= qemuDomainHasCurrentSnapshot
, /* 0.8.0 */
24021 .domainSnapshotGetParent
= qemuDomainSnapshotGetParent
, /* 0.9.7 */
24022 .domainSnapshotCurrent
= qemuDomainSnapshotCurrent
, /* 0.8.0 */
24023 .domainSnapshotIsCurrent
= qemuDomainSnapshotIsCurrent
, /* 0.9.13 */
24024 .domainSnapshotHasMetadata
= qemuDomainSnapshotHasMetadata
, /* 0.9.13 */
24025 .domainRevertToSnapshot
= qemuDomainRevertToSnapshot
, /* 0.8.0 */
24026 .domainSnapshotDelete
= qemuDomainSnapshotDelete
, /* 0.8.0 */
24027 .domainQemuMonitorCommand
= qemuDomainQemuMonitorCommand
, /* 0.8.3 */
24028 .domainQemuAttach
= qemuDomainQemuAttach
, /* 0.9.4 */
24029 .domainQemuAgentCommand
= qemuDomainQemuAgentCommand
, /* 0.10.0 */
24030 .connectDomainQemuMonitorEventRegister
= qemuConnectDomainQemuMonitorEventRegister
, /* 1.2.3 */
24031 .connectDomainQemuMonitorEventDeregister
= qemuConnectDomainQemuMonitorEventDeregister
, /* 1.2.3 */
24032 .domainOpenConsole
= qemuDomainOpenConsole
, /* 0.8.6 */
24033 .domainOpenGraphics
= qemuDomainOpenGraphics
, /* 0.9.7 */
24034 .domainOpenGraphicsFD
= qemuDomainOpenGraphicsFD
, /* 1.2.8 */
24035 .domainInjectNMI
= qemuDomainInjectNMI
, /* 0.9.2 */
24036 .domainMigrateBegin3
= qemuDomainMigrateBegin3
, /* 0.9.2 */
24037 .domainMigratePrepare3
= qemuDomainMigratePrepare3
, /* 0.9.2 */
24038 .domainMigratePrepareTunnel3
= qemuDomainMigratePrepareTunnel3
, /* 0.9.2 */
24039 .domainMigratePerform3
= qemuDomainMigratePerform3
, /* 0.9.2 */
24040 .domainMigrateFinish3
= qemuDomainMigrateFinish3
, /* 0.9.2 */
24041 .domainMigrateConfirm3
= qemuDomainMigrateConfirm3
, /* 0.9.2 */
24042 .domainSendKey
= qemuDomainSendKey
, /* 0.9.4 */
24043 .domainGetPerfEvents
= qemuDomainGetPerfEvents
, /* 1.3.3 */
24044 .domainSetPerfEvents
= qemuDomainSetPerfEvents
, /* 1.3.3 */
24045 .domainBlockJobAbort
= qemuDomainBlockJobAbort
, /* 0.9.4 */
24046 .domainGetBlockJobInfo
= qemuDomainGetBlockJobInfo
, /* 0.9.4 */
24047 .domainBlockJobSetSpeed
= qemuDomainBlockJobSetSpeed
, /* 0.9.4 */
24048 .domainBlockPull
= qemuDomainBlockPull
, /* 0.9.4 */
24049 .domainBlockRebase
= qemuDomainBlockRebase
, /* 0.9.10 */
24050 .domainBlockCopy
= qemuDomainBlockCopy
, /* 1.2.9 */
24051 .domainBlockCommit
= qemuDomainBlockCommit
, /* 1.0.0 */
24052 .connectIsAlive
= qemuConnectIsAlive
, /* 0.9.8 */
24053 .nodeSuspendForDuration
= qemuNodeSuspendForDuration
, /* 0.9.8 */
24054 .domainSetBlockIoTune
= qemuDomainSetBlockIoTune
, /* 0.9.8 */
24055 .domainGetBlockIoTune
= qemuDomainGetBlockIoTune
, /* 0.9.8 */
24056 .domainSetNumaParameters
= qemuDomainSetNumaParameters
, /* 0.9.9 */
24057 .domainGetNumaParameters
= qemuDomainGetNumaParameters
, /* 0.9.9 */
24058 .domainGetInterfaceParameters
= qemuDomainGetInterfaceParameters
, /* 0.9.9 */
24059 .domainSetInterfaceParameters
= qemuDomainSetInterfaceParameters
, /* 0.9.9 */
24060 .domainGetDiskErrors
= qemuDomainGetDiskErrors
, /* 0.9.10 */
24061 .domainSetMetadata
= qemuDomainSetMetadata
, /* 0.9.10 */
24062 .domainGetMetadata
= qemuDomainGetMetadata
, /* 0.9.10 */
24063 .domainPMSuspendForDuration
= qemuDomainPMSuspendForDuration
, /* 0.9.11 */
24064 .domainPMWakeup
= qemuDomainPMWakeup
, /* 0.9.11 */
24065 .domainGetCPUStats
= qemuDomainGetCPUStats
, /* 0.9.11 */
24066 .nodeGetMemoryParameters
= qemuNodeGetMemoryParameters
, /* 0.10.2 */
24067 .nodeSetMemoryParameters
= qemuNodeSetMemoryParameters
, /* 0.10.2 */
24068 .nodeGetCPUMap
= qemuNodeGetCPUMap
, /* 1.0.0 */
24069 .domainFSTrim
= qemuDomainFSTrim
, /* 1.0.1 */
24070 .domainOpenChannel
= qemuDomainOpenChannel
, /* 1.0.2 */
24071 .domainMigrateBegin3Params
= qemuDomainMigrateBegin3Params
, /* 1.1.0 */
24072 .domainMigratePrepare3Params
= qemuDomainMigratePrepare3Params
, /* 1.1.0 */
24073 .domainMigratePrepareTunnel3Params
= qemuDomainMigratePrepareTunnel3Params
, /* 1.1.0 */
24074 .domainMigratePerform3Params
= qemuDomainMigratePerform3Params
, /* 1.1.0 */
24075 .domainMigrateFinish3Params
= qemuDomainMigrateFinish3Params
, /* 1.1.0 */
24076 .domainMigrateConfirm3Params
= qemuDomainMigrateConfirm3Params
, /* 1.1.0 */
24077 .connectGetCPUModelNames
= qemuConnectGetCPUModelNames
, /* 1.1.3 */
24078 .domainFSFreeze
= qemuDomainFSFreeze
, /* 1.2.5 */
24079 .domainFSThaw
= qemuDomainFSThaw
, /* 1.2.5 */
24080 .domainGetHostname
= qemuDomainGetHostname
, /* 4.8.0 */
24081 .domainGetTime
= qemuDomainGetTime
, /* 1.2.5 */
24082 .domainSetTime
= qemuDomainSetTime
, /* 1.2.5 */
24083 .nodeGetFreePages
= qemuNodeGetFreePages
, /* 1.2.6 */
24084 .connectGetDomainCapabilities
= qemuConnectGetDomainCapabilities
, /* 1.2.7 */
24085 .connectGetAllDomainStats
= qemuConnectGetAllDomainStats
, /* 1.2.8 */
24086 .nodeAllocPages
= qemuNodeAllocPages
, /* 1.2.9 */
24087 .domainGetFSInfo
= qemuDomainGetFSInfo
, /* 1.2.11 */
24088 .domainInterfaceAddresses
= qemuDomainInterfaceAddresses
, /* 1.2.14 */
24089 .domainSetUserPassword
= qemuDomainSetUserPassword
, /* 1.2.16 */
24090 .domainRename
= qemuDomainRename
, /* 1.2.19 */
24091 .domainMigrateStartPostCopy
= qemuDomainMigrateStartPostCopy
, /* 1.3.3 */
24092 .domainGetGuestVcpus
= qemuDomainGetGuestVcpus
, /* 2.0.0 */
24093 .domainSetGuestVcpus
= qemuDomainSetGuestVcpus
, /* 2.0.0 */
24094 .domainSetVcpu
= qemuDomainSetVcpu
, /* 3.1.0 */
24095 .domainSetBlockThreshold
= qemuDomainSetBlockThreshold
, /* 3.2.0 */
24096 .domainSetLifecycleAction
= qemuDomainSetLifecycleAction
, /* 3.9.0 */
24097 .connectCompareHypervisorCPU
= qemuConnectCompareHypervisorCPU
, /* 4.4.0 */
24098 .connectBaselineHypervisorCPU
= qemuConnectBaselineHypervisorCPU
, /* 4.4.0 */
24099 .nodeGetSEVInfo
= qemuNodeGetSEVInfo
, /* 4.5.0 */
24100 .domainGetLaunchSecurityInfo
= qemuDomainGetLaunchSecurityInfo
, /* 4.5.0 */
24101 .domainCheckpointCreateXML
= qemuDomainCheckpointCreateXML
, /* 5.2.0 */
24102 .domainCheckpointGetXMLDesc
= qemuDomainCheckpointGetXMLDesc
, /* 5.2.0 */
24104 .domainListAllCheckpoints
= qemuDomainListAllCheckpoints
, /* 5.2.0 */
24105 .domainCheckpointListAllChildren
= qemuDomainCheckpointListAllChildren
, /* 5.2.0 */
24106 .domainCheckpointLookupByName
= qemuDomainCheckpointLookupByName
, /* 5.2.0 */
24107 .domainHasCurrentCheckpoint
= qemuDomainHasCurrentCheckpoint
, /* 5.2.0 */
24108 .domainCheckpointGetParent
= qemuDomainCheckpointGetParent
, /* 5.2.0 */
24109 .domainCheckpointCurrent
= qemuDomainCheckpointCurrent
, /* 5.2.0 */
24110 .domainCheckpointIsCurrent
= qemuDomainCheckpointIsCurrent
, /* 5.2.0 */
24111 .domainCheckpointHasMetadata
= qemuDomainCheckpointHasMetadata
, /* 5.2.0 */
24112 .domainCheckpointDelete
= qemuDomainCheckpointDelete
, /* 5.2.0 */
24113 .domainBackupBegin
= qemuDomainBackupBegin
, /* 5.2.0 */
24114 .domainBackupGetXMLDesc
= qemuDomainBackupGetXMLDesc
, /* 5.2.0 */
24115 .domainBackupEnd
= qemuDomainBackupEnd
, /* 5.2.0 */
24119 static virConnectDriver qemuConnectDriver
= {
24121 .uriSchemes
= (const char *[]){ "qemu", NULL
},
24122 .hypervisorDriver
= &qemuHypervisorDriver
,
24125 static virStateDriver qemuStateDriver
= {
24126 .name
= QEMU_DRIVER_NAME
,
24127 .stateInitialize
= qemuStateInitialize
,
24128 .stateCleanup
= qemuStateCleanup
,
24129 .stateReload
= qemuStateReload
,
24130 .stateStop
= qemuStateStop
,
24133 int qemuRegister(void)
24135 if (virRegisterConnectDriver(&qemuConnectDriver
,
24138 if (virRegisterStateDriver(&qemuStateDriver
) < 0)