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"
106 #define VIR_FROM_THIS VIR_FROM_QEMU
108 VIR_LOG_INIT("qemu.qemu_driver");
110 #define QEMU_NB_MEM_PARAM 3
112 #define QEMU_NB_BLOCK_IO_TUNE_BASE_PARAMS 6
113 #define QEMU_NB_BLOCK_IO_TUNE_MAX_PARAMS 7
114 #define QEMU_NB_BLOCK_IO_TUNE_LENGTH_PARAMS 6
115 #define QEMU_NB_BLOCK_IO_TUNE_GROUP_PARAMS 1
116 #define QEMU_NB_BLOCK_IO_TUNE_ALL_PARAMS (QEMU_NB_BLOCK_IO_TUNE_BASE_PARAMS + \
117 QEMU_NB_BLOCK_IO_TUNE_MAX_PARAMS + \
118 QEMU_NB_BLOCK_IO_TUNE_GROUP_PARAMS + \
119 QEMU_NB_BLOCK_IO_TUNE_LENGTH_PARAMS)
121 #define QEMU_NB_NUMA_PARAM 2
123 #define QEMU_SCHED_MIN_PERIOD 1000LL
124 #define QEMU_SCHED_MAX_PERIOD 1000000LL
125 #define QEMU_SCHED_MIN_QUOTA 1000LL
126 #define QEMU_SCHED_MAX_QUOTA 18446744073709551LL
128 #define QEMU_GUEST_VCPU_MAX_ID 4096
130 #define QEMU_NB_BLKIO_PARAM 6
132 #define QEMU_NB_BANDWIDTH_PARAM 7
134 static void qemuProcessEventHandler(void *data
, void *opaque
);
136 static int qemuStateCleanup(void);
138 static int qemuDomainObjStart(virConnectPtr conn
,
139 virQEMUDriverPtr driver
,
142 qemuDomainAsyncJob asyncJob
);
144 static int qemuDomainManagedSaveLoad(virDomainObjPtr vm
,
147 static int qemuOpenFileAs(uid_t fallback_uid
, gid_t fallback_gid
,
148 bool dynamicOwnership
,
149 const char *path
, int oflags
,
152 static int qemuGetDHCPInterfaces(virDomainPtr dom
,
154 virDomainInterfacePtr
**ifaces
);
156 static int qemuARPGetInterfaces(virDomainObjPtr vm
,
157 virDomainInterfacePtr
**ifaces
);
159 static virQEMUDriverPtr qemu_driver
;
162 * qemuDomObjFromDomain:
163 * @domain: Domain pointer that has to be looked up
165 * This function looks up @domain and returns the appropriate virDomainObjPtr
166 * that has to be released by calling virDomainObjEndAPI().
168 * Returns the domain object with incremented reference counter which is locked
169 * on success, NULL otherwise.
171 static virDomainObjPtr
172 qemuDomObjFromDomain(virDomainPtr domain
)
175 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
176 char uuidstr
[VIR_UUID_STRING_BUFLEN
];
178 vm
= virDomainObjListFindByUUID(driver
->domains
, domain
->uuid
);
180 virUUIDFormat(domain
->uuid
, uuidstr
);
181 virReportError(VIR_ERR_NO_DOMAIN
,
182 _("no domain with matching uuid '%s' (%s)"),
183 uuidstr
, domain
->name
);
190 /* Looks up the domain object from snapshot and unlocks the
191 * driver. The returned domain object is locked and ref'd and the
192 * caller must call virDomainObjEndAPI() on it. */
193 static virDomainObjPtr
194 qemuDomObjFromSnapshot(virDomainSnapshotPtr snapshot
)
196 return qemuDomObjFromDomain(snapshot
->domain
);
200 /* Looks up snapshot object from VM and name */
201 static virDomainSnapshotObjPtr
202 qemuSnapObjFromName(virDomainObjPtr vm
,
205 virDomainSnapshotObjPtr snap
= NULL
;
206 snap
= virDomainSnapshotFindByName(vm
->snapshots
, name
);
208 virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT
,
209 _("no domain snapshot with matching name '%s'"),
216 /* Looks up snapshot object from VM and snapshotPtr */
217 static virDomainSnapshotObjPtr
218 qemuSnapObjFromSnapshot(virDomainObjPtr vm
,
219 virDomainSnapshotPtr snapshot
)
221 return qemuSnapObjFromName(vm
, snapshot
->name
);
224 /* Looks up the domain object from checkpoint and unlocks the
225 * driver. The returned domain object is locked and ref'd and the
226 * caller must call virDomainObjEndAPI() on it. */
227 static virDomainObjPtr
228 qemuDomObjFromCheckpoint(virDomainCheckpointPtr checkpoint
)
230 return qemuDomObjFromDomain(checkpoint
->domain
);
234 /* Looks up checkpoint object from VM and name */
235 static virDomainCheckpointObjPtr
236 qemuCheckObjFromName(virDomainObjPtr vm
,
239 virDomainCheckpointObjPtr chk
= NULL
;
240 chk
= virDomainCheckpointFindByName(vm
->checkpoints
, name
);
242 virReportError(VIR_ERR_NO_DOMAIN_CHECKPOINT
,
243 _("no domain checkpoint with matching name '%s'"),
250 /* Looks up checkpoint object from VM and checkpointPtr */
251 static virDomainCheckpointObjPtr
252 qemuCheckObjFromCheckpoint(virDomainObjPtr vm
,
253 virDomainCheckpointPtr checkpoint
)
255 return qemuCheckObjFromName(vm
, checkpoint
->name
);
259 qemuAutostartDomain(virDomainObjPtr vm
,
262 virQEMUDriverPtr driver
= opaque
;
264 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
267 if (cfg
->autoStartBypassCache
)
268 flags
|= VIR_DOMAIN_START_BYPASS_CACHE
;
274 !virDomainObjIsActive(vm
)) {
275 if (qemuProcessBeginJob(driver
, vm
,
276 VIR_DOMAIN_JOB_OPERATION_START
, flags
) < 0) {
277 virReportError(VIR_ERR_INTERNAL_ERROR
,
278 _("Failed to start job on VM '%s': %s"),
279 vm
->def
->name
, virGetLastErrorMessage());
283 if (qemuDomainObjStart(NULL
, driver
, vm
, flags
,
284 QEMU_ASYNC_JOB_START
) < 0) {
285 virReportError(VIR_ERR_INTERNAL_ERROR
,
286 _("Failed to autostart VM '%s': %s"),
287 vm
->def
->name
, virGetLastErrorMessage());
290 qemuProcessEndJob(driver
, vm
);
295 virDomainObjEndAPI(&vm
);
302 qemuAutostartDomains(virQEMUDriverPtr driver
)
304 virDomainObjListForEach(driver
->domains
, qemuAutostartDomain
, driver
);
309 qemuSecurityChownCallback(const virStorageSource
*src
,
317 VIR_AUTOUNREF(virStorageSourcePtr
) cpy
= NULL
;
319 rv
= virStorageFileSupportsSecurityDriver(src
);
323 if (virStorageSourceIsLocalStorage(src
)) {
324 /* use direct chown for local files so that the file doesn't
325 * need to be initialized */
329 if (stat(src
->path
, &sb
) >= 0) {
330 if (sb
.st_uid
== uid
&&
332 /* It's alright, there's nothing to change anyway. */
337 if (chown(src
->path
, uid
, gid
) < 0)
340 if (!(cpy
= virStorageSourceCopy(src
, false)))
343 /* src file init reports errors, return -2 on failure */
344 if (virStorageFileInit(cpy
) < 0) {
349 if (virStorageFileChown(cpy
, uid
, gid
) < 0)
357 virStorageFileDeinit(cpy
);
365 qemuSecurityInit(virQEMUDriverPtr driver
)
368 virSecurityManagerPtr mgr
= NULL
;
369 virSecurityManagerPtr stack
= NULL
;
370 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
371 unsigned int flags
= 0;
373 if (cfg
->securityDefaultConfined
)
374 flags
|= VIR_SECURITY_MANAGER_DEFAULT_CONFINED
;
375 if (cfg
->securityRequireConfined
)
376 flags
|= VIR_SECURITY_MANAGER_REQUIRE_CONFINED
;
377 if (virQEMUDriverIsPrivileged(driver
))
378 flags
|= VIR_SECURITY_MANAGER_PRIVILEGED
;
380 if (cfg
->securityDriverNames
&&
381 cfg
->securityDriverNames
[0]) {
382 names
= cfg
->securityDriverNames
;
383 while (names
&& *names
) {
384 if (!(mgr
= qemuSecurityNew(*names
,
389 if (!(stack
= qemuSecurityNewStack(mgr
)))
392 if (qemuSecurityStackAddNested(stack
, mgr
) < 0)
399 if (!(mgr
= qemuSecurityNew(NULL
,
403 if (!(stack
= qemuSecurityNewStack(mgr
)))
408 if (virQEMUDriverIsPrivileged(driver
)) {
409 if (cfg
->dynamicOwnership
)
410 flags
|= VIR_SECURITY_MANAGER_DYNAMIC_OWNERSHIP
;
411 if (virBitmapIsBitSet(cfg
->namespaces
, QEMU_DOMAIN_NS_MOUNT
))
412 flags
|= VIR_SECURITY_MANAGER_MOUNT_NAMESPACE
;
413 if (!(mgr
= qemuSecurityNewDAC(QEMU_DRIVER_NAME
,
417 qemuSecurityChownCallback
)))
420 if (!(stack
= qemuSecurityNewStack(mgr
)))
423 if (qemuSecurityStackAddNested(stack
, mgr
) < 0)
429 driver
->securityManager
= stack
;
434 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
435 _("Failed to initialize security drivers"));
436 virObjectUnref(stack
);
444 qemuDomainSnapshotLoad(virDomainObjPtr vm
,
447 char *baseDir
= (char *)data
;
448 char *snapDir
= NULL
;
450 struct dirent
*entry
;
453 virDomainSnapshotDefPtr def
= NULL
;
454 virDomainSnapshotObjPtr snap
= NULL
;
455 virDomainSnapshotObjPtr current
= NULL
;
456 unsigned int flags
= (VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE
|
457 VIR_DOMAIN_SNAPSHOT_PARSE_DISKS
|
458 VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL
);
460 virCapsPtr caps
= NULL
;
464 if (virAsprintf(&snapDir
, "%s/%s", baseDir
, vm
->def
->name
) < 0) {
465 virReportError(VIR_ERR_INTERNAL_ERROR
,
466 _("Failed to allocate memory for "
467 "snapshot directory for domain %s"),
472 if (!(caps
= virQEMUDriverGetCapabilities(qemu_driver
, false)))
475 VIR_INFO("Scanning for snapshots for domain %s in %s", vm
->def
->name
,
478 if (virDirOpenIfExists(&dir
, snapDir
) <= 0)
481 while ((direrr
= virDirRead(dir
, &entry
, NULL
)) > 0) {
482 /* NB: ignoring errors, so one malformed config doesn't
483 kill the whole process */
484 VIR_INFO("Loading snapshot file '%s'", entry
->d_name
);
486 if (virAsprintf(&fullpath
, "%s/%s", snapDir
, entry
->d_name
) < 0) {
487 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
488 _("Failed to allocate memory for path"));
492 if (virFileReadAll(fullpath
, 1024*1024*1, &xmlStr
) < 0) {
493 /* Nothing we can do here, skip this one */
494 virReportSystemError(errno
,
495 _("Failed to read snapshot file %s"),
501 def
= virDomainSnapshotDefParseString(xmlStr
, caps
,
505 /* Nothing we can do here, skip this one */
506 virReportError(VIR_ERR_INTERNAL_ERROR
,
507 _("Failed to parse snapshot XML from file '%s'"),
514 snap
= virDomainSnapshotAssignDef(vm
->snapshots
, def
);
516 virDomainSnapshotDefFree(def
);
517 } else if (snap
->def
->current
) {
519 if (!vm
->current_snapshot
)
520 vm
->current_snapshot
= snap
;
527 virReportError(VIR_ERR_INTERNAL_ERROR
,
528 _("Failed to fully read directory %s"),
531 if (vm
->current_snapshot
!= current
) {
532 virReportError(VIR_ERR_INTERNAL_ERROR
,
533 _("Too many snapshots claiming to be current for domain %s"),
535 vm
->current_snapshot
= NULL
;
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 virDomainCheckpointObjPtr chk
= NULL
;
576 virDomainCheckpointObjPtr current
= NULL
;
577 unsigned int flags
= (VIR_DOMAIN_CHECKPOINT_PARSE_REDEFINE
|
578 VIR_DOMAIN_CHECKPOINT_PARSE_DISKS
|
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
,
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
);
638 } else if (chk
->def
->current
) {
640 if (!vm
->current_checkpoint
)
641 vm
->current_checkpoint
= chk
;
648 virReportError(VIR_ERR_INTERNAL_ERROR
,
649 _("Failed to fully read directory %s"),
652 if (vm
->current_checkpoint
!= current
) {
653 virReportError(VIR_ERR_INTERNAL_ERROR
,
654 _("Too many checkpoints claiming to be current for domain %s"),
656 vm
->current_checkpoint
= NULL
;
659 if (virDomainCheckpointUpdateRelations(vm
->checkpoints
) < 0)
660 virReportError(VIR_ERR_INTERNAL_ERROR
,
661 _("Checkpoints have inconsistent relations for domain %s"),
664 /* FIXME: qemu keeps internal track of bitmaps, which form the
665 * basis for checkpoints; it would be nice if we could update our
666 * internal state to reflect that information automatically. But
667 * qemu 3.0 did not have access to this via qemu-img for offline
668 * images (you have to use QMP commands on a running guest), and
669 * it also does not track <parent> relations which we find
670 * important in our metadata.
679 virObjectUnref(caps
);
686 qemuDomainNetsRestart(virDomainObjPtr vm
,
687 void *data ATTRIBUTE_UNUSED
)
690 virDomainDefPtr def
= vm
->def
;
694 for (i
= 0; i
< def
->nnets
; i
++) {
695 virDomainNetDefPtr net
= def
->nets
[i
];
696 if (virDomainNetGetActualType(net
) == VIR_DOMAIN_NET_TYPE_DIRECT
&&
697 virDomainNetGetActualDirectMode(net
) == VIR_NETDEV_MACVLAN_MODE_VEPA
) {
698 VIR_DEBUG("VEPA mode device %s active in domain %s. Reassociating.",
699 net
->ifname
, def
->name
);
700 ignore_value(virNetDevMacVLanRestartWithVPortProfile(net
->ifname
,
702 virDomainNetGetActualDirectDev(net
),
704 virDomainNetGetActualVirtPortProfile(net
),
705 VIR_NETDEV_VPORT_PROFILE_OP_CREATE
));
715 qemuDomainFindMaxID(virDomainObjPtr vm
,
718 int *driver_maxid
= data
;
720 if (vm
->def
->id
> *driver_maxid
)
721 *driver_maxid
= vm
->def
->id
;
728 * qemuStateInitialize:
730 * Initialization function for the QEMU daemon
733 qemuStateInitialize(bool privileged
,
734 virStateInhibitCallback callback
,
737 char *driverConf
= NULL
;
738 virQEMUDriverConfigPtr cfg
;
741 char *hugepagePath
= NULL
;
742 char *memoryBackingPath
= NULL
;
744 virCPUDefPtr hostCPU
= NULL
;
745 unsigned int microcodeVersion
= 0;
747 if (VIR_ALLOC(qemu_driver
) < 0)
750 if (virMutexInit(&qemu_driver
->lock
) < 0) {
751 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
752 _("cannot initialize mutex"));
753 VIR_FREE(qemu_driver
);
757 qemu_driver
->inhibitCallback
= callback
;
758 qemu_driver
->inhibitOpaque
= opaque
;
760 qemu_driver
->privileged
= privileged
;
762 if (!(qemu_driver
->domains
= virDomainObjListNew()))
765 /* Init domain events */
766 qemu_driver
->domainEventState
= virObjectEventStateNew();
767 if (!qemu_driver
->domainEventState
)
770 /* read the host sysinfo */
772 qemu_driver
->hostsysinfo
= virSysinfoRead();
774 if (!(qemu_driver
->config
= cfg
= virQEMUDriverConfigNew(privileged
)))
777 if (virAsprintf(&driverConf
, "%s/qemu.conf", cfg
->configBaseDir
) < 0)
780 if (virQEMUDriverConfigLoadFile(cfg
, driverConf
, privileged
) < 0)
782 VIR_FREE(driverConf
);
784 if (virQEMUDriverConfigValidate(cfg
) < 0)
787 if (virQEMUDriverConfigSetDefaults(cfg
) < 0)
790 if (virFileMakePath(cfg
->stateDir
) < 0) {
791 virReportSystemError(errno
, _("Failed to create state dir %s"),
795 if (virFileMakePath(cfg
->libDir
) < 0) {
796 virReportSystemError(errno
, _("Failed to create lib dir %s"),
800 if (virFileMakePath(cfg
->cacheDir
) < 0) {
801 virReportSystemError(errno
, _("Failed to create cache dir %s"),
805 if (virFileMakePath(cfg
->saveDir
) < 0) {
806 virReportSystemError(errno
, _("Failed to create save dir %s"),
810 if (virFileMakePath(cfg
->snapshotDir
) < 0) {
811 virReportSystemError(errno
, _("Failed to create snapshot dir %s"),
815 if (virFileMakePath(cfg
->checkpointDir
) < 0) {
816 virReportSystemError(errno
, _("Failed to create checkpoint dir %s"),
820 if (virFileMakePath(cfg
->autoDumpPath
) < 0) {
821 virReportSystemError(errno
, _("Failed to create dump dir %s"),
825 if (virFileMakePath(cfg
->channelTargetDir
) < 0) {
826 virReportSystemError(errno
, _("Failed to create channel target dir %s"),
827 cfg
->channelTargetDir
);
830 if (virFileMakePath(cfg
->nvramDir
) < 0) {
831 virReportSystemError(errno
, _("Failed to create nvram dir %s"),
835 if (virFileMakePath(cfg
->memoryBackingDir
) < 0) {
836 virReportSystemError(errno
, _("Failed to create memory backing dir %s"),
837 cfg
->memoryBackingDir
);
841 qemu_driver
->qemuImgBinary
= virFindFileInPath("qemu-img");
843 if (!(qemu_driver
->lockManager
=
844 virLockManagerPluginNew(cfg
->lockManagerName
?
845 cfg
->lockManagerName
: "nop",
851 if (cfg
->macFilter
) {
852 if (!(qemu_driver
->ebtables
= ebtablesContextNew("qemu"))) {
853 virReportSystemError(errno
,
854 _("failed to enable mac filter in '%s'"),
859 if (ebtablesAddForwardPolicyReject(qemu_driver
->ebtables
) < 0)
863 /* Allocate bitmap for remote display port reservations. We cannot
864 * do this before the config is loaded properly, since the port
865 * numbers are configurable now */
866 if ((qemu_driver
->remotePorts
=
867 virPortAllocatorRangeNew(_("display"),
869 cfg
->remotePortMax
)) == NULL
)
872 if ((qemu_driver
->webSocketPorts
=
873 virPortAllocatorRangeNew(_("webSocket"),
874 cfg
->webSocketPortMin
,
875 cfg
->webSocketPortMax
)) == NULL
)
878 if ((qemu_driver
->migrationPorts
=
879 virPortAllocatorRangeNew(_("migration"),
880 cfg
->migrationPortMin
,
881 cfg
->migrationPortMax
)) == NULL
)
884 if (qemuSecurityInit(qemu_driver
) < 0)
887 if (!(qemu_driver
->hostdevMgr
= virHostdevManagerGetDefault()))
890 if (!(qemu_driver
->sharedDevices
= virHashCreate(30, qemuSharedDeviceEntryFree
)))
893 if (qemuMigrationDstErrorInit(qemu_driver
) < 0)
899 if (chown(cfg
->libDir
, cfg
->user
, cfg
->group
) < 0) {
900 virReportSystemError(errno
,
901 _("unable to set ownership of '%s' to user %d:%d"),
902 cfg
->libDir
, (int)cfg
->user
,
906 if (chown(cfg
->cacheDir
, cfg
->user
, cfg
->group
) < 0) {
907 virReportSystemError(errno
,
908 _("unable to set ownership of '%s' to %d:%d"),
909 cfg
->cacheDir
, (int)cfg
->user
,
913 if (chown(cfg
->saveDir
, cfg
->user
, cfg
->group
) < 0) {
914 virReportSystemError(errno
,
915 _("unable to set ownership of '%s' to %d:%d"),
916 cfg
->saveDir
, (int)cfg
->user
,
920 if (chown(cfg
->snapshotDir
, cfg
->user
, cfg
->group
) < 0) {
921 virReportSystemError(errno
,
922 _("unable to set ownership of '%s' to %d:%d"),
923 cfg
->snapshotDir
, (int)cfg
->user
,
927 if (chown(cfg
->checkpointDir
, cfg
->user
, cfg
->group
) < 0) {
928 virReportSystemError(errno
,
929 _("unable to set ownership of '%s' to %d:%d"),
930 cfg
->checkpointDir
, (int)cfg
->user
,
934 if (chown(cfg
->autoDumpPath
, cfg
->user
, cfg
->group
) < 0) {
935 virReportSystemError(errno
,
936 _("unable to set ownership of '%s' to %d:%d"),
937 cfg
->autoDumpPath
, (int)cfg
->user
,
941 if (!(channeldir
= mdir_name(cfg
->channelTargetDir
))) {
945 if (chown(channeldir
, cfg
->user
, cfg
->group
) < 0) {
946 virReportSystemError(errno
,
947 _("unable to set ownership of '%s' to %d:%d"),
948 channeldir
, (int)cfg
->user
,
950 VIR_FREE(channeldir
);
953 VIR_FREE(channeldir
);
954 if (chown(cfg
->channelTargetDir
, cfg
->user
, cfg
->group
) < 0) {
955 virReportSystemError(errno
,
956 _("unable to set ownership of '%s' to %d:%d"),
957 cfg
->channelTargetDir
, (int)cfg
->user
,
961 if (chown(cfg
->nvramDir
, cfg
->user
, cfg
->group
) < 0) {
962 virReportSystemError(errno
,
963 _("unable to set ownership of '%s' to %d:%d"),
964 cfg
->nvramDir
, (int)cfg
->user
,
968 if (chown(cfg
->memoryBackingDir
, cfg
->user
, cfg
->group
) < 0) {
969 virReportSystemError(errno
,
970 _("unable to set ownership of '%s' to %d:%d"),
971 cfg
->memoryBackingDir
, (int)cfg
->user
,
977 run_gid
= cfg
->group
;
980 if ((hostCPU
= virCPUProbeHost(virArchFromHost())))
981 microcodeVersion
= hostCPU
->microcodeVersion
;
982 virCPUDefFree(hostCPU
);
984 qemu_driver
->qemuCapsCache
= virQEMUCapsCacheNew(cfg
->libDir
,
989 if (!qemu_driver
->qemuCapsCache
)
992 if ((qemu_driver
->caps
= virQEMUDriverCreateCapabilities(qemu_driver
)) == NULL
)
995 if (!(qemu_driver
->xmlopt
= virQEMUDriverCreateXMLConf(qemu_driver
)))
998 /* If hugetlbfs is present, then we need to create a sub-directory within
999 * it, since we can't assume the root mount point has permissions that
1000 * will let our spawned QEMU instances use it. */
1001 for (i
= 0; i
< cfg
->nhugetlbfs
; i
++) {
1002 hugepagePath
= qemuGetBaseHugepagePath(&cfg
->hugetlbfs
[i
]);
1007 if (virFileMakePath(hugepagePath
) < 0) {
1008 virReportSystemError(errno
,
1009 _("unable to create hugepage path %s"),
1014 virFileUpdatePerm(cfg
->hugetlbfs
[i
].mnt_dir
,
1015 0, S_IXGRP
| S_IXOTH
) < 0)
1017 VIR_FREE(hugepagePath
);
1020 if (qemuGetMemoryBackingBasePath(cfg
, &memoryBackingPath
) < 0)
1023 if (virFileMakePath(memoryBackingPath
) < 0) {
1024 virReportSystemError(errno
,
1025 _("unable to create memory backing path %s"),
1031 virFileUpdatePerm(memoryBackingPath
,
1032 0, S_IXGRP
| S_IXOTH
) < 0)
1034 VIR_FREE(memoryBackingPath
);
1036 if (!(qemu_driver
->closeCallbacks
= virCloseCallbacksNew()))
1039 /* Get all the running persistent or transient configs first */
1040 if (virDomainObjListLoadAllConfigs(qemu_driver
->domains
,
1044 qemu_driver
->xmlopt
,
1048 /* find the maximum ID from active and transient configs to initialize
1049 * the driver with. This is to avoid race between autostart and reconnect
1051 virDomainObjListForEach(qemu_driver
->domains
,
1052 qemuDomainFindMaxID
,
1053 &qemu_driver
->lastvmid
);
1055 virDomainObjListForEach(qemu_driver
->domains
,
1056 qemuDomainNetsRestart
,
1059 /* Then inactive persistent configs */
1060 if (virDomainObjListLoadAllConfigs(qemu_driver
->domains
,
1062 cfg
->autostartDir
, false,
1064 qemu_driver
->xmlopt
,
1068 virDomainObjListForEach(qemu_driver
->domains
,
1069 qemuDomainSnapshotLoad
,
1072 virDomainObjListForEach(qemu_driver
->domains
,
1073 qemuDomainCheckpointLoad
,
1074 cfg
->checkpointDir
);
1076 virDomainObjListForEach(qemu_driver
->domains
,
1077 qemuDomainManagedSaveLoad
,
1080 /* must be initialized before trying to reconnect to all the
1081 * running domains since there might occur some QEMU monitor
1082 * events that will be dispatched to the worker pool */
1083 qemu_driver
->workerPool
= virThreadPoolNew(0, 1, 0, qemuProcessEventHandler
, qemu_driver
);
1084 if (!qemu_driver
->workerPool
)
1087 qemuProcessReconnectAll(qemu_driver
);
1089 qemuAutostartDomains(qemu_driver
);
1094 VIR_FREE(driverConf
);
1095 VIR_FREE(hugepagePath
);
1096 VIR_FREE(memoryBackingPath
);
1101 static void qemuNotifyLoadDomain(virDomainObjPtr vm
, int newVM
, void *opaque
)
1103 virQEMUDriverPtr driver
= opaque
;
1106 virObjectEventPtr event
=
1107 virDomainEventLifecycleNewFromObj(vm
,
1108 VIR_DOMAIN_EVENT_DEFINED
,
1109 VIR_DOMAIN_EVENT_DEFINED_ADDED
);
1110 virObjectEventStateQueue(driver
->domainEventState
, event
);
1117 * Function to restart the QEMU daemon, it will recheck the configuration
1118 * files and update its state and the networking
1121 qemuStateReload(void)
1123 virQEMUDriverConfigPtr cfg
= NULL
;
1124 virCapsPtr caps
= NULL
;
1129 if (!(caps
= virQEMUDriverGetCapabilities(qemu_driver
, false)))
1132 cfg
= virQEMUDriverGetConfig(qemu_driver
);
1133 virDomainObjListLoadAllConfigs(qemu_driver
->domains
,
1135 cfg
->autostartDir
, false,
1136 caps
, qemu_driver
->xmlopt
,
1137 qemuNotifyLoadDomain
, qemu_driver
);
1139 virObjectUnref(cfg
);
1140 virObjectUnref(caps
);
1148 * Save any VMs in preparation for shutdown
1159 virDomainPtr
*domains
= NULL
;
1160 unsigned int *flags
= NULL
;
1161 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(qemu_driver
);
1163 if (!(conn
= virConnectOpen(cfg
->uri
)))
1166 if ((numDomains
= virConnectListAllDomains(conn
,
1168 VIR_CONNECT_LIST_DOMAINS_ACTIVE
)) < 0)
1171 if (VIR_ALLOC_N(flags
, numDomains
) < 0)
1174 /* First we pause all VMs to make them stop dirtying
1175 pages, etc. We remember if any VMs were paused so
1176 we can restore that on resume. */
1177 for (i
= 0; i
< numDomains
; i
++) {
1178 flags
[i
] = VIR_DOMAIN_SAVE_RUNNING
;
1179 if (virDomainGetState(domains
[i
], &state
, NULL
, 0) == 0) {
1180 if (state
== VIR_DOMAIN_PAUSED
)
1181 flags
[i
] = VIR_DOMAIN_SAVE_PAUSED
;
1183 virDomainSuspend(domains
[i
]);
1187 /* Then we save the VMs to disk */
1188 for (i
= 0; i
< numDomains
; i
++)
1189 if (virDomainManagedSave(domains
[i
], flags
[i
]) < 0)
1194 for (i
= 0; i
< numDomains
; i
++)
1195 virObjectUnref(domains
[i
]);
1199 virObjectUnref(conn
);
1200 virObjectUnref(cfg
);
1208 * Shutdown the QEMU daemon, it will stop all active domains and networks
1211 qemuStateCleanup(void)
1216 virThreadPoolFree(qemu_driver
->workerPool
);
1217 virObjectUnref(qemu_driver
->config
);
1218 virObjectUnref(qemu_driver
->hostdevMgr
);
1219 virHashFree(qemu_driver
->sharedDevices
);
1220 virObjectUnref(qemu_driver
->caps
);
1221 virObjectUnref(qemu_driver
->qemuCapsCache
);
1223 virObjectUnref(qemu_driver
->domains
);
1224 virPortAllocatorRangeFree(qemu_driver
->remotePorts
);
1225 virPortAllocatorRangeFree(qemu_driver
->webSocketPorts
);
1226 virPortAllocatorRangeFree(qemu_driver
->migrationPorts
);
1227 virObjectUnref(qemu_driver
->migrationErrors
);
1229 virObjectUnref(qemu_driver
->xmlopt
);
1231 virSysinfoDefFree(qemu_driver
->hostsysinfo
);
1233 virObjectUnref(qemu_driver
->closeCallbacks
);
1235 VIR_FREE(qemu_driver
->qemuImgBinary
);
1237 virObjectUnref(qemu_driver
->securityManager
);
1239 ebtablesContextFree(qemu_driver
->ebtables
);
1241 /* Free domain callback list */
1242 virObjectUnref(qemu_driver
->domainEventState
);
1244 virLockManagerPluginUnref(qemu_driver
->lockManager
);
1246 virMutexDestroy(&qemu_driver
->lock
);
1247 VIR_FREE(qemu_driver
);
1254 qemuConnectURIProbe(char **uri
)
1256 virQEMUDriverConfigPtr cfg
= NULL
;
1259 if (qemu_driver
== NULL
)
1262 cfg
= virQEMUDriverGetConfig(qemu_driver
);
1263 if (VIR_STRDUP(*uri
, cfg
->uri
) < 0)
1268 virObjectUnref(cfg
);
1272 static virDrvOpenStatus
qemuConnectOpen(virConnectPtr conn
,
1273 virConnectAuthPtr auth ATTRIBUTE_UNUSED
,
1274 virConfPtr conf ATTRIBUTE_UNUSED
,
1277 virQEMUDriverConfigPtr cfg
= NULL
;
1278 virDrvOpenStatus ret
= VIR_DRV_OPEN_ERROR
;
1279 virCheckFlags(VIR_CONNECT_RO
, VIR_DRV_OPEN_ERROR
);
1281 if (qemu_driver
== NULL
) {
1282 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
1283 _("qemu state driver is not active"));
1287 cfg
= virQEMUDriverGetConfig(qemu_driver
);
1289 if (virQEMUDriverIsPrivileged(qemu_driver
)) {
1290 if (STRNEQ(conn
->uri
->path
, "/system") &&
1291 STRNEQ(conn
->uri
->path
, "/session")) {
1292 virReportError(VIR_ERR_INTERNAL_ERROR
,
1293 _("unexpected QEMU URI path '%s', try qemu:///system"),
1298 if (STRNEQ(conn
->uri
->path
, "/session")) {
1299 virReportError(VIR_ERR_INTERNAL_ERROR
,
1300 _("unexpected QEMU URI path '%s', try qemu:///session"),
1306 if (virConnectOpenEnsureACL(conn
) < 0)
1309 conn
->privateData
= qemu_driver
;
1311 ret
= VIR_DRV_OPEN_SUCCESS
;
1313 virObjectUnref(cfg
);
1317 static int qemuConnectClose(virConnectPtr conn
)
1319 virQEMUDriverPtr driver
= conn
->privateData
;
1321 /* Get rid of callbacks registered for this conn */
1322 virCloseCallbacksRun(driver
->closeCallbacks
, conn
, driver
->domains
, driver
);
1324 conn
->privateData
= NULL
;
1329 /* Which features are supported by this driver? */
1331 qemuConnectSupportsFeature(virConnectPtr conn
, int feature
)
1333 if (virConnectSupportsFeatureEnsureACL(conn
) < 0)
1336 switch ((virDrvFeature
) feature
) {
1337 case VIR_DRV_FEATURE_MIGRATION_V2
:
1338 case VIR_DRV_FEATURE_MIGRATION_V3
:
1339 case VIR_DRV_FEATURE_MIGRATION_P2P
:
1340 case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION
:
1341 case VIR_DRV_FEATURE_FD_PASSING
:
1342 case VIR_DRV_FEATURE_TYPED_PARAM_STRING
:
1343 case VIR_DRV_FEATURE_XML_MIGRATABLE
:
1344 case VIR_DRV_FEATURE_MIGRATION_OFFLINE
:
1345 case VIR_DRV_FEATURE_MIGRATION_PARAMS
:
1347 case VIR_DRV_FEATURE_MIGRATION_DIRECT
:
1348 case VIR_DRV_FEATURE_MIGRATION_V1
:
1349 case VIR_DRV_FEATURE_PROGRAM_KEEPALIVE
:
1350 case VIR_DRV_FEATURE_REMOTE
:
1351 case VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK
:
1352 case VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK
:
1358 static const char *qemuConnectGetType(virConnectPtr conn
) {
1359 if (virConnectGetTypeEnsureACL(conn
) < 0)
1366 static int qemuConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED
)
1368 /* Trivially secure, since always inside the daemon */
1372 static int qemuConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED
)
1374 /* Not encrypted, but remote driver takes care of that */
1378 static int qemuConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED
)
1385 qemuConnectGetSysinfo(virConnectPtr conn
, unsigned int flags
)
1387 virQEMUDriverPtr driver
= conn
->privateData
;
1388 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
1390 virCheckFlags(0, NULL
);
1392 if (virConnectGetSysinfoEnsureACL(conn
) < 0)
1395 if (!driver
->hostsysinfo
) {
1396 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
1397 _("Host SMBIOS information is not available"));
1401 if (virSysinfoFormat(&buf
, driver
->hostsysinfo
) < 0)
1403 if (virBufferCheckError(&buf
) < 0)
1405 return virBufferContentAndReset(&buf
);
1409 qemuConnectGetMaxVcpus(virConnectPtr conn ATTRIBUTE_UNUSED
, const char *type
)
1411 if (virConnectGetMaxVcpusEnsureACL(conn
) < 0)
1417 if (STRCASEEQ(type
, "qemu"))
1420 if (STRCASEEQ(type
, "kvm"))
1421 return virHostCPUGetKVMMaxVCPUs();
1423 virReportError(VIR_ERR_INVALID_ARG
,
1424 _("unknown type '%s'"), type
);
1429 static char *qemuConnectGetCapabilities(virConnectPtr conn
) {
1430 virQEMUDriverPtr driver
= conn
->privateData
;
1431 virCapsPtr caps
= NULL
;
1434 if (virConnectGetCapabilitiesEnsureACL(conn
) < 0)
1437 if (!(caps
= virQEMUDriverGetCapabilities(driver
, true)))
1440 xml
= virCapabilitiesFormatXML(caps
);
1441 virObjectUnref(caps
);
1450 qemuGetSchedInfo(unsigned long long *cpuWait
,
1451 pid_t pid
, pid_t tid
)
1455 char **lines
= NULL
;
1462 /* In general, we cannot assume pid_t fits in int; but /proc parsing
1463 * is specific to Linux where int works fine. */
1465 ret
= virAsprintf(&proc
, "/proc/%d/task/%d/sched", (int)pid
, (int)tid
);
1467 ret
= virAsprintf(&proc
, "/proc/%d/sched", (int)pid
);
1472 /* The file is not guaranteed to exist (needs CONFIG_SCHED_DEBUG) */
1473 if (access(proc
, R_OK
) < 0) {
1478 if (virFileReadAll(proc
, (1<<16), &data
) < 0)
1481 lines
= virStringSplit(data
, "\n", 0);
1485 for (i
= 0; lines
[i
] != NULL
; i
++) {
1486 const char *line
= lines
[i
];
1488 /* Needs CONFIG_SCHEDSTATS. The second check
1489 * is the old name the kernel used in past */
1490 if (STRPREFIX(line
, "se.statistics.wait_sum") ||
1491 STRPREFIX(line
, "se.wait_sum")) {
1492 line
= strchr(line
, ':');
1494 virReportError(VIR_ERR_INTERNAL_ERROR
,
1495 _("Missing separator in sched info '%s'"),
1500 while (*line
== ' ')
1503 if (virStrToDouble(line
, NULL
, &val
) < 0) {
1504 virReportError(VIR_ERR_INTERNAL_ERROR
,
1505 _("Unable to parse sched info value '%s'"),
1510 *cpuWait
= (unsigned long long)(val
* 1000000);
1520 virStringListFree(lines
);
1526 qemuGetProcessInfo(unsigned long long *cpuTime
, int *lastCpu
, long *vm_rss
,
1531 unsigned long long usertime
= 0, systime
= 0;
1536 /* In general, we cannot assume pid_t fits in int; but /proc parsing
1537 * is specific to Linux where int works fine. */
1539 ret
= virAsprintf(&proc
, "/proc/%d/task/%d/stat", (int)pid
, tid
);
1541 ret
= virAsprintf(&proc
, "/proc/%d/stat", (int)pid
);
1545 pidinfo
= fopen(proc
, "r");
1548 /* See 'man proc' for information about what all these fields are. We're
1549 * only interested in a very few of them */
1553 "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %llu %llu"
1554 /* cutime -> endcode */
1555 "%*d %*d %*d %*d %*d %*d %*u %*u %ld %*u %*u %*u"
1556 /* startstack -> processor */
1557 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %d",
1558 &usertime
, &systime
, &rss
, &cpu
) != 4) {
1559 VIR_WARN("cannot parse process status data");
1563 * We want nanoseconds
1564 * _SC_CLK_TCK is jiffies per second
1565 * So calculate thus....
1568 *cpuTime
= 1000ull * 1000ull * 1000ull * (usertime
+ systime
)
1569 / (unsigned long long)sysconf(_SC_CLK_TCK
);
1574 *vm_rss
= rss
* virGetSystemPageSizeKB();
1577 VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d rss=%ld",
1578 (int)pid
, tid
, usertime
, systime
, cpu
, rss
);
1580 VIR_FORCE_FCLOSE(pidinfo
);
1587 qemuDomainHelperGetVcpus(virDomainObjPtr vm
,
1588 virVcpuInfoPtr info
,
1589 unsigned long long *cpuwait
,
1591 unsigned char *cpumaps
,
1594 size_t ncpuinfo
= 0;
1600 if (!qemuDomainHasVcpuPids(vm
)) {
1601 virReportError(VIR_ERR_OPERATION_INVALID
,
1602 "%s", _("cpu affinity is not supported"));
1607 memset(info
, 0, sizeof(*info
) * maxinfo
);
1610 memset(cpumaps
, 0, sizeof(*cpumaps
) * maxinfo
);
1612 for (i
= 0; i
< virDomainDefGetVcpusMax(vm
->def
) && ncpuinfo
< maxinfo
; i
++) {
1613 virDomainVcpuDefPtr vcpu
= virDomainDefGetVcpu(vm
->def
, i
);
1614 pid_t vcpupid
= qemuDomainGetVcpuPid(vm
, i
);
1615 virVcpuInfoPtr vcpuinfo
= info
+ ncpuinfo
;
1621 vcpuinfo
->number
= i
;
1622 vcpuinfo
->state
= VIR_VCPU_RUNNING
;
1624 if (qemuGetProcessInfo(&vcpuinfo
->cpuTime
,
1625 &vcpuinfo
->cpu
, NULL
,
1626 vm
->pid
, vcpupid
) < 0) {
1627 virReportSystemError(errno
, "%s",
1628 _("cannot get vCPU placement & pCPU time"));
1634 unsigned char *cpumap
= VIR_GET_CPUMAP(cpumaps
, maplen
, ncpuinfo
);
1635 virBitmapPtr map
= NULL
;
1637 if (!(map
= virProcessGetAffinity(vcpupid
)))
1640 virBitmapToDataBuf(map
, cpumap
, maplen
);
1645 if (qemuGetSchedInfo(&(cpuwait
[ncpuinfo
]), vm
->pid
, vcpupid
) < 0)
1656 static virDomainPtr
qemuDomainLookupByID(virConnectPtr conn
,
1659 virQEMUDriverPtr driver
= conn
->privateData
;
1661 virDomainPtr dom
= NULL
;
1663 vm
= virDomainObjListFindByID(driver
->domains
, id
);
1666 virReportError(VIR_ERR_NO_DOMAIN
,
1667 _("no domain with matching id %d"), id
);
1671 if (virDomainLookupByIDEnsureACL(conn
, vm
->def
) < 0)
1674 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
1677 virDomainObjEndAPI(&vm
);
1681 static virDomainPtr
qemuDomainLookupByUUID(virConnectPtr conn
,
1682 const unsigned char *uuid
)
1684 virQEMUDriverPtr driver
= conn
->privateData
;
1686 virDomainPtr dom
= NULL
;
1688 vm
= virDomainObjListFindByUUID(driver
->domains
, uuid
);
1691 char uuidstr
[VIR_UUID_STRING_BUFLEN
];
1692 virUUIDFormat(uuid
, uuidstr
);
1693 virReportError(VIR_ERR_NO_DOMAIN
,
1694 _("no domain with matching uuid '%s'"), uuidstr
);
1698 if (virDomainLookupByUUIDEnsureACL(conn
, vm
->def
) < 0)
1701 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
1704 virDomainObjEndAPI(&vm
);
1708 static virDomainPtr
qemuDomainLookupByName(virConnectPtr conn
,
1711 virQEMUDriverPtr driver
= conn
->privateData
;
1713 virDomainPtr dom
= NULL
;
1715 vm
= virDomainObjListFindByName(driver
->domains
, name
);
1718 virReportError(VIR_ERR_NO_DOMAIN
,
1719 _("no domain with matching name '%s'"), name
);
1723 if (virDomainLookupByNameEnsureACL(conn
, vm
->def
) < 0)
1726 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
1729 virDomainObjEndAPI(&vm
);
1734 static int qemuDomainIsActive(virDomainPtr dom
)
1736 virDomainObjPtr obj
;
1739 if (!(obj
= qemuDomObjFromDomain(dom
)))
1742 if (virDomainIsActiveEnsureACL(dom
->conn
, obj
->def
) < 0)
1745 ret
= virDomainObjIsActive(obj
);
1748 virDomainObjEndAPI(&obj
);
1752 static int qemuDomainIsPersistent(virDomainPtr dom
)
1754 virDomainObjPtr obj
;
1757 if (!(obj
= qemuDomObjFromDomain(dom
)))
1760 if (virDomainIsPersistentEnsureACL(dom
->conn
, obj
->def
) < 0)
1763 ret
= obj
->persistent
;
1766 virDomainObjEndAPI(&obj
);
1770 static int qemuDomainIsUpdated(virDomainPtr dom
)
1772 virDomainObjPtr obj
;
1775 if (!(obj
= qemuDomObjFromDomain(dom
)))
1778 if (virDomainIsUpdatedEnsureACL(dom
->conn
, obj
->def
) < 0)
1784 virDomainObjEndAPI(&obj
);
1788 static int qemuConnectGetVersion(virConnectPtr conn
, unsigned long *version
)
1790 virQEMUDriverPtr driver
= conn
->privateData
;
1792 unsigned int qemuVersion
= 0;
1793 virCapsPtr caps
= NULL
;
1795 if (virConnectGetVersionEnsureACL(conn
) < 0)
1798 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
1801 if (virQEMUCapsGetDefaultVersion(caps
,
1802 driver
->qemuCapsCache
,
1806 *version
= qemuVersion
;
1810 virObjectUnref(caps
);
1815 static char *qemuConnectGetHostname(virConnectPtr conn
)
1817 if (virConnectGetHostnameEnsureACL(conn
) < 0)
1820 return virGetHostname();
1824 static int qemuConnectListDomains(virConnectPtr conn
, int *ids
, int nids
)
1826 virQEMUDriverPtr driver
= conn
->privateData
;
1829 if (virConnectListDomainsEnsureACL(conn
) < 0)
1832 n
= virDomainObjListGetActiveIDs(driver
->domains
, ids
, nids
,
1833 virConnectListDomainsCheckACL
, conn
);
1838 static int qemuConnectNumOfDomains(virConnectPtr conn
)
1840 virQEMUDriverPtr driver
= conn
->privateData
;
1843 if (virConnectNumOfDomainsEnsureACL(conn
) < 0)
1846 n
= virDomainObjListNumOfDomains(driver
->domains
, true,
1847 virConnectNumOfDomainsCheckACL
, conn
);
1853 static virDomainPtr
qemuDomainCreateXML(virConnectPtr conn
,
1857 virQEMUDriverPtr driver
= conn
->privateData
;
1858 virDomainDefPtr def
= NULL
;
1859 virDomainObjPtr vm
= NULL
;
1860 virDomainPtr dom
= NULL
;
1861 virObjectEventPtr event
= NULL
;
1862 virObjectEventPtr event2
= NULL
;
1863 unsigned int start_flags
= VIR_QEMU_PROCESS_START_COLD
;
1864 virCapsPtr caps
= NULL
;
1865 unsigned int parse_flags
= VIR_DOMAIN_DEF_PARSE_INACTIVE
|
1866 VIR_DOMAIN_DEF_PARSE_ABI_UPDATE
;
1868 virCheckFlags(VIR_DOMAIN_START_PAUSED
|
1869 VIR_DOMAIN_START_AUTODESTROY
|
1870 VIR_DOMAIN_START_VALIDATE
, NULL
);
1872 if (flags
& VIR_DOMAIN_START_VALIDATE
)
1873 parse_flags
|= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA
;
1874 if (flags
& VIR_DOMAIN_START_PAUSED
)
1875 start_flags
|= VIR_QEMU_PROCESS_START_PAUSED
;
1876 if (flags
& VIR_DOMAIN_START_AUTODESTROY
)
1877 start_flags
|= VIR_QEMU_PROCESS_START_AUTODESTROY
;
1879 virNWFilterReadLockFilterUpdates();
1881 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
1884 if (!(def
= virDomainDefParseString(xml
, caps
, driver
->xmlopt
,
1885 NULL
, parse_flags
)))
1888 if (virDomainCreateXMLEnsureACL(conn
, def
) < 0)
1891 if (!(vm
= virDomainObjListAdd(driver
->domains
, def
,
1893 VIR_DOMAIN_OBJ_LIST_ADD_LIVE
|
1894 VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE
,
1899 if (qemuProcessBeginJob(driver
, vm
, VIR_DOMAIN_JOB_OPERATION_START
,
1901 qemuDomainRemoveInactiveJob(driver
, vm
);
1905 if (qemuProcessStart(conn
, driver
, vm
, NULL
, QEMU_ASYNC_JOB_START
,
1906 NULL
, -1, NULL
, NULL
,
1907 VIR_NETDEV_VPORT_PROFILE_OP_CREATE
,
1909 virDomainAuditStart(vm
, "booted", false);
1910 qemuDomainRemoveInactive(driver
, vm
);
1911 qemuProcessEndJob(driver
, vm
);
1915 event
= virDomainEventLifecycleNewFromObj(vm
,
1916 VIR_DOMAIN_EVENT_STARTED
,
1917 VIR_DOMAIN_EVENT_STARTED_BOOTED
);
1918 if (event
&& (flags
& VIR_DOMAIN_START_PAUSED
)) {
1919 /* There are two classes of event-watching clients - those
1920 * that only care about on/off (and must see a started event
1921 * no matter what, but don't care about suspend events), and
1922 * those that also care about running/paused. To satisfy both
1923 * client types, we have to send two events. */
1924 event2
= virDomainEventLifecycleNewFromObj(vm
,
1925 VIR_DOMAIN_EVENT_SUSPENDED
,
1926 VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
);
1928 virDomainAuditStart(vm
, "booted", true);
1930 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
1932 qemuProcessEndJob(driver
, vm
);
1935 virDomainDefFree(def
);
1936 virDomainObjEndAPI(&vm
);
1937 virObjectEventStateQueue(driver
->domainEventState
, event
);
1938 virObjectEventStateQueue(driver
->domainEventState
, event2
);
1939 virObjectUnref(caps
);
1940 virNWFilterUnlockFilterUpdates();
1945 static int qemuDomainSuspend(virDomainPtr dom
)
1947 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
1950 virObjectEventPtr event
= NULL
;
1951 qemuDomainObjPrivatePtr priv
;
1952 virDomainPausedReason reason
;
1955 virQEMUDriverConfigPtr cfg
= NULL
;
1957 if (!(vm
= qemuDomObjFromDomain(dom
)))
1960 if (virDomainSuspendEnsureACL(dom
->conn
, vm
->def
) < 0)
1963 cfg
= virQEMUDriverGetConfig(driver
);
1964 priv
= vm
->privateData
;
1966 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_SUSPEND
) < 0)
1969 if (virDomainObjCheckActive(vm
) < 0)
1972 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_OUT
) {
1973 reason
= VIR_DOMAIN_PAUSED_MIGRATION
;
1974 eventDetail
= VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED
;
1975 } else if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_SNAPSHOT
) {
1976 reason
= VIR_DOMAIN_PAUSED_SNAPSHOT
;
1977 eventDetail
= -1; /* don't create lifecycle events when doing snapshot */
1979 reason
= VIR_DOMAIN_PAUSED_USER
;
1980 eventDetail
= VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
;
1983 state
= virDomainObjGetState(vm
, NULL
);
1984 if (state
== VIR_DOMAIN_PMSUSPENDED
) {
1985 virReportError(VIR_ERR_OPERATION_INVALID
,
1986 "%s", _("domain is pmsuspended"));
1988 } else if (state
!= VIR_DOMAIN_PAUSED
) {
1989 if (qemuProcessStopCPUs(driver
, vm
, reason
, QEMU_ASYNC_JOB_NONE
) < 0)
1992 if (eventDetail
>= 0) {
1993 event
= virDomainEventLifecycleNewFromObj(vm
,
1994 VIR_DOMAIN_EVENT_SUSPENDED
,
1998 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
2003 qemuDomainObjEndJob(driver
, vm
);
2006 virDomainObjEndAPI(&vm
);
2008 virObjectEventStateQueue(driver
->domainEventState
, event
);
2009 virObjectUnref(cfg
);
2014 static int qemuDomainResume(virDomainPtr dom
)
2016 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2021 virQEMUDriverConfigPtr cfg
= NULL
;
2023 if (!(vm
= qemuDomObjFromDomain(dom
)))
2026 cfg
= virQEMUDriverGetConfig(driver
);
2028 if (virDomainResumeEnsureACL(dom
->conn
, vm
->def
) < 0)
2031 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2034 if (virDomainObjCheckActive(vm
) < 0)
2037 state
= virDomainObjGetState(vm
, &reason
);
2038 if (state
== VIR_DOMAIN_PMSUSPENDED
) {
2039 virReportError(VIR_ERR_OPERATION_INVALID
,
2040 "%s", _("domain is pmsuspended"));
2042 } else if (state
== VIR_DOMAIN_RUNNING
) {
2043 virReportError(VIR_ERR_OPERATION_INVALID
,
2044 "%s", _("domain is already running"));
2046 } else if ((state
== VIR_DOMAIN_CRASHED
&&
2047 reason
== VIR_DOMAIN_CRASHED_PANICKED
) ||
2048 state
== VIR_DOMAIN_PAUSED
) {
2049 if (qemuProcessStartCPUs(driver
, vm
,
2050 VIR_DOMAIN_RUNNING_UNPAUSED
,
2051 QEMU_ASYNC_JOB_NONE
) < 0) {
2052 if (virGetLastErrorCode() == VIR_ERR_OK
)
2053 virReportError(VIR_ERR_OPERATION_FAILED
,
2054 "%s", _("resume operation failed"));
2058 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
2063 qemuDomainObjEndJob(driver
, vm
);
2066 virDomainObjEndAPI(&vm
);
2067 virObjectUnref(cfg
);
2071 static int qemuDomainShutdownFlags(virDomainPtr dom
, unsigned int flags
)
2073 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2076 qemuDomainObjPrivatePtr priv
;
2077 bool useAgent
= false, agentRequested
, acpiRequested
;
2078 bool isReboot
= false;
2080 qemuDomainAgentJob agentJob
= QEMU_AGENT_JOB_NONE
;
2081 int agentFlag
= QEMU_AGENT_SHUTDOWN_POWERDOWN
;
2083 virCheckFlags(VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN
|
2084 VIR_DOMAIN_SHUTDOWN_GUEST_AGENT
, -1);
2086 if (!(vm
= qemuDomObjFromDomain(dom
)))
2089 if (vm
->def
->onPoweroff
== VIR_DOMAIN_LIFECYCLE_ACTION_RESTART
||
2090 vm
->def
->onPoweroff
== VIR_DOMAIN_LIFECYCLE_ACTION_RESTART_RENAME
) {
2092 agentFlag
= QEMU_AGENT_SHUTDOWN_REBOOT
;
2093 VIR_INFO("Domain on_poweroff setting overridden, attempting reboot");
2096 priv
= vm
->privateData
;
2097 agentRequested
= flags
& VIR_DOMAIN_SHUTDOWN_GUEST_AGENT
;
2098 acpiRequested
= flags
& VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN
;
2100 /* Prefer agent unless we were requested to not to. */
2101 if (agentRequested
|| (!flags
&& priv
->agent
))
2104 if (virDomainShutdownFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
2108 agentJob
= QEMU_AGENT_JOB_MODIFY
;
2110 if (qemuDomainObjBeginJobWithAgent(driver
, vm
,
2115 if (virDomainObjGetState(vm
, NULL
) != VIR_DOMAIN_RUNNING
) {
2116 virReportError(VIR_ERR_OPERATION_INVALID
,
2117 "%s", _("domain is not running"));
2121 agentForced
= agentRequested
&& !acpiRequested
;
2122 if (!qemuDomainAgentAvailable(vm
, agentForced
)) {
2131 qemuDomainSetFakeReboot(driver
, vm
, false);
2132 agent
= qemuDomainObjEnterAgent(vm
);
2133 ret
= qemuAgentShutdown(agent
, agentFlag
);
2134 qemuDomainObjExitAgent(vm
, agent
);
2137 /* If we are not enforced to use just an agent, try ACPI
2138 * shutdown as well in case agent did not succeed.
2141 (ret
< 0 && (acpiRequested
|| !flags
))) {
2143 /* Even if agent failed, we have to check if guest went away
2144 * by itself while our locks were down. */
2145 if (useAgent
&& !virDomainObjIsActive(vm
)) {
2150 qemuDomainSetFakeReboot(driver
, vm
, isReboot
);
2151 qemuDomainObjEnterMonitor(driver
, vm
);
2152 ret
= qemuMonitorSystemPowerdown(priv
->mon
);
2153 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2159 qemuDomainObjEndJobWithAgent(driver
, vm
);
2161 qemuDomainObjEndJob(driver
, vm
);
2164 virDomainObjEndAPI(&vm
);
2168 static int qemuDomainShutdown(virDomainPtr dom
)
2170 return qemuDomainShutdownFlags(dom
, 0);
2175 qemuDomainReboot(virDomainPtr dom
, unsigned int flags
)
2177 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2180 qemuDomainObjPrivatePtr priv
;
2181 bool useAgent
= false, agentRequested
, acpiRequested
;
2182 bool isReboot
= true;
2184 qemuDomainAgentJob agentJob
= QEMU_AGENT_JOB_NONE
;
2185 int agentFlag
= QEMU_AGENT_SHUTDOWN_REBOOT
;
2187 virCheckFlags(VIR_DOMAIN_REBOOT_ACPI_POWER_BTN
|
2188 VIR_DOMAIN_REBOOT_GUEST_AGENT
, -1);
2190 if (!(vm
= qemuDomObjFromDomain(dom
)))
2193 if (vm
->def
->onReboot
== VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY
||
2194 vm
->def
->onReboot
== VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE
) {
2195 agentFlag
= QEMU_AGENT_SHUTDOWN_POWERDOWN
;
2197 VIR_INFO("Domain on_reboot setting overridden, shutting down");
2200 priv
= vm
->privateData
;
2201 agentRequested
= flags
& VIR_DOMAIN_REBOOT_GUEST_AGENT
;
2202 acpiRequested
= flags
& VIR_DOMAIN_REBOOT_ACPI_POWER_BTN
;
2204 /* Prefer agent unless we were requested to not to. */
2205 if (agentRequested
|| (!flags
&& priv
->agent
))
2208 if (virDomainRebootEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
2212 agentJob
= QEMU_AGENT_JOB_MODIFY
;
2214 if (qemuDomainObjBeginJobWithAgent(driver
, vm
,
2219 agentForced
= agentRequested
&& !acpiRequested
;
2220 if (!qemuDomainAgentAvailable(vm
, agentForced
)) {
2226 if (virDomainObjCheckActive(vm
) < 0)
2232 qemuDomainSetFakeReboot(driver
, vm
, false);
2233 agent
= qemuDomainObjEnterAgent(vm
);
2234 ret
= qemuAgentShutdown(agent
, agentFlag
);
2235 qemuDomainObjExitAgent(vm
, agent
);
2238 /* If we are not enforced to use just an agent, try ACPI
2239 * shutdown as well in case agent did not succeed.
2242 (ret
< 0 && (acpiRequested
|| !flags
))) {
2244 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2245 _("ACPI reboot is not supported without the JSON monitor"));
2248 qemuDomainSetFakeReboot(driver
, vm
, isReboot
);
2249 qemuDomainObjEnterMonitor(driver
, vm
);
2250 ret
= qemuMonitorSystemPowerdown(priv
->mon
);
2251 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2257 qemuDomainObjEndJobWithAgent(driver
, vm
);
2259 qemuDomainObjEndJob(driver
, vm
);
2262 virDomainObjEndAPI(&vm
);
2268 qemuDomainReset(virDomainPtr dom
, unsigned int flags
)
2270 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2273 qemuDomainObjPrivatePtr priv
;
2274 virDomainState state
;
2276 virCheckFlags(0, -1);
2278 if (!(vm
= qemuDomObjFromDomain(dom
)))
2281 if (virDomainResetEnsureACL(dom
->conn
, vm
->def
) < 0)
2284 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2287 if (virDomainObjCheckActive(vm
) < 0)
2290 priv
= vm
->privateData
;
2291 qemuDomainObjEnterMonitor(driver
, vm
);
2292 ret
= qemuMonitorSystemReset(priv
->mon
);
2293 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2296 priv
->fakeReboot
= false;
2298 state
= virDomainObjGetState(vm
, NULL
);
2299 if (state
== VIR_DOMAIN_CRASHED
)
2300 virDomainObjSetState(vm
, VIR_DOMAIN_PAUSED
, VIR_DOMAIN_PAUSED_CRASHED
);
2303 qemuDomainObjEndJob(driver
, vm
);
2306 virDomainObjEndAPI(&vm
);
2311 /* Count how many snapshots in a set are external snapshots. */
2313 qemuDomainSnapshotCountExternal(void *payload
,
2314 const void *name ATTRIBUTE_UNUSED
,
2317 virDomainSnapshotObjPtr snap
= payload
;
2320 if (virDomainSnapshotIsExternal(snap
))
2326 qemuDomainDestroyFlags(virDomainPtr dom
,
2329 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2332 virObjectEventPtr event
= NULL
;
2333 qemuDomainObjPrivatePtr priv
;
2334 unsigned int stopFlags
= 0;
2339 virCheckFlags(VIR_DOMAIN_DESTROY_GRACEFUL
, -1);
2341 if (!(vm
= qemuDomObjFromDomain(dom
)))
2344 priv
= vm
->privateData
;
2346 if (virDomainDestroyFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
2349 if (virDomainObjCheckActive(vm
) < 0)
2352 state
= virDomainObjGetState(vm
, &reason
);
2353 starting
= (state
== VIR_DOMAIN_PAUSED
&&
2354 reason
== VIR_DOMAIN_PAUSED_STARTING_UP
&&
2355 !priv
->beingDestroyed
);
2357 if (qemuProcessBeginStopJob(driver
, vm
, QEMU_JOB_DESTROY
,
2358 !(flags
& VIR_DOMAIN_DESTROY_GRACEFUL
)) < 0)
2361 if (!virDomainObjIsActive(vm
)) {
2363 VIR_DEBUG("Domain %s is not running anymore", vm
->def
->name
);
2366 virReportError(VIR_ERR_OPERATION_INVALID
,
2367 "%s", _("domain is not running"));
2372 qemuDomainSetFakeReboot(driver
, vm
, false);
2374 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_IN
)
2375 stopFlags
|= VIR_QEMU_PROCESS_STOP_MIGRATED
;
2377 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_DESTROYED
,
2378 QEMU_ASYNC_JOB_NONE
, stopFlags
);
2379 event
= virDomainEventLifecycleNewFromObj(vm
,
2380 VIR_DOMAIN_EVENT_STOPPED
,
2381 VIR_DOMAIN_EVENT_STOPPED_DESTROYED
);
2382 virDomainAuditStop(vm
, "destroyed");
2387 qemuDomainRemoveInactive(driver
, vm
);
2388 qemuDomainObjEndJob(driver
, vm
);
2391 virDomainObjEndAPI(&vm
);
2392 virObjectEventStateQueue(driver
->domainEventState
, event
);
2397 qemuDomainDestroy(virDomainPtr dom
)
2399 return qemuDomainDestroyFlags(dom
, 0);
2402 static char *qemuDomainGetOSType(virDomainPtr dom
) {
2406 if (!(vm
= qemuDomObjFromDomain(dom
)))
2409 if (virDomainGetOSTypeEnsureACL(dom
->conn
, vm
->def
) < 0)
2412 ignore_value(VIR_STRDUP(type
, virDomainOSTypeToString(vm
->def
->os
.type
)));
2415 virDomainObjEndAPI(&vm
);
2419 /* Returns max memory in kb, 0 if error */
2420 static unsigned long long
2421 qemuDomainGetMaxMemory(virDomainPtr dom
)
2424 unsigned long long ret
= 0;
2426 if (!(vm
= qemuDomObjFromDomain(dom
)))
2429 if (virDomainGetMaxMemoryEnsureACL(dom
->conn
, vm
->def
) < 0)
2432 ret
= virDomainDefGetMemoryTotal(vm
->def
);
2435 virDomainObjEndAPI(&vm
);
2439 static int qemuDomainSetMemoryFlags(virDomainPtr dom
, unsigned long newmem
,
2442 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2443 qemuDomainObjPrivatePtr priv
;
2445 virDomainDefPtr def
;
2446 virDomainDefPtr persistentDef
;
2448 virQEMUDriverConfigPtr cfg
= NULL
;
2450 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
2451 VIR_DOMAIN_AFFECT_CONFIG
|
2452 VIR_DOMAIN_MEM_MAXIMUM
, -1);
2454 if (!(vm
= qemuDomObjFromDomain(dom
)))
2457 cfg
= virQEMUDriverGetConfig(driver
);
2459 if (virDomainSetMemoryFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
2462 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2465 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
2469 if (flags
& VIR_DOMAIN_MEM_MAXIMUM
) {
2470 /* resize the maximum memory */
2473 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2474 _("cannot resize the maximum memory on an "
2479 if (persistentDef
) {
2480 /* resizing memory with NUMA nodes specified doesn't work as there
2481 * is no way to change the individual node sizes with this API */
2482 if (virDomainNumaGetNodeCount(persistentDef
->numa
) > 0) {
2483 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2484 _("initial memory size of a domain with NUMA "
2485 "nodes cannot be modified with this API"));
2489 if (persistentDef
->mem
.max_memory
&&
2490 persistentDef
->mem
.max_memory
< newmem
) {
2491 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2492 _("cannot set initial memory size greater than "
2493 "the maximum memory size"));
2497 virDomainDefSetMemoryTotal(persistentDef
, newmem
);
2499 if (persistentDef
->mem
.cur_balloon
> newmem
)
2500 persistentDef
->mem
.cur_balloon
= newmem
;
2501 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
2507 /* resize the current memory */
2508 unsigned long oldmax
= 0;
2511 oldmax
= virDomainDefGetMemoryTotal(def
);
2512 if (persistentDef
) {
2513 if (!oldmax
|| oldmax
> virDomainDefGetMemoryTotal(persistentDef
))
2514 oldmax
= virDomainDefGetMemoryTotal(persistentDef
);
2517 if (newmem
> oldmax
) {
2518 virReportError(VIR_ERR_INVALID_ARG
, "%s",
2519 _("cannot set memory higher than max memory"));
2524 priv
= vm
->privateData
;
2525 qemuDomainObjEnterMonitor(driver
, vm
);
2526 r
= qemuMonitorSetBalloon(priv
->mon
, newmem
);
2527 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || r
< 0)
2530 /* Lack of balloon support is a fatal error */
2532 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2533 _("Unable to change memory of active domain without "
2534 "the balloon device and guest OS balloon driver"));
2539 if (persistentDef
) {
2540 persistentDef
->mem
.cur_balloon
= newmem
;
2541 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
2549 qemuDomainObjEndJob(driver
, vm
);
2552 virDomainObjEndAPI(&vm
);
2553 virObjectUnref(cfg
);
2557 static int qemuDomainSetMemory(virDomainPtr dom
, unsigned long newmem
)
2559 return qemuDomainSetMemoryFlags(dom
, newmem
, VIR_DOMAIN_AFFECT_LIVE
);
2562 static int qemuDomainSetMaxMemory(virDomainPtr dom
, unsigned long memory
)
2564 return qemuDomainSetMemoryFlags(dom
, memory
, VIR_DOMAIN_MEM_MAXIMUM
);
2567 static int qemuDomainSetMemoryStatsPeriod(virDomainPtr dom
, int period
,
2570 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
2571 qemuDomainObjPrivatePtr priv
;
2573 virDomainDefPtr def
;
2574 virDomainDefPtr persistentDef
;
2576 virQEMUDriverConfigPtr cfg
= NULL
;
2578 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
2579 VIR_DOMAIN_AFFECT_CONFIG
, -1);
2581 if (!(vm
= qemuDomObjFromDomain(dom
)))
2584 cfg
= virQEMUDriverGetConfig(driver
);
2586 if (virDomainSetMemoryStatsPeriodEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
2589 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2592 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
2595 /* Set the balloon driver collection interval */
2596 priv
= vm
->privateData
;
2599 if (!virDomainDefHasMemballoon(def
)) {
2600 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
2601 _("No memory balloon device configured, "
2602 "can not set the collection period"));
2606 qemuDomainObjEnterMonitor(driver
, vm
);
2607 r
= qemuMonitorSetMemoryStatsPeriod(priv
->mon
, def
->memballoon
, period
);
2608 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2611 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
2612 _("unable to set balloon driver collection period"));
2616 def
->memballoon
->period
= period
;
2617 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
2621 if (persistentDef
) {
2622 if (!virDomainDefHasMemballoon(persistentDef
)) {
2623 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
2624 _("No memory balloon device configured, "
2625 "can not set the collection period"));
2628 persistentDef
->memballoon
->period
= period
;
2629 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
);
2635 qemuDomainObjEndJob(driver
, vm
);
2638 virDomainObjEndAPI(&vm
);
2639 virObjectUnref(cfg
);
2643 static int qemuDomainInjectNMI(virDomainPtr domain
, unsigned int flags
)
2645 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
2646 virDomainObjPtr vm
= NULL
;
2648 qemuDomainObjPrivatePtr priv
;
2650 virCheckFlags(0, -1);
2652 if (!(vm
= qemuDomObjFromDomain(domain
)))
2655 if (virDomainInjectNMIEnsureACL(domain
->conn
, vm
->def
) < 0)
2658 priv
= vm
->privateData
;
2660 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2663 if (virDomainObjCheckActive(vm
) < 0)
2666 qemuDomainObjEnterMonitor(driver
, vm
);
2667 ret
= qemuMonitorInjectNMI(priv
->mon
);
2668 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2672 qemuDomainObjEndJob(driver
, vm
);
2675 virDomainObjEndAPI(&vm
);
2679 static int qemuDomainSendKey(virDomainPtr domain
,
2680 unsigned int codeset
,
2681 unsigned int holdtime
,
2682 unsigned int *keycodes
,
2686 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
2687 virDomainObjPtr vm
= NULL
;
2689 qemuDomainObjPrivatePtr priv
;
2691 virCheckFlags(0, -1);
2693 /* translate the keycode to QNUM for qemu driver */
2694 if (codeset
!= VIR_KEYCODE_SET_QNUM
) {
2698 for (i
= 0; i
< nkeycodes
; i
++) {
2699 keycode
= virKeycodeValueTranslate(codeset
, VIR_KEYCODE_SET_QNUM
,
2702 virReportError(VIR_ERR_INTERNAL_ERROR
,
2703 _("cannot translate keycode %u of %s codeset to qnum keycode"),
2705 virKeycodeSetTypeToString(codeset
));
2708 keycodes
[i
] = keycode
;
2712 if (!(vm
= qemuDomObjFromDomain(domain
)))
2715 priv
= vm
->privateData
;
2717 if (virDomainSendKeyEnsureACL(domain
->conn
, vm
->def
) < 0)
2720 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
2723 if (virDomainObjCheckActive(vm
) < 0)
2726 qemuDomainObjEnterMonitor(driver
, vm
);
2727 ret
= qemuMonitorSendKey(priv
->mon
, holdtime
, keycodes
, nkeycodes
);
2728 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
2732 qemuDomainObjEndJob(driver
, vm
);
2735 virDomainObjEndAPI(&vm
);
2741 qemuDomainGetInfo(virDomainPtr dom
,
2742 virDomainInfoPtr info
)
2744 unsigned long long maxmem
;
2748 if (!(vm
= qemuDomObjFromDomain(dom
)))
2751 if (virDomainGetInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
2754 qemuDomainUpdateCurrentMemorySize(vm
);
2756 memset(info
, 0, sizeof(*info
));
2758 info
->state
= virDomainObjGetState(vm
, NULL
);
2760 maxmem
= virDomainDefGetMemoryTotal(vm
->def
);
2761 if (VIR_ASSIGN_IS_OVERFLOW(info
->maxMem
, maxmem
)) {
2762 virReportError(VIR_ERR_OVERFLOW
, "%s",
2763 _("Initial memory size too large"));
2767 if (VIR_ASSIGN_IS_OVERFLOW(info
->memory
, vm
->def
->mem
.cur_balloon
)) {
2768 virReportError(VIR_ERR_OVERFLOW
, "%s",
2769 _("Current memory size too large"));
2773 if (virDomainObjIsActive(vm
)) {
2774 if (qemuGetProcessInfo(&(info
->cpuTime
), NULL
, NULL
, vm
->pid
, 0) < 0) {
2775 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
2776 _("cannot read cputime for domain"));
2781 if (VIR_ASSIGN_IS_OVERFLOW(info
->nrVirtCpu
, virDomainDefGetVcpus(vm
->def
))) {
2782 virReportError(VIR_ERR_OVERFLOW
, "%s", _("cpu count too large"));
2789 virDomainObjEndAPI(&vm
);
2794 qemuDomainGetState(virDomainPtr dom
,
2802 virCheckFlags(0, -1);
2804 if (!(vm
= qemuDomObjFromDomain(dom
)))
2807 if (virDomainGetStateEnsureACL(dom
->conn
, vm
->def
) < 0)
2810 *state
= virDomainObjGetState(vm
, reason
);
2814 virDomainObjEndAPI(&vm
);
2819 qemuDomainGetControlInfo(virDomainPtr dom
,
2820 virDomainControlInfoPtr info
,
2824 qemuDomainObjPrivatePtr priv
;
2827 virCheckFlags(0, -1);
2829 if (!(vm
= qemuDomObjFromDomain(dom
)))
2832 if (virDomainGetControlInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
2835 if (virDomainObjCheckActive(vm
) < 0)
2838 priv
= vm
->privateData
;
2840 memset(info
, 0, sizeof(*info
));
2842 if (priv
->monError
) {
2843 info
->state
= VIR_DOMAIN_CONTROL_ERROR
;
2844 info
->details
= VIR_DOMAIN_CONTROL_ERROR_REASON_MONITOR
;
2845 } else if (priv
->job
.active
) {
2846 if (virTimeMillisNow(&info
->stateTime
) < 0)
2848 if (priv
->job
.current
) {
2849 info
->state
= VIR_DOMAIN_CONTROL_JOB
;
2850 info
->stateTime
-= priv
->job
.current
->started
;
2852 if (priv
->monStart
> 0) {
2853 info
->state
= VIR_DOMAIN_CONTROL_OCCUPIED
;
2854 info
->stateTime
-= priv
->monStart
;
2856 /* At this point the domain has an active job, but monitor was
2857 * not entered and the domain object lock is not held thus we
2858 * are stuck in the job forever due to a programming error.
2860 info
->state
= VIR_DOMAIN_CONTROL_ERROR
;
2861 info
->details
= VIR_DOMAIN_CONTROL_ERROR_REASON_INTERNAL
;
2862 info
->stateTime
= 0;
2866 info
->state
= VIR_DOMAIN_CONTROL_OK
;
2872 virDomainObjEndAPI(&vm
);
2877 /* It would be nice to replace 'Qemud' with 'Qemu' but
2878 * this magic string is ABI, so it can't be changed
2880 #define QEMU_SAVE_MAGIC "LibvirtQemudSave"
2881 #define QEMU_SAVE_PARTIAL "LibvirtQemudPart"
2882 #define QEMU_SAVE_VERSION 2
2884 verify(sizeof(QEMU_SAVE_MAGIC
) == sizeof(QEMU_SAVE_PARTIAL
));
2887 QEMU_SAVE_FORMAT_RAW
= 0,
2888 QEMU_SAVE_FORMAT_GZIP
= 1,
2889 QEMU_SAVE_FORMAT_BZIP2
= 2,
2891 * Deprecated by xz and never used as part of a release
2892 * QEMU_SAVE_FORMAT_LZMA
2894 QEMU_SAVE_FORMAT_XZ
= 3,
2895 QEMU_SAVE_FORMAT_LZOP
= 4,
2896 /* Note: add new members only at the end.
2897 These values are used in the on-disk format.
2898 Do not change or re-use numbers. */
2900 QEMU_SAVE_FORMAT_LAST
2901 } virQEMUSaveFormat
;
2903 VIR_ENUM_DECL(qemuSaveCompression
);
2904 VIR_ENUM_IMPL(qemuSaveCompression
, QEMU_SAVE_FORMAT_LAST
,
2912 VIR_ENUM_DECL(qemuDumpFormat
);
2913 VIR_ENUM_IMPL(qemuDumpFormat
, VIR_DOMAIN_CORE_DUMP_FORMAT_LAST
,
2920 typedef struct _virQEMUSaveHeader virQEMUSaveHeader
;
2921 typedef virQEMUSaveHeader
*virQEMUSaveHeaderPtr
;
2922 struct _virQEMUSaveHeader
{
2923 char magic
[sizeof(QEMU_SAVE_MAGIC
)-1];
2926 uint32_t was_running
;
2927 uint32_t compressed
;
2928 uint32_t cookieOffset
;
2929 uint32_t unused
[14];
2932 typedef struct _virQEMUSaveData virQEMUSaveData
;
2933 typedef virQEMUSaveData
*virQEMUSaveDataPtr
;
2934 struct _virQEMUSaveData
{
2935 virQEMUSaveHeader header
;
2942 bswap_header(virQEMUSaveHeaderPtr hdr
)
2944 hdr
->version
= bswap_32(hdr
->version
);
2945 hdr
->data_len
= bswap_32(hdr
->data_len
);
2946 hdr
->was_running
= bswap_32(hdr
->was_running
);
2947 hdr
->compressed
= bswap_32(hdr
->compressed
);
2948 hdr
->cookieOffset
= bswap_32(hdr
->cookieOffset
);
2953 virQEMUSaveDataFree(virQEMUSaveDataPtr data
)
2958 VIR_FREE(data
->xml
);
2959 VIR_FREE(data
->cookie
);
2965 * This function steals @domXML on success.
2967 static virQEMUSaveDataPtr
2968 virQEMUSaveDataNew(char *domXML
,
2969 qemuDomainSaveCookiePtr cookieObj
,
2972 virDomainXMLOptionPtr xmlopt
)
2974 virQEMUSaveDataPtr data
= NULL
;
2975 virQEMUSaveHeaderPtr header
;
2977 if (VIR_ALLOC(data
) < 0)
2980 VIR_STEAL_PTR(data
->xml
, domXML
);
2983 !(data
->cookie
= virSaveCookieFormat((virObjectPtr
) cookieObj
,
2984 virDomainXMLOptionGetSaveCookie(xmlopt
))))
2987 header
= &data
->header
;
2988 memcpy(header
->magic
, QEMU_SAVE_PARTIAL
, sizeof(header
->magic
));
2989 header
->version
= QEMU_SAVE_VERSION
;
2990 header
->was_running
= running
? 1 : 0;
2991 header
->compressed
= compressed
;
2996 virQEMUSaveDataFree(data
);
3001 /* virQEMUSaveDataWrite:
3003 * Writes libvirt's header (including domain XML) into a saved image of a
3004 * running domain. If @header has data_len filled in (because it was previously
3005 * read from the file), the function will make sure the new data will fit
3008 * Returns -1 on failure, or 0 on success.
3011 virQEMUSaveDataWrite(virQEMUSaveDataPtr data
,
3015 virQEMUSaveHeaderPtr header
= &data
->header
;
3018 size_t cookie_len
= 0;
3020 size_t zerosLen
= 0;
3023 xml_len
= strlen(data
->xml
) + 1;
3025 cookie_len
= strlen(data
->cookie
) + 1;
3027 len
= xml_len
+ cookie_len
;
3029 if (header
->data_len
> 0) {
3030 if (len
> header
->data_len
) {
3031 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
3032 _("new xml too large to fit in file"));
3036 zerosLen
= header
->data_len
- len
;
3037 if (VIR_ALLOC_N(zeros
, zerosLen
) < 0)
3040 header
->data_len
= len
;
3044 header
->cookieOffset
= xml_len
;
3046 if (safewrite(fd
, header
, sizeof(*header
)) != sizeof(*header
)) {
3047 virReportSystemError(errno
,
3048 _("failed to write header to domain save file '%s'"),
3053 if (safewrite(fd
, data
->xml
, xml_len
) != xml_len
) {
3054 virReportSystemError(errno
,
3055 _("failed to write domain xml to '%s'"),
3061 safewrite(fd
, data
->cookie
, cookie_len
) != cookie_len
) {
3062 virReportSystemError(errno
,
3063 _("failed to write cookie to '%s'"),
3068 if (safewrite(fd
, zeros
, zerosLen
) != zerosLen
) {
3069 virReportSystemError(errno
,
3070 _("failed to write padding to '%s'"),
3084 virQEMUSaveDataFinish(virQEMUSaveDataPtr data
,
3088 virQEMUSaveHeaderPtr header
= &data
->header
;
3090 memcpy(header
->magic
, QEMU_SAVE_MAGIC
, sizeof(header
->magic
));
3092 if (safewrite(*fd
, header
, sizeof(*header
)) != sizeof(*header
) ||
3093 VIR_CLOSE(*fd
) < 0) {
3094 virReportSystemError(errno
,
3095 _("failed to write header to domain save file '%s'"),
3104 static virCommandPtr
3105 qemuCompressGetCommand(virQEMUSaveFormat compression
)
3107 virCommandPtr ret
= NULL
;
3108 const char *prog
= qemuSaveCompressionTypeToString(compression
);
3111 virReportError(VIR_ERR_OPERATION_FAILED
,
3112 _("Invalid compressed save format %d"),
3117 ret
= virCommandNew(prog
);
3118 virCommandAddArg(ret
, "-dc");
3120 if (compression
== QEMU_SAVE_FORMAT_LZOP
)
3121 virCommandAddArg(ret
, "--ignore-warn");
3128 * @driver: driver object
3129 * @vm: domain object
3130 * @path: path to file to open
3131 * @oflags: flags for opening/creation of the file
3132 * @needUnlink: set to true if file was created by this function
3134 * Internal function to properly create or open existing files, with
3135 * ownership affected by qemu driver setup and domain DAC label.
3137 * Returns the file descriptor on success and negative errno on failure.
3139 * This function should not be used on storage sources. Use
3140 * qemuDomainStorageFileInit and storage driver APIs if possible.
3143 qemuOpenFile(virQEMUDriverPtr driver
,
3150 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
3151 uid_t user
= cfg
->user
;
3152 gid_t group
= cfg
->group
;
3153 bool dynamicOwnership
= cfg
->dynamicOwnership
;
3154 virSecurityLabelDefPtr seclabel
;
3156 virObjectUnref(cfg
);
3158 /* TODO: Take imagelabel into account? */
3160 (seclabel
= virDomainDefGetSecurityLabelDef(vm
->def
, "dac")) != NULL
&&
3161 seclabel
->label
!= NULL
&&
3162 (virParseOwnershipIds(seclabel
->label
, &user
, &group
) < 0))
3165 ret
= qemuOpenFileAs(user
, group
, dynamicOwnership
,
3166 path
, oflags
, needUnlink
);
3173 qemuOpenFileAs(uid_t fallback_uid
, gid_t fallback_gid
,
3174 bool dynamicOwnership
,
3175 const char *path
, int oflags
,
3180 bool need_unlink
= false;
3181 unsigned int vfoflags
= 0;
3183 int path_shared
= virFileIsSharedFS(path
);
3184 uid_t uid
= geteuid();
3185 gid_t gid
= getegid();
3187 /* path might be a pre-existing block dev, in which case
3188 * we need to skip the create step, and also avoid unlink
3189 * in the failure case */
3190 if (oflags
& O_CREAT
) {
3193 /* Don't force chown on network-shared FS
3194 * as it is likely to fail. */
3195 if (path_shared
<= 0 || dynamicOwnership
)
3196 vfoflags
|= VIR_FILE_OPEN_FORCE_OWNER
;
3198 if (stat(path
, &sb
) == 0) {
3199 /* It already exists, we don't want to delete it on error */
3200 need_unlink
= false;
3202 is_reg
= !!S_ISREG(sb
.st_mode
);
3203 /* If the path is regular file which exists
3204 * already and dynamic_ownership is off, we don't
3205 * want to change its ownership, just open it as-is */
3206 if (is_reg
&& !dynamicOwnership
) {
3213 /* First try creating the file as root */
3215 if ((fd
= open(path
, oflags
& ~O_CREAT
)) < 0) {
3220 if ((fd
= virFileOpenAs(path
, oflags
, S_IRUSR
| S_IWUSR
, uid
, gid
,
3221 vfoflags
| VIR_FILE_OPEN_NOFORK
)) < 0) {
3222 /* If we failed as root, and the error was permission-denied
3223 (EACCES or EPERM), assume it's on a network-connected share
3224 where root access is restricted (eg, root-squashed NFS). If the
3225 qemu user is non-root, just set a flag to
3226 bypass security driver shenanigans, and retry the operation
3227 after doing setuid to qemu user */
3228 if ((fd
!= -EACCES
&& fd
!= -EPERM
) || fallback_uid
== geteuid())
3231 /* On Linux we can also verify the FS-type of the directory. */
3232 switch (path_shared
) {
3234 /* it was on a network share, so we'll continue
3240 virReportSystemError(-fd
, oflags
& O_CREAT
3241 ? _("Failed to create file "
3242 "'%s': couldn't determine fs type")
3243 : _("Failed to open file "
3244 "'%s': couldn't determine fs type"),
3250 /* local file - log the error returned by virFileOpenAs */
3254 /* If we created the file above, then we need to remove it;
3255 * otherwise, the next attempt to create will fail. If the
3256 * file had already existed before we got here, then we also
3257 * don't want to delete it and allow the following to succeed
3258 * or fail based on existing protections
3263 /* Retry creating the file as qemu user */
3265 /* Since we're passing different modes... */
3266 vfoflags
|= VIR_FILE_OPEN_FORCE_MODE
;
3268 if ((fd
= virFileOpenAs(path
, oflags
,
3269 S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IWGRP
,
3270 fallback_uid
, fallback_gid
,
3271 vfoflags
| VIR_FILE_OPEN_FORK
)) < 0) {
3272 virReportSystemError(-fd
, oflags
& O_CREAT
3273 ? _("Error from child process creating '%s'")
3274 : _("Error from child process opening '%s'"),
3282 *needUnlink
= need_unlink
;
3286 virReportSystemError(-fd
, oflags
& O_CREAT
3287 ? _("Failed to create file '%s'")
3288 : _("Failed to open file '%s'"),
3295 qemuFileWrapperFDClose(virDomainObjPtr vm
,
3296 virFileWrapperFdPtr fd
)
3300 /* virFileWrapperFd uses iohelper to write data onto disk.
3301 * However, iohelper calls fdatasync() which may take ages to
3302 * finish. Therefore, we shouldn't be waiting with the domain
3305 /* XXX Currently, this function is intended for *Save() only
3306 * as restore needs some reworking before it's ready for
3309 virObjectUnlock(vm
);
3310 ret
= virFileWrapperFdClose(fd
);
3312 if (!virDomainObjIsActive(vm
)) {
3313 if (virGetLastErrorCode() == VIR_ERR_OK
)
3314 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
3315 _("domain is no longer running"));
3322 /* Helper function to execute a migration to file with a correct save header
3323 * the caller needs to make sure that the processors are stopped and do all other
3324 * actions besides saving memory */
3326 qemuDomainSaveMemory(virQEMUDriverPtr driver
,
3329 virQEMUSaveDataPtr data
,
3330 const char *compressedpath
,
3332 qemuDomainAsyncJob asyncJob
)
3334 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
3335 bool needUnlink
= false;
3339 virFileWrapperFdPtr wrapperFd
= NULL
;
3340 unsigned int wrapperFlags
= VIR_FILE_WRAPPER_NON_BLOCKING
;
3342 /* Obtain the file handle. */
3343 if ((flags
& VIR_DOMAIN_SAVE_BYPASS_CACHE
)) {
3344 wrapperFlags
|= VIR_FILE_WRAPPER_BYPASS_CACHE
;
3345 directFlag
= virFileDirectFdFlag();
3346 if (directFlag
< 0) {
3347 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
3348 _("bypass cache unsupported by this system"));
3353 fd
= qemuOpenFileAs(cfg
->user
, cfg
->group
, false, path
,
3354 O_WRONLY
| O_TRUNC
| O_CREAT
| directFlag
,
3359 if (qemuSecuritySetImageFDLabel(driver
->securityManager
, vm
->def
, fd
) < 0)
3362 if (!(wrapperFd
= virFileWrapperFdNew(&fd
, path
, wrapperFlags
)))
3365 if (virQEMUSaveDataWrite(data
, fd
, path
) < 0)
3368 /* Perform the migration */
3369 if (qemuMigrationSrcToFile(driver
, vm
, fd
, compressedpath
, asyncJob
) < 0)
3372 /* Touch up file header to mark image complete. */
3374 /* Reopen the file to touch up the header, since we aren't set
3375 * up to seek backwards on wrapperFd. The reopened fd will
3376 * trigger a single page of file system cache pollution, but
3377 * that's acceptable. */
3378 if (VIR_CLOSE(fd
) < 0) {
3379 virReportSystemError(errno
, _("unable to close %s"), path
);
3383 if (qemuFileWrapperFDClose(vm
, wrapperFd
) < 0)
3386 if ((fd
= qemuOpenFile(driver
, vm
, path
, O_WRONLY
, NULL
)) < 0 ||
3387 virQEMUSaveDataFinish(data
, &fd
, path
) < 0)
3393 VIR_FORCE_CLOSE(fd
);
3394 if (qemuFileWrapperFDClose(vm
, wrapperFd
) < 0)
3396 virFileWrapperFdFree(wrapperFd
);
3397 virObjectUnref(cfg
);
3399 if (ret
< 0 && needUnlink
)
3405 /* The vm must be active + locked. Vm will be unlocked and
3406 * potentially free'd after this returns (eg transient VMs are freed
3407 * shutdown). So 'vm' must not be referenced by the caller after
3408 * this returns (whether returning success or failure).
3411 qemuDomainSaveInternal(virQEMUDriverPtr driver
,
3412 virDomainObjPtr vm
, const char *path
,
3413 int compressed
, const char *compressedpath
,
3414 const char *xmlin
, unsigned int flags
)
3417 bool was_running
= false;
3419 virObjectEventPtr event
= NULL
;
3420 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
3422 virQEMUSaveDataPtr data
= NULL
;
3423 qemuDomainSaveCookiePtr cookie
= NULL
;
3425 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
3428 if (!qemuMigrationSrcIsAllowed(driver
, vm
, false, 0))
3431 if (qemuDomainObjBeginAsyncJob(driver
, vm
, QEMU_ASYNC_JOB_SAVE
,
3432 VIR_DOMAIN_JOB_OPERATION_SAVE
, flags
) < 0)
3435 if (!virDomainObjIsActive(vm
)) {
3436 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
3437 _("guest unexpectedly quit"));
3441 priv
->job
.current
->statsType
= QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP
;
3444 if (virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
) {
3446 if (qemuProcessStopCPUs(driver
, vm
, VIR_DOMAIN_PAUSED_SAVE
,
3447 QEMU_ASYNC_JOB_SAVE
) < 0)
3450 if (!virDomainObjIsActive(vm
)) {
3451 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
3452 _("guest unexpectedly quit"));
3457 /* libvirt-domain.c already guaranteed these two flags are exclusive. */
3458 if (flags
& VIR_DOMAIN_SAVE_RUNNING
)
3460 else if (flags
& VIR_DOMAIN_SAVE_PAUSED
)
3461 was_running
= false;
3463 /* Get XML for the domain. Restore needs only the inactive xml,
3464 * including secure. We should get the same result whether xmlin
3465 * is NULL or whether it was the live xml of the domain moments
3468 virDomainDefPtr def
= NULL
;
3470 if (!(def
= virDomainDefParseString(xmlin
, caps
, driver
->xmlopt
, NULL
,
3471 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
3472 VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
))) {
3475 if (!qemuDomainCheckABIStability(driver
, vm
, def
)) {
3476 virDomainDefFree(def
);
3479 xml
= qemuDomainDefFormatLive(driver
, def
, NULL
, true, true);
3481 xml
= qemuDomainDefFormatLive(driver
, vm
->def
, priv
->origCPU
, true, true);
3484 virReportError(VIR_ERR_OPERATION_FAILED
,
3485 "%s", _("failed to get domain xml"));
3489 if (!(cookie
= qemuDomainSaveCookieNew(vm
)))
3492 if (!(data
= virQEMUSaveDataNew(xml
, cookie
, was_running
, compressed
,
3497 ret
= qemuDomainSaveMemory(driver
, vm
, path
, data
, compressedpath
,
3498 flags
, QEMU_ASYNC_JOB_SAVE
);
3503 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_SAVED
,
3504 QEMU_ASYNC_JOB_SAVE
, 0);
3505 virDomainAuditStop(vm
, "saved");
3506 event
= virDomainEventLifecycleNewFromObj(vm
, VIR_DOMAIN_EVENT_STOPPED
,
3507 VIR_DOMAIN_EVENT_STOPPED_SAVED
);
3510 if (was_running
&& virDomainObjIsActive(vm
)) {
3511 virErrorPtr save_err
= virSaveLastError();
3512 if (qemuProcessStartCPUs(driver
, vm
,
3513 VIR_DOMAIN_RUNNING_SAVE_CANCELED
,
3514 QEMU_ASYNC_JOB_SAVE
) < 0) {
3515 VIR_WARN("Unable to resume guest CPUs after save failure");
3516 virObjectEventStateQueue(driver
->domainEventState
,
3517 virDomainEventLifecycleNewFromObj(vm
,
3518 VIR_DOMAIN_EVENT_SUSPENDED
,
3519 VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR
));
3521 virSetError(save_err
);
3522 virFreeError(save_err
);
3525 qemuDomainObjEndAsyncJob(driver
, vm
);
3527 qemuDomainRemoveInactiveJob(driver
, vm
);
3530 virObjectUnref(cookie
);
3532 virQEMUSaveDataFree(data
);
3533 virObjectEventStateQueue(driver
->domainEventState
, event
);
3534 virObjectUnref(caps
);
3539 /* qemuGetCompressionProgram:
3540 * @imageFormat: String representation from qemu.conf for the compression
3541 * image format being used (dump, save, or snapshot).
3542 * @compresspath: Pointer to a character string to store the fully qualified
3543 * path from virFindFileInPath.
3544 * @styleFormat: String representing the style of format (dump, save, snapshot)
3545 * @use_raw_on_fail: Boolean indicating how to handle the error path. For
3546 * callers that are OK with invalid data or inability to
3547 * find the compression program, just return a raw format
3548 * and let the path remain as NULL.
3551 * virQEMUSaveFormat - Integer representation of the compression
3552 * program to be used for particular style
3553 * (e.g. dump, save, or snapshot).
3554 * QEMU_SAVE_FORMAT_RAW - If there is no qemu.conf imageFormat value or
3555 * no there was an error, then just return RAW
3558 static int ATTRIBUTE_NONNULL(2)
3559 qemuGetCompressionProgram(const char *imageFormat
,
3560 char **compresspath
,
3561 const char *styleFormat
,
3562 bool use_raw_on_fail
)
3566 *compresspath
= NULL
;
3569 return QEMU_SAVE_FORMAT_RAW
;
3571 if ((ret
= qemuSaveCompressionTypeFromString(imageFormat
)) < 0)
3574 if (ret
== QEMU_SAVE_FORMAT_RAW
)
3575 return QEMU_SAVE_FORMAT_RAW
;
3577 if (!(*compresspath
= virFindFileInPath(imageFormat
)))
3584 if (use_raw_on_fail
)
3585 VIR_WARN("Invalid %s image format specified in "
3586 "configuration file, using raw",
3589 virReportError(VIR_ERR_OPERATION_FAILED
,
3590 _("Invalid %s image format specified "
3591 "in configuration file"),
3594 if (use_raw_on_fail
)
3595 VIR_WARN("Compression program for %s image format in "
3596 "configuration file isn't available, using raw",
3599 virReportError(VIR_ERR_OPERATION_FAILED
,
3600 _("Compression program for %s image format "
3601 "in configuration file isn't available"),
3605 /* Use "raw" as the format if the specified format is not valid,
3606 * or the compress program is not available. */
3607 if (use_raw_on_fail
)
3608 return QEMU_SAVE_FORMAT_RAW
;
3615 qemuDomainSaveFlags(virDomainPtr dom
, const char *path
, const char *dxml
,
3618 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
3620 char *compressedpath
= NULL
;
3622 virDomainObjPtr vm
= NULL
;
3623 virQEMUDriverConfigPtr cfg
= NULL
;
3625 virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE
|
3626 VIR_DOMAIN_SAVE_RUNNING
|
3627 VIR_DOMAIN_SAVE_PAUSED
, -1);
3629 cfg
= virQEMUDriverGetConfig(driver
);
3630 if ((compressed
= qemuGetCompressionProgram(cfg
->saveImageFormat
,
3632 "save", false)) < 0)
3635 if (!(vm
= qemuDomObjFromDomain(dom
)))
3638 if (virDomainSaveFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
3641 if (virDomainObjCheckActive(vm
) < 0)
3644 ret
= qemuDomainSaveInternal(driver
, vm
, path
, compressed
,
3645 compressedpath
, dxml
, flags
);
3648 virDomainObjEndAPI(&vm
);
3649 VIR_FREE(compressedpath
);
3650 virObjectUnref(cfg
);
3655 qemuDomainSave(virDomainPtr dom
, const char *path
)
3657 return qemuDomainSaveFlags(dom
, path
, NULL
, 0);
3661 qemuDomainManagedSavePath(virQEMUDriverPtr driver
, virDomainObjPtr vm
)
3664 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
3666 if (virAsprintf(&ret
, "%s/%s.save", cfg
->saveDir
, vm
->def
->name
) < 0) {
3667 virObjectUnref(cfg
);
3671 virObjectUnref(cfg
);
3676 qemuDomainManagedSave(virDomainPtr dom
, unsigned int flags
)
3678 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
3679 virQEMUDriverConfigPtr cfg
= NULL
;
3681 char *compressedpath
= NULL
;
3686 virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE
|
3687 VIR_DOMAIN_SAVE_RUNNING
|
3688 VIR_DOMAIN_SAVE_PAUSED
, -1);
3690 if (!(vm
= qemuDomObjFromDomain(dom
)))
3693 if (virDomainManagedSaveEnsureACL(dom
->conn
, vm
->def
) < 0)
3696 if (virDomainObjCheckActive(vm
) < 0)
3699 if (!vm
->persistent
) {
3700 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
3701 _("cannot do managed save for transient domain"));
3705 cfg
= virQEMUDriverGetConfig(driver
);
3706 if ((compressed
= qemuGetCompressionProgram(cfg
->saveImageFormat
,
3708 "save", false)) < 0)
3711 if (!(name
= qemuDomainManagedSavePath(driver
, vm
)))
3714 VIR_INFO("Saving state of domain '%s' to '%s'", vm
->def
->name
, name
);
3716 ret
= qemuDomainSaveInternal(driver
, vm
, name
, compressed
,
3717 compressedpath
, NULL
, flags
);
3719 vm
->hasManagedSave
= true;
3722 virDomainObjEndAPI(&vm
);
3724 VIR_FREE(compressedpath
);
3725 virObjectUnref(cfg
);
3731 qemuDomainManagedSaveLoad(virDomainObjPtr vm
,
3734 virQEMUDriverPtr driver
= opaque
;
3740 if (!(name
= qemuDomainManagedSavePath(driver
, vm
)))
3743 vm
->hasManagedSave
= virFileExists(name
);
3747 virObjectUnlock(vm
);
3754 qemuDomainHasManagedSaveImage(virDomainPtr dom
, unsigned int flags
)
3756 virDomainObjPtr vm
= NULL
;
3759 virCheckFlags(0, -1);
3761 if (!(vm
= qemuDomObjFromDomain(dom
)))
3764 if (virDomainHasManagedSaveImageEnsureACL(dom
->conn
, vm
->def
) < 0)
3767 ret
= vm
->hasManagedSave
;
3770 virDomainObjEndAPI(&vm
);
3775 qemuDomainManagedSaveRemove(virDomainPtr dom
, unsigned int flags
)
3777 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
3782 virCheckFlags(0, -1);
3784 if (!(vm
= qemuDomObjFromDomain(dom
)))
3787 if (virDomainManagedSaveRemoveEnsureACL(dom
->conn
, vm
->def
) < 0)
3790 if (!(name
= qemuDomainManagedSavePath(driver
, vm
)))
3793 if (unlink(name
) < 0) {
3794 virReportSystemError(errno
,
3795 _("Failed to remove managed save file '%s'"),
3800 vm
->hasManagedSave
= false;
3805 virDomainObjEndAPI(&vm
);
3811 * qemuDumpWaitForCompletion:
3812 * @vm: domain object
3814 * If the query dump capability exists, then it's possible to start a
3815 * guest memory dump operation using a thread via a 'detach' qualifier
3816 * to the dump guest memory command. This allows the async check if the
3819 * Returns 0 on success, -1 on failure
3822 qemuDumpWaitForCompletion(virDomainObjPtr vm
)
3824 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
3827 VIR_DEBUG("Waiting for dump completion");
3828 while (!priv
->job
.dumpCompleted
&& !priv
->job
.abortJob
) {
3829 if (virDomainObjWait(vm
) < 0)
3833 if (priv
->job
.current
->stats
.dump
.status
== QEMU_MONITOR_DUMP_STATUS_FAILED
) {
3834 if (priv
->job
.error
)
3835 virReportError(VIR_ERR_OPERATION_FAILED
,
3836 _("memory-only dump failed: %s"),
3839 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
3840 _("memory-only dump failed for unknown reason"));
3844 qemuDomainJobInfoUpdateTime(priv
->job
.current
);
3854 qemuDumpToFd(virQEMUDriverPtr driver
,
3857 qemuDomainAsyncJob asyncJob
,
3858 const char *dumpformat
)
3860 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
3861 bool detach
= false;
3864 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DUMP_GUEST_MEMORY
)) {
3865 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
3866 _("dump-guest-memory is not supported"));
3870 detach
= virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DUMP_COMPLETED
);
3872 if (qemuSecuritySetImageFDLabel(driver
->securityManager
, vm
->def
, fd
) < 0)
3876 priv
->job
.current
->statsType
= QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP
;
3878 VIR_FREE(priv
->job
.current
);
3880 if (qemuDomainObjEnterMonitorAsync(driver
, vm
, asyncJob
) < 0)
3884 ret
= qemuMonitorGetDumpGuestMemoryCapability(priv
->mon
, dumpformat
);
3887 virReportError(VIR_ERR_INVALID_ARG
,
3888 _("unsupported dumpformat '%s' "
3889 "for this QEMU binary"),
3892 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
3897 ret
= qemuMonitorDumpToFd(priv
->mon
, fd
, dumpformat
, detach
);
3899 if ((qemuDomainObjExitMonitor(driver
, vm
) < 0) || ret
< 0)
3903 ret
= qemuDumpWaitForCompletion(vm
);
3911 doCoreDump(virQEMUDriverPtr driver
,
3914 unsigned int dump_flags
,
3915 unsigned int dumpformat
)
3919 virFileWrapperFdPtr wrapperFd
= NULL
;
3921 unsigned int flags
= VIR_FILE_WRAPPER_NON_BLOCKING
;
3922 const char *memory_dump_format
= NULL
;
3923 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
3924 char *compressedpath
= NULL
;
3926 /* We reuse "save" flag for "dump" here. Then, we can support the same
3927 * format in "save" and "dump". This path doesn't need the compression
3928 * program to exist and can ignore the return value - it only cares to
3929 * get the compressedpath */
3930 ignore_value(qemuGetCompressionProgram(cfg
->dumpImageFormat
,
3934 /* Create an empty file with appropriate ownership. */
3935 if (dump_flags
& VIR_DUMP_BYPASS_CACHE
) {
3936 flags
|= VIR_FILE_WRAPPER_BYPASS_CACHE
;
3937 directFlag
= virFileDirectFdFlag();
3938 if (directFlag
< 0) {
3939 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
3940 _("bypass cache unsupported by this system"));
3944 /* Core dumps usually imply last-ditch analysis efforts are
3945 * desired, so we intentionally do not unlink even if a file was
3947 if ((fd
= qemuOpenFileAs(cfg
->user
, cfg
->group
, false, path
,
3948 O_CREAT
| O_TRUNC
| O_WRONLY
| directFlag
,
3952 if (!(wrapperFd
= virFileWrapperFdNew(&fd
, path
, flags
)))
3955 if (dump_flags
& VIR_DUMP_MEMORY_ONLY
) {
3956 if (!(memory_dump_format
= qemuDumpFormatTypeToString(dumpformat
))) {
3957 virReportError(VIR_ERR_INVALID_ARG
,
3958 _("unknown dumpformat '%d'"), dumpformat
);
3962 /* qemu dumps in "elf" without dumpformat set */
3963 if (STREQ(memory_dump_format
, "elf"))
3964 memory_dump_format
= NULL
;
3966 ret
= qemuDumpToFd(driver
, vm
, fd
, QEMU_ASYNC_JOB_DUMP
,
3967 memory_dump_format
);
3969 if (dumpformat
!= VIR_DOMAIN_CORE_DUMP_FORMAT_RAW
) {
3970 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
3971 _("kdump-compressed format is only supported with "
3972 "memory-only dump"));
3976 if (!qemuMigrationSrcIsAllowed(driver
, vm
, false, 0))
3979 ret
= qemuMigrationSrcToFile(driver
, vm
, fd
, compressedpath
,
3980 QEMU_ASYNC_JOB_DUMP
);
3986 if (VIR_CLOSE(fd
) < 0) {
3987 virReportSystemError(errno
,
3988 _("unable to close file %s"),
3992 if (qemuFileWrapperFDClose(vm
, wrapperFd
) < 0)
3998 VIR_FORCE_CLOSE(fd
);
3999 if (qemuFileWrapperFDClose(vm
, wrapperFd
) < 0)
4001 virFileWrapperFdFree(wrapperFd
);
4004 VIR_FREE(compressedpath
);
4005 virObjectUnref(cfg
);
4011 qemuDomainCoreDumpWithFormat(virDomainPtr dom
,
4013 unsigned int dumpformat
,
4016 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
4018 qemuDomainObjPrivatePtr priv
= NULL
;
4019 bool resume
= false, paused
= false;
4021 virObjectEventPtr event
= NULL
;
4023 virCheckFlags(VIR_DUMP_LIVE
| VIR_DUMP_CRASH
|
4024 VIR_DUMP_BYPASS_CACHE
| VIR_DUMP_RESET
|
4025 VIR_DUMP_MEMORY_ONLY
, -1);
4027 if (!(vm
= qemuDomObjFromDomain(dom
)))
4030 if (virDomainCoreDumpWithFormatEnsureACL(dom
->conn
, vm
->def
) < 0)
4033 if (qemuDomainObjBeginAsyncJob(driver
, vm
,
4034 QEMU_ASYNC_JOB_DUMP
,
4035 VIR_DOMAIN_JOB_OPERATION_DUMP
,
4039 if (virDomainObjCheckActive(vm
) < 0)
4042 priv
= vm
->privateData
;
4043 priv
->job
.current
->statsType
= QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP
;
4045 /* Migrate will always stop the VM, so the resume condition is
4046 independent of whether the stop command is issued. */
4047 resume
= virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
;
4049 /* Pause domain for non-live dump */
4050 if (!(flags
& VIR_DUMP_LIVE
) &&
4051 virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
) {
4052 if (qemuProcessStopCPUs(driver
, vm
, VIR_DOMAIN_PAUSED_DUMP
,
4053 QEMU_ASYNC_JOB_DUMP
) < 0)
4057 if (!virDomainObjIsActive(vm
)) {
4058 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
4059 _("guest unexpectedly quit"));
4064 if ((ret
= doCoreDump(driver
, vm
, path
, flags
, dumpformat
)) < 0)
4070 if ((ret
== 0) && (flags
& VIR_DUMP_CRASH
)) {
4071 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_CRASHED
,
4072 QEMU_ASYNC_JOB_DUMP
, 0);
4073 virDomainAuditStop(vm
, "crashed");
4074 event
= virDomainEventLifecycleNewFromObj(vm
,
4075 VIR_DOMAIN_EVENT_STOPPED
,
4076 VIR_DOMAIN_EVENT_STOPPED_CRASHED
);
4077 } else if (((resume
&& paused
) || (flags
& VIR_DUMP_RESET
)) &&
4078 virDomainObjIsActive(vm
)) {
4079 if ((ret
== 0) && (flags
& VIR_DUMP_RESET
)) {
4080 qemuDomainObjEnterMonitor(driver
, vm
);
4081 ret
= qemuMonitorSystemReset(priv
->mon
);
4082 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
4086 if (resume
&& virDomainObjIsActive(vm
)) {
4087 if (qemuProcessStartCPUs(driver
, vm
,
4088 VIR_DOMAIN_RUNNING_UNPAUSED
,
4089 QEMU_ASYNC_JOB_DUMP
) < 0) {
4090 event
= virDomainEventLifecycleNewFromObj(vm
,
4091 VIR_DOMAIN_EVENT_SUSPENDED
,
4092 VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR
);
4093 if (virGetLastErrorCode() == VIR_ERR_OK
)
4094 virReportError(VIR_ERR_OPERATION_FAILED
,
4095 "%s", _("resuming after dump failed"));
4100 qemuDomainObjEndAsyncJob(driver
, vm
);
4101 if (ret
== 0 && flags
& VIR_DUMP_CRASH
)
4102 qemuDomainRemoveInactiveJob(driver
, vm
);
4105 virDomainObjEndAPI(&vm
);
4106 virObjectEventStateQueue(driver
->domainEventState
, event
);
4112 qemuDomainCoreDump(virDomainPtr dom
,
4116 return qemuDomainCoreDumpWithFormat(dom
, path
,
4117 VIR_DOMAIN_CORE_DUMP_FORMAT_RAW
,
4123 qemuDomainScreenshot(virDomainPtr dom
,
4125 unsigned int screen
,
4128 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
4130 qemuDomainObjPrivatePtr priv
;
4134 const char *videoAlias
= NULL
;
4136 bool unlink_tmp
= false;
4137 virQEMUDriverConfigPtr cfg
= NULL
;
4139 virCheckFlags(0, NULL
);
4141 if (!(vm
= qemuDomObjFromDomain(dom
)))
4144 priv
= vm
->privateData
;
4145 cfg
= virQEMUDriverGetConfig(driver
);
4147 if (virDomainScreenshotEnsureACL(dom
->conn
, vm
->def
) < 0)
4150 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
4153 if (virDomainObjCheckActive(vm
) < 0)
4156 if (!vm
->def
->nvideos
) {
4157 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
4158 _("no screens to take screenshot from"));
4163 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_SCREENDUMP_DEVICE
)) {
4164 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
4165 _("qemu does not allow specifying screen ID"));
4169 for (i
= 0; i
< vm
->def
->nvideos
; i
++) {
4170 const virDomainVideoDef
*video
= vm
->def
->videos
[i
];
4172 if (screen
< video
->heads
) {
4173 videoAlias
= video
->info
.alias
;
4177 screen
-= video
->heads
;
4180 if (i
== vm
->def
->nvideos
) {
4181 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
4182 _("no such screen ID"));
4187 if (virAsprintf(&tmp
, "%s/qemu.screendump.XXXXXX", cfg
->cacheDir
) < 0)
4190 if ((tmp_fd
= mkostemp(tmp
, O_CLOEXEC
)) == -1) {
4191 virReportSystemError(errno
, _("mkostemp(\"%s\") failed"), tmp
);
4196 qemuSecuritySetSavedStateLabel(driver
, vm
, tmp
);
4198 qemuDomainObjEnterMonitor(driver
, vm
);
4199 if (qemuMonitorScreendump(priv
->mon
, videoAlias
, screen
, tmp
) < 0) {
4200 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
4203 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
4206 if (VIR_CLOSE(tmp_fd
) < 0) {
4207 virReportSystemError(errno
, _("unable to close %s"), tmp
);
4211 if (virFDStreamOpenFile(st
, tmp
, 0, 0, O_RDONLY
) < 0) {
4212 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
4213 _("unable to open stream"));
4217 ignore_value(VIR_STRDUP(ret
, "image/x-portable-pixmap"));
4220 VIR_FORCE_CLOSE(tmp_fd
);
4225 qemuDomainObjEndJob(driver
, vm
);
4228 virDomainObjEndAPI(&vm
);
4229 virObjectUnref(cfg
);
4234 getAutoDumpPath(virQEMUDriverPtr driver
,
4237 char *dumpfile
= NULL
;
4238 char *domname
= virDomainDefGetShortName(vm
->def
);
4240 struct tm time_info
;
4241 time_t curtime
= time(NULL
);
4242 virQEMUDriverConfigPtr cfg
= NULL
;
4247 cfg
= virQEMUDriverGetConfig(driver
);
4249 localtime_r(&curtime
, &time_info
);
4250 strftime(timestr
, sizeof(timestr
), "%Y-%m-%d-%H:%M:%S", &time_info
);
4252 ignore_value(virAsprintf(&dumpfile
, "%s/%s-%s",
4257 virObjectUnref(cfg
);
4263 processWatchdogEvent(virQEMUDriverPtr driver
,
4268 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4269 char *dumpfile
= getAutoDumpPath(driver
, vm
);
4270 unsigned int flags
= VIR_DUMP_MEMORY_ONLY
;
4276 case VIR_DOMAIN_WATCHDOG_ACTION_DUMP
:
4277 if (qemuDomainObjBeginAsyncJob(driver
, vm
,
4278 QEMU_ASYNC_JOB_DUMP
,
4279 VIR_DOMAIN_JOB_OPERATION_DUMP
,
4284 if (virDomainObjCheckActive(vm
) < 0)
4287 flags
|= cfg
->autoDumpBypassCache
? VIR_DUMP_BYPASS_CACHE
: 0;
4288 if ((ret
= doCoreDump(driver
, vm
, dumpfile
, flags
,
4289 VIR_DOMAIN_CORE_DUMP_FORMAT_RAW
)) < 0)
4290 virReportError(VIR_ERR_OPERATION_FAILED
,
4291 "%s", _("Dump failed"));
4293 ret
= qemuProcessStartCPUs(driver
, vm
,
4294 VIR_DOMAIN_RUNNING_UNPAUSED
,
4295 QEMU_ASYNC_JOB_DUMP
);
4298 virReportError(VIR_ERR_OPERATION_FAILED
,
4299 "%s", _("Resuming after dump failed"));
4306 qemuDomainObjEndAsyncJob(driver
, vm
);
4309 virObjectUnref(cfg
);
4314 doCoreDumpToAutoDumpPath(virQEMUDriverPtr driver
,
4319 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4320 char *dumpfile
= getAutoDumpPath(driver
, vm
);
4325 flags
|= cfg
->autoDumpBypassCache
? VIR_DUMP_BYPASS_CACHE
: 0;
4326 if ((ret
= doCoreDump(driver
, vm
, dumpfile
, flags
,
4327 VIR_DOMAIN_CORE_DUMP_FORMAT_RAW
)) < 0)
4328 virReportError(VIR_ERR_OPERATION_FAILED
,
4329 "%s", _("Dump failed"));
4332 virObjectUnref(cfg
);
4338 qemuProcessGuestPanicEventInfo(virQEMUDriverPtr driver
,
4340 qemuMonitorEventPanicInfoPtr info
)
4342 char *msg
= qemuMonitorGuestPanicEventInfoFormatMsg(info
);
4343 char *timestamp
= virTimeStringNow();
4345 if (msg
&& timestamp
)
4346 qemuDomainLogAppendMessage(driver
, vm
, "%s: panic %s\n", timestamp
, msg
);
4348 VIR_FREE(timestamp
);
4354 processGuestPanicEvent(virQEMUDriverPtr driver
,
4357 qemuMonitorEventPanicInfoPtr info
)
4359 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
4360 virObjectEventPtr event
= NULL
;
4361 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4362 bool removeInactive
= false;
4363 unsigned long flags
= VIR_DUMP_MEMORY_ONLY
;
4365 if (qemuDomainObjBeginAsyncJob(driver
, vm
, QEMU_ASYNC_JOB_DUMP
,
4366 VIR_DOMAIN_JOB_OPERATION_DUMP
, flags
) < 0)
4369 if (!virDomainObjIsActive(vm
)) {
4370 VIR_DEBUG("Ignoring GUEST_PANICKED event from inactive domain %s",
4376 qemuProcessGuestPanicEventInfo(driver
, vm
, info
);
4378 virDomainObjSetState(vm
, VIR_DOMAIN_CRASHED
, VIR_DOMAIN_CRASHED_PANICKED
);
4380 event
= virDomainEventLifecycleNewFromObj(vm
,
4381 VIR_DOMAIN_EVENT_CRASHED
,
4382 VIR_DOMAIN_EVENT_CRASHED_PANICKED
);
4384 virObjectEventStateQueue(driver
->domainEventState
, event
);
4386 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0) {
4387 VIR_WARN("Unable to save status on vm %s after state change",
4391 if (virDomainLockProcessPause(driver
->lockManager
, vm
, &priv
->lockState
) < 0)
4392 VIR_WARN("Unable to release lease on %s", vm
->def
->name
);
4393 VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv
->lockState
));
4396 case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY
:
4397 if (doCoreDumpToAutoDumpPath(driver
, vm
, flags
) < 0)
4399 ATTRIBUTE_FALLTHROUGH
;
4401 case VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY
:
4402 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_CRASHED
,
4403 QEMU_ASYNC_JOB_DUMP
, 0);
4404 event
= virDomainEventLifecycleNewFromObj(vm
,
4405 VIR_DOMAIN_EVENT_STOPPED
,
4406 VIR_DOMAIN_EVENT_STOPPED_CRASHED
);
4408 virObjectEventStateQueue(driver
->domainEventState
, event
);
4409 virDomainAuditStop(vm
, "destroyed");
4410 removeInactive
= true;
4413 case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART
:
4414 if (doCoreDumpToAutoDumpPath(driver
, vm
, flags
) < 0)
4416 ATTRIBUTE_FALLTHROUGH
;
4418 case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART
:
4419 qemuDomainSetFakeReboot(driver
, vm
, true);
4420 qemuProcessShutdownOrReboot(driver
, vm
);
4423 case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE
:
4431 qemuDomainObjEndAsyncJob(driver
, vm
);
4433 qemuDomainRemoveInactiveJob(driver
, vm
);
4436 virObjectUnref(cfg
);
4441 processDeviceDeletedEvent(virQEMUDriverPtr driver
,
4443 const char *devAlias
)
4445 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4446 virDomainDeviceDef dev
;
4448 VIR_DEBUG("Removing device %s from domain %p %s",
4449 devAlias
, vm
, vm
->def
->name
);
4451 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
4454 if (!virDomainObjIsActive(vm
)) {
4455 VIR_DEBUG("Domain is not running");
4459 if (STRPREFIX(devAlias
, "vcpu")) {
4460 qemuDomainRemoveVcpuAlias(driver
, vm
, devAlias
);
4462 if (virDomainDefFindDevice(vm
->def
, devAlias
, &dev
, true) < 0)
4465 if (qemuDomainRemoveDevice(driver
, vm
, &dev
) < 0)
4469 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
4470 VIR_WARN("unable to save domain status after removing device %s",
4474 qemuDomainObjEndJob(driver
, vm
);
4477 virObjectUnref(cfg
);
4482 syncNicRxFilterMacAddr(char *ifname
, virNetDevRxFilterPtr guestFilter
,
4483 virNetDevRxFilterPtr hostFilter
)
4485 char newMacStr
[VIR_MAC_STRING_BUFLEN
];
4487 if (virMacAddrCmp(&hostFilter
->mac
, &guestFilter
->mac
)) {
4488 virMacAddrFormat(&guestFilter
->mac
, newMacStr
);
4490 /* set new MAC address from guest to associated macvtap device */
4491 if (virNetDevSetMAC(ifname
, &guestFilter
->mac
) < 0) {
4492 VIR_WARN("Couldn't set new MAC address %s to device %s "
4493 "while responding to NIC_RX_FILTER_CHANGED",
4496 VIR_DEBUG("device %s MAC address set to %s", ifname
, newMacStr
);
4503 syncNicRxFilterGuestMulticast(char *ifname
, virNetDevRxFilterPtr guestFilter
,
4504 virNetDevRxFilterPtr hostFilter
)
4508 char macstr
[VIR_MAC_STRING_BUFLEN
];
4510 for (i
= 0; i
< guestFilter
->multicast
.nTable
; i
++) {
4513 for (j
= 0; j
< hostFilter
->multicast
.nTable
; j
++) {
4514 if (virMacAddrCmp(&guestFilter
->multicast
.table
[i
],
4515 &hostFilter
->multicast
.table
[j
]) == 0) {
4522 virMacAddrFormat(&guestFilter
->multicast
.table
[i
], macstr
);
4524 if (virNetDevAddMulti(ifname
, &guestFilter
->multicast
.table
[i
]) < 0) {
4525 VIR_WARN("Couldn't add new multicast MAC address %s to "
4526 "device %s while responding to NIC_RX_FILTER_CHANGED",
4529 VIR_DEBUG("Added multicast MAC %s to %s interface",
4538 syncNicRxFilterHostMulticast(char *ifname
, virNetDevRxFilterPtr guestFilter
,
4539 virNetDevRxFilterPtr hostFilter
)
4543 char macstr
[VIR_MAC_STRING_BUFLEN
];
4545 for (i
= 0; i
< hostFilter
->multicast
.nTable
; i
++) {
4548 for (j
= 0; j
< guestFilter
->multicast
.nTable
; j
++) {
4549 if (virMacAddrCmp(&hostFilter
->multicast
.table
[i
],
4550 &guestFilter
->multicast
.table
[j
]) == 0) {
4557 virMacAddrFormat(&hostFilter
->multicast
.table
[i
], macstr
);
4559 if (virNetDevDelMulti(ifname
, &hostFilter
->multicast
.table
[i
]) < 0) {
4560 VIR_WARN("Couldn't delete multicast MAC address %s from "
4561 "device %s while responding to NIC_RX_FILTER_CHANGED",
4564 VIR_DEBUG("Deleted multicast MAC %s from %s interface",
4573 syncNicRxFilterPromiscMode(char *ifname
,
4574 virNetDevRxFilterPtr guestFilter
,
4575 virNetDevRxFilterPtr hostFilter
)
4578 bool setpromisc
= false;
4580 /* Set macvtap promisc mode to true if the guest has vlans defined */
4581 /* or synchronize the macvtap promisc mode if different from guest */
4582 if (guestFilter
->vlan
.nTable
> 0) {
4583 if (!hostFilter
->promiscuous
) {
4587 } else if (hostFilter
->promiscuous
!= guestFilter
->promiscuous
) {
4589 promisc
= guestFilter
->promiscuous
;
4593 if (virNetDevSetPromiscuous(ifname
, promisc
) < 0) {
4594 VIR_WARN("Couldn't set PROMISC flag to %s for device %s "
4595 "while responding to NIC_RX_FILTER_CHANGED",
4596 promisc
? "true" : "false", ifname
);
4603 syncNicRxFilterMultiMode(char *ifname
, virNetDevRxFilterPtr guestFilter
,
4604 virNetDevRxFilterPtr hostFilter
)
4606 if (hostFilter
->multicast
.mode
!= guestFilter
->multicast
.mode
||
4607 (guestFilter
->multicast
.overflow
&&
4608 guestFilter
->multicast
.mode
== VIR_NETDEV_RX_FILTER_MODE_NORMAL
)) {
4609 switch (guestFilter
->multicast
.mode
) {
4610 case VIR_NETDEV_RX_FILTER_MODE_ALL
:
4611 if (virNetDevSetRcvAllMulti(ifname
, true) < 0) {
4612 VIR_WARN("Couldn't set allmulticast flag to 'on' for "
4613 "device %s while responding to "
4614 "NIC_RX_FILTER_CHANGED", ifname
);
4618 case VIR_NETDEV_RX_FILTER_MODE_NORMAL
:
4619 if (guestFilter
->multicast
.overflow
&&
4620 (hostFilter
->multicast
.mode
== VIR_NETDEV_RX_FILTER_MODE_ALL
)) {
4624 if (virNetDevSetRcvMulti(ifname
, true) < 0) {
4625 VIR_WARN("Couldn't set multicast flag to 'on' for "
4626 "device %s while responding to "
4627 "NIC_RX_FILTER_CHANGED", ifname
);
4630 if (virNetDevSetRcvAllMulti(ifname
,
4631 guestFilter
->multicast
.overflow
) < 0) {
4632 VIR_WARN("Couldn't set allmulticast flag to '%s' for "
4633 "device %s while responding to "
4634 "NIC_RX_FILTER_CHANGED",
4635 virTristateSwitchTypeToString(virTristateSwitchFromBool(guestFilter
->multicast
.overflow
)),
4640 case VIR_NETDEV_RX_FILTER_MODE_NONE
:
4641 if (virNetDevSetRcvAllMulti(ifname
, false) < 0) {
4642 VIR_WARN("Couldn't set allmulticast flag to 'off' for "
4643 "device %s while responding to "
4644 "NIC_RX_FILTER_CHANGED", ifname
);
4647 if (virNetDevSetRcvMulti(ifname
, false) < 0) {
4648 VIR_WARN("Couldn't set multicast flag to 'off' for "
4649 "device %s while responding to "
4650 "NIC_RX_FILTER_CHANGED",
4660 syncNicRxFilterDeviceOptions(char *ifname
, virNetDevRxFilterPtr guestFilter
,
4661 virNetDevRxFilterPtr hostFilter
)
4663 syncNicRxFilterPromiscMode(ifname
, guestFilter
, hostFilter
);
4664 syncNicRxFilterMultiMode(ifname
, guestFilter
, hostFilter
);
4669 syncNicRxFilterMulticast(char *ifname
,
4670 virNetDevRxFilterPtr guestFilter
,
4671 virNetDevRxFilterPtr hostFilter
)
4673 syncNicRxFilterGuestMulticast(ifname
, guestFilter
, hostFilter
);
4674 syncNicRxFilterHostMulticast(ifname
, guestFilter
, hostFilter
);
4678 processNicRxFilterChangedEvent(virQEMUDriverPtr driver
,
4680 const char *devAlias
)
4682 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4683 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
4684 virDomainDeviceDef dev
;
4685 virDomainNetDefPtr def
;
4686 virNetDevRxFilterPtr guestFilter
= NULL
;
4687 virNetDevRxFilterPtr hostFilter
= NULL
;
4690 VIR_DEBUG("Received NIC_RX_FILTER_CHANGED event for device %s "
4691 "from domain %p %s",
4692 devAlias
, vm
, vm
->def
->name
);
4694 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
4697 if (!virDomainObjIsActive(vm
)) {
4698 VIR_DEBUG("Domain is not running");
4702 if (virDomainDefFindDevice(vm
->def
, devAlias
, &dev
, true) < 0) {
4703 VIR_WARN("NIC_RX_FILTER_CHANGED event received for "
4704 "non-existent device %s in domain %s",
4705 devAlias
, vm
->def
->name
);
4708 if (dev
.type
!= VIR_DOMAIN_DEVICE_NET
) {
4709 VIR_WARN("NIC_RX_FILTER_CHANGED event received for "
4710 "non-network device %s in domain %s",
4711 devAlias
, vm
->def
->name
);
4716 if (!virDomainNetGetActualTrustGuestRxFilters(def
)) {
4717 VIR_DEBUG("ignore NIC_RX_FILTER_CHANGED event for network "
4718 "device %s in domain %s",
4719 def
->info
.alias
, vm
->def
->name
);
4720 /* not sending "query-rx-filter" will also suppress any
4721 * further NIC_RX_FILTER_CHANGED events for this device
4726 /* handle the event - send query-rx-filter and respond to it. */
4728 VIR_DEBUG("process NIC_RX_FILTER_CHANGED event for network "
4729 "device %s in domain %s", def
->info
.alias
, vm
->def
->name
);
4731 qemuDomainObjEnterMonitor(driver
, vm
);
4732 ret
= qemuMonitorQueryRxFilter(priv
->mon
, devAlias
, &guestFilter
);
4733 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
4738 if (virDomainNetGetActualType(def
) == VIR_DOMAIN_NET_TYPE_DIRECT
) {
4740 if (virNetDevGetRxFilter(def
->ifname
, &hostFilter
)) {
4741 VIR_WARN("Couldn't get current RX filter for device %s "
4742 "while responding to NIC_RX_FILTER_CHANGED",
4747 /* For macvtap connections, set the following macvtap network device
4748 * attributes to match those of the guest network device:
4750 * - Multicast MAC address table
4756 syncNicRxFilterMacAddr(def
->ifname
, guestFilter
, hostFilter
);
4757 syncNicRxFilterMulticast(def
->ifname
, guestFilter
, hostFilter
);
4758 syncNicRxFilterDeviceOptions(def
->ifname
, guestFilter
, hostFilter
);
4761 if (virDomainNetGetActualType(def
) == VIR_DOMAIN_NET_TYPE_NETWORK
) {
4762 const char *brname
= virDomainNetGetActualBridgeName(def
);
4764 /* For libivrt network connections, set the following TUN/TAP network
4765 * device attributes to match those of the guest network device:
4766 * - QoS filters (which are based on MAC address)
4768 if (virDomainNetGetActualBandwidth(def
) &&
4769 def
->data
.network
.actual
&&
4770 virNetDevBandwidthUpdateFilter(brname
, &guestFilter
->mac
,
4771 def
->data
.network
.actual
->class_id
) < 0)
4776 qemuDomainObjEndJob(driver
, vm
);
4779 virNetDevRxFilterFree(hostFilter
);
4780 virNetDevRxFilterFree(guestFilter
);
4781 virObjectUnref(cfg
);
4786 processSerialChangedEvent(virQEMUDriverPtr driver
,
4788 const char *devAlias
,
4791 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
4792 virDomainChrDeviceState newstate
;
4793 virObjectEventPtr event
= NULL
;
4794 virDomainDeviceDef dev
;
4795 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
4798 newstate
= VIR_DOMAIN_CHR_DEVICE_STATE_CONNECTED
;
4800 newstate
= VIR_DOMAIN_CHR_DEVICE_STATE_DISCONNECTED
;
4802 VIR_DEBUG("Changing serial port state %s in domain %p %s",
4803 devAlias
, vm
, vm
->def
->name
);
4805 if (newstate
== VIR_DOMAIN_CHR_DEVICE_STATE_DISCONNECTED
&&
4806 virDomainObjIsActive(vm
) && priv
->agent
) {
4807 /* peek into the domain definition to find the channel */
4808 if (virDomainDefFindDevice(vm
->def
, devAlias
, &dev
, true) == 0 &&
4809 dev
.type
== VIR_DOMAIN_DEVICE_CHR
&&
4810 dev
.data
.chr
->deviceType
== VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL
&&
4811 dev
.data
.chr
->targetType
== VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO
&&
4812 STREQ_NULLABLE(dev
.data
.chr
->target
.name
, "org.qemu.guest_agent.0"))
4813 /* Close agent monitor early, so that other threads
4814 * waiting for the agent to reply can finish and our
4815 * job we acquire below can succeed. */
4816 qemuAgentNotifyClose(priv
->agent
);
4818 /* now discard the data, since it may possibly change once we unlock
4819 * while entering the job */
4820 memset(&dev
, 0, sizeof(dev
));
4823 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
4826 if (!virDomainObjIsActive(vm
)) {
4827 VIR_DEBUG("Domain is not running");
4831 if (virDomainDefFindDevice(vm
->def
, devAlias
, &dev
, true) < 0)
4834 /* we care only about certain devices */
4835 if (dev
.type
!= VIR_DOMAIN_DEVICE_CHR
||
4836 dev
.data
.chr
->deviceType
!= VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL
||
4837 dev
.data
.chr
->targetType
!= VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO
)
4840 dev
.data
.chr
->state
= newstate
;
4842 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
4843 VIR_WARN("unable to save status of domain %s after updating state of "
4844 "channel %s", vm
->def
->name
, devAlias
);
4846 if (STREQ_NULLABLE(dev
.data
.chr
->target
.name
, "org.qemu.guest_agent.0")) {
4847 if (newstate
== VIR_DOMAIN_CHR_DEVICE_STATE_CONNECTED
) {
4848 if (qemuConnectAgent(driver
, vm
) < 0)
4852 qemuAgentClose(priv
->agent
);
4855 priv
->agentError
= false;
4858 event
= virDomainEventAgentLifecycleNewFromObj(vm
, newstate
,
4859 VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL
);
4860 virObjectEventStateQueue(driver
->domainEventState
, event
);
4864 qemuDomainObjEndJob(driver
, vm
);
4867 virObjectUnref(cfg
);
4872 processBlockJobEvent(virQEMUDriverPtr driver
,
4874 const char *diskAlias
,
4878 virDomainDiskDefPtr disk
;
4879 qemuBlockJobDataPtr job
= NULL
;
4881 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
4884 if (!virDomainObjIsActive(vm
)) {
4885 VIR_DEBUG("Domain is not running");
4889 if (!(disk
= qemuProcessFindDomainDiskByAliasOrQOM(vm
, diskAlias
, NULL
))) {
4890 VIR_DEBUG("disk %s not found", diskAlias
);
4894 if (!(job
= qemuBlockJobDiskGetJob(disk
))) {
4895 if (!(job
= qemuBlockJobDiskNew(disk
, type
, diskAlias
)))
4897 qemuBlockJobStarted(job
);
4900 job
->newstate
= status
;
4902 qemuBlockJobUpdate(vm
, job
, QEMU_ASYNC_JOB_NONE
);
4905 qemuBlockJobStartupFinalize(job
);
4906 qemuDomainObjEndJob(driver
, vm
);
4911 processMonitorEOFEvent(virQEMUDriverPtr driver
,
4914 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
4915 int eventReason
= VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN
;
4916 int stopReason
= VIR_DOMAIN_SHUTOFF_SHUTDOWN
;
4917 const char *auditReason
= "shutdown";
4918 unsigned int stopFlags
= 0;
4919 virObjectEventPtr event
= NULL
;
4921 if (qemuProcessBeginStopJob(driver
, vm
, QEMU_JOB_DESTROY
, true) < 0)
4924 if (!virDomainObjIsActive(vm
)) {
4925 VIR_DEBUG("Domain %p '%s' is not active, ignoring EOF",
4930 if (priv
->monJSON
&&
4931 virDomainObjGetState(vm
, NULL
) != VIR_DOMAIN_SHUTDOWN
) {
4932 VIR_DEBUG("Monitor connection to '%s' closed without SHUTDOWN event; "
4933 "assuming the domain crashed", vm
->def
->name
);
4934 eventReason
= VIR_DOMAIN_EVENT_STOPPED_FAILED
;
4935 stopReason
= VIR_DOMAIN_SHUTOFF_CRASHED
;
4936 auditReason
= "failed";
4939 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_IN
) {
4940 stopFlags
|= VIR_QEMU_PROCESS_STOP_MIGRATED
;
4941 qemuMigrationDstErrorSave(driver
, vm
->def
->name
,
4942 qemuMonitorLastError(priv
->mon
));
4945 event
= virDomainEventLifecycleNewFromObj(vm
, VIR_DOMAIN_EVENT_STOPPED
,
4947 qemuProcessStop(driver
, vm
, stopReason
, QEMU_ASYNC_JOB_NONE
, stopFlags
);
4948 virDomainAuditStop(vm
, auditReason
);
4949 virObjectEventStateQueue(driver
->domainEventState
, event
);
4952 qemuDomainRemoveInactive(driver
, vm
);
4953 qemuDomainObjEndJob(driver
, vm
);
4958 processPRDisconnectEvent(virDomainObjPtr vm
)
4960 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
4962 if (!virDomainObjIsActive(vm
))
4965 if (!priv
->prDaemonRunning
&&
4966 virDomainDefHasManagedPR(vm
->def
))
4967 qemuProcessStartManagedPRDaemon(vm
);
4972 processRdmaGidStatusChangedEvent(virDomainObjPtr vm
,
4973 qemuMonitorRdmaGidStatusPtr info
)
4975 unsigned int prefix_len
;
4977 VIR_AUTOFREE(char *) addrStr
= NULL
;
4980 if (!virDomainObjIsActive(vm
))
4983 VIR_DEBUG("netdev=%s, gid_status=%d, subnet_prefix=0x%llx, interface_id=0x%llx",
4984 info
->netdev
, info
->gid_status
, info
->subnet_prefix
,
4985 info
->interface_id
);
4987 if (info
->subnet_prefix
) {
4988 uint32_t ipv6
[4] = {0};
4991 memcpy(&ipv6
[0], &info
->subnet_prefix
, sizeof(info
->subnet_prefix
));
4992 memcpy(&ipv6
[2], &info
->interface_id
, sizeof(info
->interface_id
));
4993 virSocketAddrSetIPv6AddrNetOrder(&addr
, ipv6
);
4996 virSocketAddrSetIPv4AddrNetOrder(&addr
, info
->interface_id
>> 32);
4999 if (!(addrStr
= virSocketAddrFormat(&addr
)))
5002 if (info
->gid_status
) {
5003 VIR_DEBUG("Adding %s to %s", addrStr
, info
->netdev
);
5004 rc
= virNetDevIPAddrAdd(info
->netdev
, &addr
, NULL
, prefix_len
);
5006 VIR_DEBUG("Removing %s from %s", addrStr
, info
->netdev
);
5007 rc
= virNetDevIPAddrDel(info
->netdev
, &addr
, prefix_len
);
5011 VIR_WARN("Fail to update address %s to %s", addrStr
, info
->netdev
);
5015 static void qemuProcessEventHandler(void *data
, void *opaque
)
5017 struct qemuProcessEvent
*processEvent
= data
;
5018 virDomainObjPtr vm
= processEvent
->vm
;
5019 virQEMUDriverPtr driver
= opaque
;
5021 VIR_DEBUG("vm=%p, event=%d", vm
, processEvent
->eventType
);
5025 switch (processEvent
->eventType
) {
5026 case QEMU_PROCESS_EVENT_WATCHDOG
:
5027 processWatchdogEvent(driver
, vm
, processEvent
->action
);
5029 case QEMU_PROCESS_EVENT_GUESTPANIC
:
5030 processGuestPanicEvent(driver
, vm
, processEvent
->action
,
5031 processEvent
->data
);
5033 case QEMU_PROCESS_EVENT_DEVICE_DELETED
:
5034 processDeviceDeletedEvent(driver
, vm
, processEvent
->data
);
5036 case QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED
:
5037 processNicRxFilterChangedEvent(driver
, vm
, processEvent
->data
);
5039 case QEMU_PROCESS_EVENT_SERIAL_CHANGED
:
5040 processSerialChangedEvent(driver
, vm
, processEvent
->data
,
5041 processEvent
->action
);
5043 case QEMU_PROCESS_EVENT_BLOCK_JOB
:
5044 processBlockJobEvent(driver
, vm
,
5046 processEvent
->action
,
5047 processEvent
->status
);
5049 case QEMU_PROCESS_EVENT_MONITOR_EOF
:
5050 processMonitorEOFEvent(driver
, vm
);
5052 case QEMU_PROCESS_EVENT_PR_DISCONNECT
:
5053 processPRDisconnectEvent(vm
);
5055 case QEMU_PROCESS_EVENT_RDMA_GID_STATUS_CHANGED
:
5056 processRdmaGidStatusChangedEvent(vm
, processEvent
->data
);
5058 case QEMU_PROCESS_EVENT_LAST
:
5062 virDomainObjEndAPI(&vm
);
5063 qemuProcessEventFree(processEvent
);
5068 qemuDomainSetVcpusAgent(virDomainObjPtr vm
,
5069 unsigned int nvcpus
)
5071 qemuAgentCPUInfoPtr cpuinfo
= NULL
;
5076 if (!qemuDomainAgentAvailable(vm
, true))
5079 if (nvcpus
> virDomainDefGetVcpus(vm
->def
)) {
5080 virReportError(VIR_ERR_INVALID_ARG
,
5081 _("requested vcpu count is greater than the count "
5082 "of enabled vcpus in the domain: %d > %d"),
5083 nvcpus
, virDomainDefGetVcpus(vm
->def
));
5087 agent
= qemuDomainObjEnterAgent(vm
);
5088 ncpuinfo
= qemuAgentGetVCPUs(agent
, &cpuinfo
);
5089 qemuDomainObjExitAgent(vm
, agent
);
5095 if (qemuAgentUpdateCPUInfo(nvcpus
, cpuinfo
, ncpuinfo
) < 0)
5098 if (!qemuDomainAgentAvailable(vm
, true))
5101 agent
= qemuDomainObjEnterAgent(vm
);
5102 ret
= qemuAgentSetVCPUs(agent
, cpuinfo
, ncpuinfo
);
5103 qemuDomainObjExitAgent(vm
, agent
);
5113 qemuDomainSetVcpusMax(virQEMUDriverPtr driver
,
5114 virDomainDefPtr def
,
5115 virDomainDefPtr persistentDef
,
5116 unsigned int nvcpus
)
5118 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
5119 unsigned int topologycpus
;
5123 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
5124 _("maximum vcpu count of a live domain can't be modified"));
5128 if (virDomainNumaGetCPUCountTotal(persistentDef
->numa
) > nvcpus
) {
5129 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5130 _("Number of CPUs in <numa> exceeds the desired "
5131 "maximum vcpu count"));
5135 if (virDomainDefGetVcpusTopology(persistentDef
, &topologycpus
) == 0 &&
5136 nvcpus
!= topologycpus
) {
5137 /* allow setting a valid vcpu count for the topology so an invalid
5138 * setting may be corrected via this API */
5139 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5140 _("CPU topology doesn't match the desired vcpu count"));
5144 /* ordering information may become invalid, thus clear it */
5145 virDomainDefVcpuOrderClear(persistentDef
);
5147 if (virDomainDefSetVcpusMax(persistentDef
, nvcpus
, driver
->xmlopt
) < 0)
5150 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
5156 virObjectUnref(cfg
);
5162 qemuDomainSetVcpusFlags(virDomainPtr dom
,
5163 unsigned int nvcpus
,
5166 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5167 virDomainObjPtr vm
= NULL
;
5168 virDomainDefPtr def
;
5169 virDomainDefPtr persistentDef
;
5170 bool hotpluggable
= !!(flags
& VIR_DOMAIN_VCPU_HOTPLUGGABLE
);
5171 bool useAgent
= !!(flags
& VIR_DOMAIN_VCPU_GUEST
);
5172 qemuDomainJob job
= QEMU_JOB_NONE
;
5173 qemuDomainAgentJob agentJob
= QEMU_AGENT_JOB_NONE
;
5176 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5177 VIR_DOMAIN_AFFECT_CONFIG
|
5178 VIR_DOMAIN_VCPU_MAXIMUM
|
5179 VIR_DOMAIN_VCPU_GUEST
|
5180 VIR_DOMAIN_VCPU_HOTPLUGGABLE
, -1);
5182 if (!(vm
= qemuDomObjFromDomain(dom
)))
5185 if (virDomainSetVcpusFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
5189 agentJob
= QEMU_AGENT_JOB_MODIFY
;
5191 job
= QEMU_JOB_MODIFY
;
5193 if (qemuDomainObjBeginJobWithAgent(driver
, vm
, job
, agentJob
) < 0)
5196 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
5200 ret
= qemuDomainSetVcpusAgent(vm
, nvcpus
);
5201 else if (flags
& VIR_DOMAIN_VCPU_MAXIMUM
)
5202 ret
= qemuDomainSetVcpusMax(driver
, def
, persistentDef
, nvcpus
);
5204 ret
= qemuDomainSetVcpusInternal(driver
, vm
, def
, persistentDef
,
5205 nvcpus
, hotpluggable
);
5209 qemuDomainObjEndAgentJob(vm
);
5211 qemuDomainObjEndJob(driver
, vm
);
5214 virDomainObjEndAPI(&vm
);
5220 qemuDomainSetVcpus(virDomainPtr dom
, unsigned int nvcpus
)
5222 return qemuDomainSetVcpusFlags(dom
, nvcpus
, VIR_DOMAIN_AFFECT_LIVE
);
5227 qemuDomainPinVcpuLive(virDomainObjPtr vm
,
5228 virDomainDefPtr def
,
5230 virQEMUDriverPtr driver
,
5231 virQEMUDriverConfigPtr cfg
,
5232 virBitmapPtr cpumap
)
5234 virBitmapPtr tmpmap
= NULL
;
5235 virDomainVcpuDefPtr vcpuinfo
;
5236 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
5237 virCgroupPtr cgroup_vcpu
= NULL
;
5239 virObjectEventPtr event
= NULL
;
5240 char paramField
[VIR_TYPED_PARAM_FIELD_LENGTH
] = "";
5241 virTypedParameterPtr eventParams
= NULL
;
5242 int eventNparams
= 0;
5243 int eventMaxparams
= 0;
5246 if (!qemuDomainHasVcpuPids(vm
)) {
5247 virReportError(VIR_ERR_OPERATION_INVALID
,
5248 "%s", _("cpu affinity is not supported"));
5252 if (!(vcpuinfo
= virDomainDefGetVcpu(def
, vcpu
))) {
5253 virReportError(VIR_ERR_INVALID_ARG
,
5254 _("vcpu %d is out of range of live cpu count %d"),
5255 vcpu
, virDomainDefGetVcpusMax(def
));
5259 if (!(tmpmap
= virBitmapNewCopy(cpumap
)))
5262 if (!(str
= virBitmapFormat(cpumap
)))
5265 if (vcpuinfo
->online
) {
5266 /* Configure the corresponding cpuset cgroup before set affinity. */
5267 if (virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPUSET
)) {
5268 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_VCPU
, vcpu
,
5269 false, &cgroup_vcpu
) < 0)
5271 if (qemuSetupCgroupCpusetCpus(cgroup_vcpu
, cpumap
) < 0)
5275 if (virProcessSetAffinity(qemuDomainGetVcpuPid(vm
, vcpu
), cpumap
) < 0)
5279 virBitmapFree(vcpuinfo
->cpumask
);
5280 vcpuinfo
->cpumask
= tmpmap
;
5283 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
5286 if (snprintf(paramField
, VIR_TYPED_PARAM_FIELD_LENGTH
,
5287 VIR_DOMAIN_TUNABLE_CPU_VCPUPIN
, vcpu
) < 0) {
5291 if (virTypedParamsAddString(&eventParams
, &eventNparams
,
5292 &eventMaxparams
, paramField
, str
) < 0)
5295 event
= virDomainEventTunableNewFromObj(vm
, eventParams
, eventNparams
);
5300 virBitmapFree(tmpmap
);
5301 virCgroupFree(&cgroup_vcpu
);
5303 virObjectEventStateQueue(driver
->domainEventState
, event
);
5309 qemuDomainPinVcpuFlags(virDomainPtr dom
,
5311 unsigned char *cpumap
,
5315 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5317 virDomainDefPtr def
;
5318 virDomainDefPtr persistentDef
;
5320 virBitmapPtr pcpumap
= NULL
;
5321 virDomainVcpuDefPtr vcpuinfo
= NULL
;
5322 virQEMUDriverConfigPtr cfg
= NULL
;
5324 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5325 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5327 cfg
= virQEMUDriverGetConfig(driver
);
5329 if (!(vm
= qemuDomObjFromDomain(dom
)))
5332 if (virDomainPinVcpuFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
5335 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
5338 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
5341 if (persistentDef
&&
5342 !(vcpuinfo
= virDomainDefGetVcpu(persistentDef
, vcpu
))) {
5343 virReportError(VIR_ERR_INVALID_ARG
,
5344 _("vcpu %d is out of range of persistent cpu count %d"),
5345 vcpu
, virDomainDefGetVcpus(persistentDef
));
5349 if (!(pcpumap
= virBitmapNewData(cpumap
, maplen
)))
5352 if (virBitmapIsAllClear(pcpumap
)) {
5353 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5354 _("Empty cpu list for pinning"));
5359 qemuDomainPinVcpuLive(vm
, def
, vcpu
, driver
, cfg
, pcpumap
) < 0)
5362 if (persistentDef
) {
5363 virBitmapFree(vcpuinfo
->cpumask
);
5364 vcpuinfo
->cpumask
= pcpumap
;
5367 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
);
5374 qemuDomainObjEndJob(driver
, vm
);
5377 virDomainObjEndAPI(&vm
);
5378 virBitmapFree(pcpumap
);
5379 virObjectUnref(cfg
);
5384 qemuDomainPinVcpu(virDomainPtr dom
,
5386 unsigned char *cpumap
,
5389 return qemuDomainPinVcpuFlags(dom
, vcpu
, cpumap
, maplen
,
5390 VIR_DOMAIN_AFFECT_LIVE
);
5394 qemuDomainGetVcpuPinInfo(virDomainPtr dom
,
5396 unsigned char *cpumaps
,
5400 virDomainObjPtr vm
= NULL
;
5401 virDomainDefPtr def
;
5404 virBitmapPtr autoCpuset
= NULL
;
5406 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5407 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5409 if (!(vm
= qemuDomObjFromDomain(dom
)))
5412 if (virDomainGetVcpuPinInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
5415 if (!(def
= virDomainObjGetOneDefState(vm
, flags
, &live
)))
5419 autoCpuset
= QEMU_DOMAIN_PRIVATE(vm
)->autoCpuset
;
5421 ret
= virDomainDefGetVcpuPinInfoHelper(def
, maplen
, ncpumaps
, cpumaps
,
5422 virHostCPUGetCount(), autoCpuset
);
5424 virDomainObjEndAPI(&vm
);
5429 qemuDomainPinEmulator(virDomainPtr dom
,
5430 unsigned char *cpumap
,
5434 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5436 virCgroupPtr cgroup_emulator
= NULL
;
5437 virDomainDefPtr def
;
5438 virDomainDefPtr persistentDef
;
5440 qemuDomainObjPrivatePtr priv
;
5441 virBitmapPtr pcpumap
= NULL
;
5442 virQEMUDriverConfigPtr cfg
= NULL
;
5443 virObjectEventPtr event
= NULL
;
5445 virTypedParameterPtr eventParams
= NULL
;
5446 int eventNparams
= 0;
5447 int eventMaxparams
= 0;
5449 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5450 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5452 cfg
= virQEMUDriverGetConfig(driver
);
5454 if (!(vm
= qemuDomObjFromDomain(dom
)))
5457 if (virDomainPinEmulatorEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
5460 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
5463 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
5466 priv
= vm
->privateData
;
5468 if (!(pcpumap
= virBitmapNewData(cpumap
, maplen
)))
5471 if (virBitmapIsAllClear(pcpumap
)) {
5472 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5473 _("Empty cpu list for pinning"));
5478 if (virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPUSET
)) {
5479 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_EMULATOR
,
5480 0, false, &cgroup_emulator
) < 0)
5483 if (qemuSetupCgroupCpusetCpus(cgroup_emulator
, pcpumap
) < 0) {
5484 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
5485 _("failed to set cpuset.cpus in cgroup"
5486 " for emulator threads"));
5491 if (virProcessSetAffinity(vm
->pid
, pcpumap
) < 0)
5494 virBitmapFree(def
->cputune
.emulatorpin
);
5495 def
->cputune
.emulatorpin
= NULL
;
5497 if (!(def
->cputune
.emulatorpin
= virBitmapNewCopy(pcpumap
)))
5500 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
5503 str
= virBitmapFormat(pcpumap
);
5504 if (virTypedParamsAddString(&eventParams
, &eventNparams
,
5506 VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN
,
5510 event
= virDomainEventTunableNewFromDom(dom
, eventParams
, eventNparams
);
5513 if (persistentDef
) {
5514 virBitmapFree(persistentDef
->cputune
.emulatorpin
);
5515 persistentDef
->cputune
.emulatorpin
= NULL
;
5517 if (!(persistentDef
->cputune
.emulatorpin
= virBitmapNewCopy(pcpumap
)))
5520 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
);
5527 qemuDomainObjEndJob(driver
, vm
);
5530 if (cgroup_emulator
)
5531 virCgroupFree(&cgroup_emulator
);
5532 virObjectEventStateQueue(driver
->domainEventState
, event
);
5534 virBitmapFree(pcpumap
);
5535 virDomainObjEndAPI(&vm
);
5536 virObjectUnref(cfg
);
5541 qemuDomainGetEmulatorPinInfo(virDomainPtr dom
,
5542 unsigned char *cpumaps
,
5546 virDomainObjPtr vm
= NULL
;
5547 virDomainDefPtr def
;
5551 virBitmapPtr cpumask
= NULL
;
5552 virBitmapPtr bitmap
= NULL
;
5553 virBitmapPtr autoCpuset
= NULL
;
5555 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5556 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5558 if (!(vm
= qemuDomObjFromDomain(dom
)))
5561 if (virDomainGetEmulatorPinInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
5564 if (!(def
= virDomainObjGetOneDefState(vm
, flags
, &live
)))
5567 if ((hostcpus
= virHostCPUGetCount()) < 0)
5571 autoCpuset
= QEMU_DOMAIN_PRIVATE(vm
)->autoCpuset
;
5573 if (def
->cputune
.emulatorpin
) {
5574 cpumask
= def
->cputune
.emulatorpin
;
5575 } else if (def
->cpumask
) {
5576 cpumask
= def
->cpumask
;
5577 } else if (vm
->def
->placement_mode
== VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO
&&
5579 cpumask
= autoCpuset
;
5581 if (!(bitmap
= virBitmapNew(hostcpus
)))
5583 virBitmapSetAll(bitmap
);
5587 virBitmapToDataBuf(cpumask
, cpumaps
, maplen
);
5592 virDomainObjEndAPI(&vm
);
5593 virBitmapFree(bitmap
);
5598 qemuDomainGetVcpus(virDomainPtr dom
,
5599 virVcpuInfoPtr info
,
5601 unsigned char *cpumaps
,
5607 if (!(vm
= qemuDomObjFromDomain(dom
)))
5610 if (virDomainGetVcpusEnsureACL(dom
->conn
, vm
->def
) < 0)
5613 if (!virDomainObjIsActive(vm
)) {
5614 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
5615 _("cannot retrieve vcpu information for inactive domain"));
5619 ret
= qemuDomainHelperGetVcpus(vm
, info
, NULL
, maxinfo
, cpumaps
, maplen
);
5622 virDomainObjEndAPI(&vm
);
5628 qemuDomainGetVcpusFlags(virDomainPtr dom
, unsigned int flags
)
5630 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5632 virDomainDefPtr def
;
5634 qemuAgentCPUInfoPtr cpuinfo
= NULL
;
5639 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5640 VIR_DOMAIN_AFFECT_CONFIG
|
5641 VIR_DOMAIN_VCPU_MAXIMUM
|
5642 VIR_DOMAIN_VCPU_GUEST
, -1);
5644 if (!(vm
= qemuDomObjFromDomain(dom
)))
5647 if (virDomainGetVcpusFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
5650 if (!(def
= virDomainObjGetOneDef(vm
, flags
)))
5653 if (flags
& VIR_DOMAIN_VCPU_GUEST
) {
5654 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
5657 if (!virDomainObjIsActive(vm
)) {
5658 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5659 _("vCPU count provided by the guest agent can only be "
5660 "requested for live domains"));
5664 if (!qemuDomainAgentAvailable(vm
, true))
5667 agent
= qemuDomainObjEnterAgent(vm
);
5668 ncpuinfo
= qemuAgentGetVCPUs(agent
, &cpuinfo
);
5669 qemuDomainObjExitAgent(vm
, agent
);
5672 qemuDomainObjEndAgentJob(vm
);
5677 if (flags
& VIR_DOMAIN_VCPU_MAXIMUM
) {
5682 /* count the online vcpus */
5684 for (i
= 0; i
< ncpuinfo
; i
++) {
5685 if (cpuinfo
[i
].online
)
5689 if (flags
& VIR_DOMAIN_VCPU_MAXIMUM
)
5690 ret
= virDomainDefGetVcpusMax(def
);
5692 ret
= virDomainDefGetVcpus(def
);
5697 virDomainObjEndAPI(&vm
);
5703 qemuDomainGetMaxVcpus(virDomainPtr dom
)
5705 return qemuDomainGetVcpusFlags(dom
, (VIR_DOMAIN_AFFECT_LIVE
|
5706 VIR_DOMAIN_VCPU_MAXIMUM
));
5711 qemuDomainGetIOThreadsMon(virQEMUDriverPtr driver
,
5713 qemuMonitorIOThreadInfoPtr
**iothreads
)
5715 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
5718 qemuDomainObjEnterMonitor(driver
, vm
);
5719 niothreads
= qemuMonitorGetIOThreads(priv
->mon
, iothreads
);
5720 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || niothreads
< 0)
5728 qemuDomainGetIOThreadsLive(virQEMUDriverPtr driver
,
5730 virDomainIOThreadInfoPtr
**info
)
5732 qemuDomainObjPrivatePtr priv
;
5733 qemuMonitorIOThreadInfoPtr
*iothreads
= NULL
;
5734 virDomainIOThreadInfoPtr
*info_ret
= NULL
;
5739 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
5742 if (!virDomainObjIsActive(vm
)) {
5743 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
5744 _("cannot list IOThreads for an inactive domain"));
5748 priv
= vm
->privateData
;
5749 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_OBJECT_IOTHREAD
)) {
5750 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
5751 _("IOThreads not supported with this binary"));
5755 if ((niothreads
= qemuDomainGetIOThreadsMon(driver
, vm
, &iothreads
)) < 0)
5759 if (niothreads
== 0) {
5764 if (VIR_ALLOC_N(info_ret
, niothreads
) < 0)
5767 for (i
= 0; i
< niothreads
; i
++) {
5768 virBitmapPtr map
= NULL
;
5770 if (VIR_ALLOC(info_ret
[i
]) < 0)
5772 info_ret
[i
]->iothread_id
= iothreads
[i
]->iothread_id
;
5774 if (!(map
= virProcessGetAffinity(iothreads
[i
]->thread_id
)))
5777 if (virBitmapToData(map
, &info_ret
[i
]->cpumap
,
5778 &info_ret
[i
]->cpumaplen
) < 0) {
5785 VIR_STEAL_PTR(*info
, info_ret
);
5789 qemuDomainObjEndJob(driver
, vm
);
5793 for (i
= 0; i
< niothreads
; i
++)
5794 virDomainIOThreadInfoFree(info_ret
[i
]);
5798 for (i
= 0; i
< niothreads
; i
++)
5799 VIR_FREE(iothreads
[i
]);
5800 VIR_FREE(iothreads
);
5807 qemuDomainGetIOThreadsConfig(virDomainDefPtr targetDef
,
5808 virDomainIOThreadInfoPtr
**info
)
5810 virDomainIOThreadInfoPtr
*info_ret
= NULL
;
5811 virBitmapPtr bitmap
= NULL
;
5812 virBitmapPtr cpumask
= NULL
;
5817 if (targetDef
->niothreadids
== 0)
5820 if ((hostcpus
= virHostCPUGetCount()) < 0)
5823 if (VIR_ALLOC_N(info_ret
, targetDef
->niothreadids
) < 0)
5826 for (i
= 0; i
< targetDef
->niothreadids
; i
++) {
5827 if (VIR_ALLOC(info_ret
[i
]) < 0)
5830 /* IOThread ID's are taken from the iothreadids list */
5831 info_ret
[i
]->iothread_id
= targetDef
->iothreadids
[i
]->iothread_id
;
5833 cpumask
= targetDef
->iothreadids
[i
]->cpumask
;
5835 if (targetDef
->cpumask
) {
5836 cpumask
= targetDef
->cpumask
;
5838 if (!(bitmap
= virBitmapNew(hostcpus
)))
5840 virBitmapSetAll(bitmap
);
5844 if (virBitmapToData(cpumask
, &info_ret
[i
]->cpumap
,
5845 &info_ret
[i
]->cpumaplen
) < 0)
5847 virBitmapFree(bitmap
);
5853 ret
= targetDef
->niothreadids
;
5857 for (i
= 0; i
< targetDef
->niothreadids
; i
++)
5858 virDomainIOThreadInfoFree(info_ret
[i
]);
5861 virBitmapFree(bitmap
);
5867 qemuDomainGetIOThreadInfo(virDomainPtr dom
,
5868 virDomainIOThreadInfoPtr
**info
,
5871 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5873 virDomainDefPtr targetDef
= NULL
;
5876 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5877 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5879 if (!(vm
= qemuDomObjFromDomain(dom
)))
5882 if (virDomainGetIOThreadInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
5885 if (virDomainObjGetDefs(vm
, flags
, NULL
, &targetDef
) < 0)
5889 ret
= qemuDomainGetIOThreadsLive(driver
, vm
, info
);
5891 ret
= qemuDomainGetIOThreadsConfig(targetDef
, info
);
5894 virDomainObjEndAPI(&vm
);
5899 qemuDomainPinIOThread(virDomainPtr dom
,
5900 unsigned int iothread_id
,
5901 unsigned char *cpumap
,
5906 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
5907 virQEMUDriverConfigPtr cfg
= NULL
;
5909 virDomainDefPtr def
;
5910 virDomainDefPtr persistentDef
;
5911 virBitmapPtr pcpumap
= NULL
;
5912 qemuDomainObjPrivatePtr priv
;
5913 virCgroupPtr cgroup_iothread
= NULL
;
5914 virObjectEventPtr event
= NULL
;
5915 char paramField
[VIR_TYPED_PARAM_FIELD_LENGTH
] = "";
5917 virTypedParameterPtr eventParams
= NULL
;
5918 int eventNparams
= 0;
5919 int eventMaxparams
= 0;
5921 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
5922 VIR_DOMAIN_AFFECT_CONFIG
, -1);
5924 cfg
= virQEMUDriverGetConfig(driver
);
5926 if (!(vm
= qemuDomObjFromDomain(dom
)))
5928 priv
= vm
->privateData
;
5930 if (virDomainPinIOThreadEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
5933 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
5936 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
5939 if (!(pcpumap
= virBitmapNewData(cpumap
, maplen
)))
5942 if (virBitmapIsAllClear(pcpumap
)) {
5943 virReportError(VIR_ERR_INVALID_ARG
, "%s",
5944 _("Empty iothread cpumap list for pinning"));
5949 virDomainIOThreadIDDefPtr iothrid
;
5950 virBitmapPtr cpumask
;
5952 if (!(iothrid
= virDomainIOThreadIDFind(def
, iothread_id
))) {
5953 virReportError(VIR_ERR_INVALID_ARG
,
5954 _("iothread %d not found"), iothread_id
);
5958 if (!(cpumask
= virBitmapNewData(cpumap
, maplen
)))
5961 virBitmapFree(iothrid
->cpumask
);
5962 iothrid
->cpumask
= cpumask
;
5963 iothrid
->autofill
= false;
5965 /* Configure the corresponding cpuset cgroup before set affinity. */
5966 if (virCgroupHasController(priv
->cgroup
,
5967 VIR_CGROUP_CONTROLLER_CPUSET
)) {
5968 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_IOTHREAD
,
5969 iothread_id
, false, &cgroup_iothread
) < 0)
5971 if (qemuSetupCgroupCpusetCpus(cgroup_iothread
, pcpumap
) < 0) {
5972 virReportError(VIR_ERR_OPERATION_INVALID
,
5973 _("failed to set cpuset.cpus in cgroup"
5974 " for iothread %d"), iothread_id
);
5979 if (virProcessSetAffinity(iothrid
->thread_id
, pcpumap
) < 0)
5982 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
5985 if (snprintf(paramField
, VIR_TYPED_PARAM_FIELD_LENGTH
,
5986 VIR_DOMAIN_TUNABLE_CPU_IOTHREADSPIN
, iothread_id
) < 0) {
5990 str
= virBitmapFormat(pcpumap
);
5991 if (virTypedParamsAddString(&eventParams
, &eventNparams
,
5992 &eventMaxparams
, paramField
, str
) < 0)
5995 event
= virDomainEventTunableNewFromDom(dom
, eventParams
, eventNparams
);
5998 if (persistentDef
) {
5999 virDomainIOThreadIDDefPtr iothrid
;
6000 virBitmapPtr cpumask
;
6002 if (!(iothrid
= virDomainIOThreadIDFind(persistentDef
, iothread_id
))) {
6003 virReportError(VIR_ERR_INVALID_ARG
,
6004 _("iothreadid %d not found"), iothread_id
);
6008 if (!(cpumask
= virBitmapNewData(cpumap
, maplen
)))
6011 virBitmapFree(iothrid
->cpumask
);
6012 iothrid
->cpumask
= cpumask
;
6013 iothrid
->autofill
= false;
6015 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
);
6022 qemuDomainObjEndJob(driver
, vm
);
6025 if (cgroup_iothread
)
6026 virCgroupFree(&cgroup_iothread
);
6027 virObjectEventStateQueue(driver
->domainEventState
, event
);
6029 virBitmapFree(pcpumap
);
6030 virDomainObjEndAPI(&vm
);
6031 virObjectUnref(cfg
);
6036 qemuDomainHotplugAddIOThread(virQEMUDriverPtr driver
,
6038 unsigned int iothread_id
)
6040 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
6044 unsigned int orig_niothreads
= vm
->def
->niothreadids
;
6045 unsigned int exp_niothreads
= vm
->def
->niothreadids
;
6046 int new_niothreads
= 0;
6047 qemuMonitorIOThreadInfoPtr
*new_iothreads
= NULL
;
6048 virDomainIOThreadIDDefPtr iothrid
;
6049 virJSONValuePtr props
= NULL
;
6051 if (virAsprintf(&alias
, "iothread%u", iothread_id
) < 0)
6054 if (qemuMonitorCreateObjectProps(&props
, "iothread", alias
, NULL
) < 0)
6057 qemuDomainObjEnterMonitor(driver
, vm
);
6059 if (qemuMonitorAddObject(priv
->mon
, &props
, NULL
) < 0)
6064 /* After hotplugging the IOThreads we need to re-detect the
6065 * IOThreads thread_id's, adjust the cgroups, thread affinity,
6066 * and add the thread_id to the vm->def->iothreadids list.
6068 if ((new_niothreads
= qemuMonitorGetIOThreads(priv
->mon
,
6069 &new_iothreads
)) < 0)
6072 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
6075 if (new_niothreads
!= exp_niothreads
) {
6076 virReportError(VIR_ERR_INTERNAL_ERROR
,
6077 _("got wrong number of IOThread ids from QEMU monitor. "
6078 "got %d, wanted %d"),
6079 new_niothreads
, exp_niothreads
);
6084 * If we've successfully added an IOThread, find out where we added it
6085 * in the QEMU IOThread list, so we can add it to our iothreadids list
6087 for (idx
= 0; idx
< new_niothreads
; idx
++) {
6088 if (new_iothreads
[idx
]->iothread_id
== iothread_id
)
6092 if (idx
== new_niothreads
) {
6093 virReportError(VIR_ERR_INTERNAL_ERROR
,
6094 _("cannot find new IOThread '%u' in QEMU monitor."),
6099 if (!(iothrid
= virDomainIOThreadIDAdd(vm
->def
, iothread_id
)))
6102 iothrid
->thread_id
= new_iothreads
[idx
]->thread_id
;
6104 if (qemuProcessSetupIOThread(vm
, iothrid
) < 0)
6110 if (new_iothreads
) {
6111 for (idx
= 0; idx
< new_niothreads
; idx
++)
6112 VIR_FREE(new_iothreads
[idx
]);
6113 VIR_FREE(new_iothreads
);
6115 virDomainAuditIOThread(vm
, orig_niothreads
, new_niothreads
,
6116 "update", ret
== 0);
6118 virJSONValueFree(props
);
6122 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
6128 qemuDomainHotplugModIOThread(virQEMUDriverPtr driver
,
6130 qemuMonitorIOThreadInfo iothread
)
6132 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
6135 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_IOTHREAD_POLLING
)) {
6136 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
6137 _("IOThreads polling is not supported for this QEMU"));
6141 qemuDomainObjEnterMonitor(driver
, vm
);
6143 rc
= qemuMonitorSetIOThread(priv
->mon
, &iothread
);
6145 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
6156 qemuDomainHotplugDelIOThread(virQEMUDriverPtr driver
,
6158 unsigned int iothread_id
)
6160 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
6165 unsigned int orig_niothreads
= vm
->def
->niothreadids
;
6166 unsigned int exp_niothreads
= vm
->def
->niothreadids
;
6167 int new_niothreads
= 0;
6168 qemuMonitorIOThreadInfoPtr
*new_iothreads
= NULL
;
6170 if (virAsprintf(&alias
, "iothread%u", iothread_id
) < 0)
6173 qemuDomainObjEnterMonitor(driver
, vm
);
6175 rc
= qemuMonitorDelObject(priv
->mon
, alias
);
6180 if ((new_niothreads
= qemuMonitorGetIOThreads(priv
->mon
,
6181 &new_iothreads
)) < 0)
6184 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
6187 if (new_niothreads
!= exp_niothreads
) {
6188 virReportError(VIR_ERR_INTERNAL_ERROR
,
6189 _("got wrong number of IOThread ids from QEMU monitor. "
6190 "got %d, wanted %d"),
6191 new_niothreads
, exp_niothreads
);
6195 virDomainIOThreadIDDel(vm
->def
, iothread_id
);
6197 if (virCgroupDelThread(priv
->cgroup
, VIR_CGROUP_THREAD_IOTHREAD
,
6204 if (new_iothreads
) {
6205 for (idx
= 0; idx
< new_niothreads
; idx
++)
6206 VIR_FREE(new_iothreads
[idx
]);
6207 VIR_FREE(new_iothreads
);
6209 virDomainAuditIOThread(vm
, orig_niothreads
, new_niothreads
,
6215 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
6221 qemuDomainAddIOThreadCheck(virDomainDefPtr def
,
6222 unsigned int iothread_id
)
6224 if (virDomainIOThreadIDFind(def
, iothread_id
)) {
6225 virReportError(VIR_ERR_INVALID_ARG
,
6226 _("an IOThread is already using iothread_id '%u'"),
6236 qemuDomainDelIOThreadCheck(virDomainDefPtr def
,
6237 unsigned int iothread_id
)
6241 if (!virDomainIOThreadIDFind(def
, iothread_id
)) {
6242 virReportError(VIR_ERR_INVALID_ARG
,
6243 _("cannot find IOThread '%u' in iothreadids list"),
6248 for (i
= 0; i
< def
->ndisks
; i
++) {
6249 if (def
->disks
[i
]->iothread
== iothread_id
) {
6250 virReportError(VIR_ERR_INVALID_ARG
,
6251 _("cannot remove IOThread %u since it "
6252 "is being used by disk '%s'"),
6253 iothread_id
, def
->disks
[i
]->dst
);
6258 for (i
= 0; i
< def
->ncontrollers
; i
++) {
6259 if (def
->controllers
[i
]->iothread
== iothread_id
) {
6260 virReportError(VIR_ERR_INVALID_ARG
,
6261 _("cannot remove IOThread '%u' since it "
6262 "is being used by controller"),
6273 * @params: Pointer to params list
6274 * @nparams: Number of params to be parsed
6275 * @iothread: Buffer to store the values
6277 * The following is a description of each value parsed:
6279 * - "poll-max-ns" for each IOThread is the maximum time in nanoseconds
6280 * to allow each polling interval to occur. A polling interval is a
6281 * period of time allowed for a thread to process data before it returns
6282 * the CPU quantum back to the host. A value set too small will not allow
6283 * the IOThread to run long enough on a CPU to process data. A value set
6284 * too high will consume too much CPU time per IOThread failing to allow
6285 * other threads running on the CPU to get time. A value of 0 (zero) will
6286 * disable the polling.
6288 * - "poll-grow" - factor to grow the current polling time when deemed
6289 * necessary. If a 0 (zero) value is provided, QEMU currently doubles
6290 * its polling interval unless the current value is greater than the
6293 * - "poll-shrink" - divisor to reduced the current polling time when deemed
6294 * necessary. If a 0 (zero) value is provided, QEMU resets the polling
6295 * interval to 0 (zero) allowing the poll-grow to manipulate the time.
6297 * QEMU keeps track of the polling time elapsed and may grow or shrink the
6298 * its polling interval based upon its heuristic algorithm. It is possible
6299 * that calculations determine that it has found a "sweet spot" and no
6300 * adjustments are made. The polling time value is not available.
6302 * Returns 0 on success, -1 on failure with error set.
6305 qemuDomainIOThreadParseParams(virTypedParameterPtr params
,
6307 qemuMonitorIOThreadInfoPtr iothread
)
6311 if (virTypedParamsValidate(params
, nparams
,
6312 VIR_DOMAIN_IOTHREAD_POLL_MAX_NS
,
6313 VIR_TYPED_PARAM_ULLONG
,
6314 VIR_DOMAIN_IOTHREAD_POLL_GROW
,
6315 VIR_TYPED_PARAM_UINT
,
6316 VIR_DOMAIN_IOTHREAD_POLL_SHRINK
,
6317 VIR_TYPED_PARAM_UINT
,
6321 if ((rc
= virTypedParamsGetULLong(params
, nparams
,
6322 VIR_DOMAIN_IOTHREAD_POLL_MAX_NS
,
6323 &iothread
->poll_max_ns
)) < 0)
6326 iothread
->set_poll_max_ns
= true;
6328 if ((rc
= virTypedParamsGetUInt(params
, nparams
,
6329 VIR_DOMAIN_IOTHREAD_POLL_GROW
,
6330 &iothread
->poll_grow
)) < 0)
6333 iothread
->set_poll_grow
= true;
6335 if ((rc
= virTypedParamsGetUInt(params
, nparams
,
6336 VIR_DOMAIN_IOTHREAD_POLL_SHRINK
,
6337 &iothread
->poll_shrink
)) < 0)
6340 iothread
->set_poll_shrink
= true;
6342 if (iothread
->set_poll_max_ns
&& iothread
->poll_max_ns
> INT_MAX
) {
6343 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
6344 _("poll-max-ns (%llu) must be less than or equal to %d"),
6345 iothread
->poll_max_ns
, INT_MAX
);
6349 if (iothread
->set_poll_grow
&& iothread
->poll_grow
> INT_MAX
) {
6350 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
6351 _("poll-grow (%u) must be less than or equal to %d"),
6352 iothread
->poll_grow
, INT_MAX
);
6356 if (iothread
->set_poll_shrink
&& iothread
->poll_shrink
> INT_MAX
) {
6357 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
6358 _("poll-shrink (%u) must be less than or equal to %d"),
6359 iothread
->poll_shrink
, INT_MAX
);
6368 VIR_DOMAIN_IOTHREAD_ACTION_ADD
,
6369 VIR_DOMAIN_IOTHREAD_ACTION_DEL
,
6370 VIR_DOMAIN_IOTHREAD_ACTION_MOD
,
6371 } virDomainIOThreadAction
;
6374 qemuDomainChgIOThread(virQEMUDriverPtr driver
,
6376 qemuMonitorIOThreadInfo iothread
,
6377 virDomainIOThreadAction action
,
6380 virQEMUDriverConfigPtr cfg
= NULL
;
6381 qemuDomainObjPrivatePtr priv
;
6382 virDomainDefPtr def
;
6383 virDomainDefPtr persistentDef
;
6386 cfg
= virQEMUDriverGetConfig(driver
);
6388 priv
= vm
->privateData
;
6390 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
6393 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
6397 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_OBJECT_IOTHREAD
)) {
6398 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
6399 _("IOThreads not supported with this binary"));
6404 case VIR_DOMAIN_IOTHREAD_ACTION_ADD
:
6405 if (qemuDomainAddIOThreadCheck(def
, iothread
.iothread_id
) < 0)
6408 if (qemuDomainHotplugAddIOThread(driver
, vm
, iothread
.iothread_id
) < 0)
6413 case VIR_DOMAIN_IOTHREAD_ACTION_DEL
:
6414 if (qemuDomainDelIOThreadCheck(def
, iothread
.iothread_id
) < 0)
6417 if (qemuDomainHotplugDelIOThread(driver
, vm
, iothread
.iothread_id
) < 0)
6422 case VIR_DOMAIN_IOTHREAD_ACTION_MOD
:
6423 if (!(virDomainIOThreadIDFind(def
, iothread
.iothread_id
))) {
6424 virReportError(VIR_ERR_INVALID_ARG
,
6425 _("cannot find IOThread '%u' in iothreadids"),
6426 iothread
.iothread_id
);
6430 if (qemuDomainHotplugModIOThread(driver
, vm
, iothread
) < 0)
6437 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
6441 if (persistentDef
) {
6443 case VIR_DOMAIN_IOTHREAD_ACTION_ADD
:
6444 if (qemuDomainAddIOThreadCheck(persistentDef
, iothread
.iothread_id
) < 0)
6447 if (!virDomainIOThreadIDAdd(persistentDef
, iothread
.iothread_id
))
6452 case VIR_DOMAIN_IOTHREAD_ACTION_DEL
:
6453 if (qemuDomainDelIOThreadCheck(persistentDef
, iothread
.iothread_id
) < 0)
6456 virDomainIOThreadIDDel(persistentDef
, iothread
.iothread_id
);
6460 case VIR_DOMAIN_IOTHREAD_ACTION_MOD
:
6461 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
6462 _("configuring persistent polling values is "
6469 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
6477 qemuDomainObjEndJob(driver
, vm
);
6480 virObjectUnref(cfg
);
6485 qemuDomainAddIOThread(virDomainPtr dom
,
6486 unsigned int iothread_id
,
6489 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
6490 virDomainObjPtr vm
= NULL
;
6491 qemuMonitorIOThreadInfo iothread
= {0};
6494 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
6495 VIR_DOMAIN_AFFECT_CONFIG
, -1);
6497 if (iothread_id
== 0) {
6498 virReportError(VIR_ERR_INVALID_ARG
, "%s",
6499 _("invalid value of 0 for iothread_id"));
6503 if (!(vm
= qemuDomObjFromDomain(dom
)))
6506 if (virDomainAddIOThreadEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
6509 iothread
.iothread_id
= iothread_id
;
6510 ret
= qemuDomainChgIOThread(driver
, vm
, iothread
,
6511 VIR_DOMAIN_IOTHREAD_ACTION_ADD
, flags
);
6514 virDomainObjEndAPI(&vm
);
6520 qemuDomainDelIOThread(virDomainPtr dom
,
6521 unsigned int iothread_id
,
6524 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
6525 virDomainObjPtr vm
= NULL
;
6526 qemuMonitorIOThreadInfo iothread
= {0};
6529 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
6530 VIR_DOMAIN_AFFECT_CONFIG
, -1);
6532 if (iothread_id
== 0) {
6533 virReportError(VIR_ERR_INVALID_ARG
, "%s",
6534 _("invalid value of 0 for iothread_id"));
6538 if (!(vm
= qemuDomObjFromDomain(dom
)))
6541 if (virDomainDelIOThreadEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
6544 iothread
.iothread_id
= iothread_id
;
6545 ret
= qemuDomainChgIOThread(driver
, vm
, iothread
,
6546 VIR_DOMAIN_IOTHREAD_ACTION_DEL
, flags
);
6549 virDomainObjEndAPI(&vm
);
6555 * @dom: Domain to set IOThread params
6556 * @iothread_id: IOThread 'id' that will be modified
6557 * @params: List of parameters to change
6558 * @nparams: Number of parameters in the list
6559 * @flags: Flags for the set (only supports live alteration)
6561 * Alter the specified @iothread_id with the values provided.
6563 * Returs 0 on success, -1 on failure
6566 qemuDomainSetIOThreadParams(virDomainPtr dom
,
6567 unsigned int iothread_id
,
6568 virTypedParameterPtr params
,
6572 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
6573 virDomainObjPtr vm
= NULL
;
6574 qemuMonitorIOThreadInfo iothread
= {0};
6577 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
, -1);
6579 if (iothread_id
== 0) {
6580 virReportError(VIR_ERR_INVALID_ARG
, "%s",
6581 _("invalid value of 0 for iothread_id"));
6585 iothread
.iothread_id
= iothread_id
;
6587 if (!(vm
= qemuDomObjFromDomain(dom
)))
6590 if (virDomainSetIOThreadParamsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
6593 if (qemuDomainIOThreadParseParams(params
, nparams
, &iothread
) < 0)
6596 ret
= qemuDomainChgIOThread(driver
, vm
, iothread
,
6597 VIR_DOMAIN_IOTHREAD_ACTION_MOD
, flags
);
6600 virDomainObjEndAPI(&vm
);
6605 static int qemuDomainGetSecurityLabel(virDomainPtr dom
, virSecurityLabelPtr seclabel
)
6607 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
6611 memset(seclabel
, 0, sizeof(*seclabel
));
6613 if (!(vm
= qemuDomObjFromDomain(dom
)))
6616 if (virDomainGetSecurityLabelEnsureACL(dom
->conn
, vm
->def
) < 0)
6619 if (!virDomainVirtTypeToString(vm
->def
->virtType
)) {
6620 virReportError(VIR_ERR_INTERNAL_ERROR
,
6621 _("unknown virt type in domain definition '%d'"),
6627 * Theoretically, the pid can be replaced during this operation and
6628 * return the label of a different process. If atomicity is needed,
6629 * further validation will be required.
6631 * Comment from Dan Berrange:
6633 * Well the PID as stored in the virDomainObjPtr can't be changed
6634 * because you've got a locked object. The OS level PID could have
6635 * exited, though and in extreme circumstances have cycled through all
6636 * PIDs back to ours. We could sanity check that our PID still exists
6637 * after reading the label, by checking that our FD connecting to the
6638 * QEMU monitor hasn't seen SIGHUP/ERR on poll().
6640 if (virDomainObjIsActive(vm
)) {
6641 if (qemuSecurityGetProcessLabel(driver
->securityManager
,
6642 vm
->def
, vm
->pid
, seclabel
) < 0)
6649 virDomainObjEndAPI(&vm
);
6653 static int qemuDomainGetSecurityLabelList(virDomainPtr dom
,
6654 virSecurityLabelPtr
* seclabels
)
6656 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
6661 if (!(vm
= qemuDomObjFromDomain(dom
)))
6664 if (virDomainGetSecurityLabelListEnsureACL(dom
->conn
, vm
->def
) < 0)
6667 if (!virDomainVirtTypeToString(vm
->def
->virtType
)) {
6668 virReportError(VIR_ERR_INTERNAL_ERROR
,
6669 _("unknown virt type in domain definition '%d'"),
6675 * Check the comment in qemuDomainGetSecurityLabel function.
6677 if (!virDomainObjIsActive(vm
)) {
6683 virSecurityManagerPtr
* mgrs
= qemuSecurityGetNested(driver
->securityManager
);
6687 /* Allocate seclabels array */
6688 for (i
= 0; mgrs
[i
]; i
++)
6691 if (VIR_ALLOC_N((*seclabels
), len
) < 0) {
6695 memset(*seclabels
, 0, sizeof(**seclabels
) * len
);
6697 /* Fill the array */
6698 for (i
= 0; i
< len
; i
++) {
6699 if (qemuSecurityGetProcessLabel(mgrs
[i
], vm
->def
, vm
->pid
,
6700 &(*seclabels
)[i
]) < 0) {
6702 VIR_FREE(*seclabels
);
6711 virDomainObjEndAPI(&vm
);
6716 static int qemuNodeGetSecurityModel(virConnectPtr conn
,
6717 virSecurityModelPtr secmodel
)
6719 virQEMUDriverPtr driver
= conn
->privateData
;
6722 virCapsPtr caps
= NULL
;
6724 memset(secmodel
, 0, sizeof(*secmodel
));
6726 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
6729 if (virNodeGetSecurityModelEnsureACL(conn
) < 0)
6732 /* We treat no driver as success, but simply return no data in *secmodel */
6733 if (caps
->host
.nsecModels
== 0 ||
6734 caps
->host
.secModels
[0].model
== NULL
)
6737 p
= caps
->host
.secModels
[0].model
;
6738 if (strlen(p
) >= VIR_SECURITY_MODEL_BUFLEN
-1) {
6739 virReportError(VIR_ERR_INTERNAL_ERROR
,
6740 _("security model string exceeds max %d bytes"),
6741 VIR_SECURITY_MODEL_BUFLEN
-1);
6745 strcpy(secmodel
->model
, p
);
6747 p
= caps
->host
.secModels
[0].doi
;
6748 if (strlen(p
) >= VIR_SECURITY_DOI_BUFLEN
-1) {
6749 virReportError(VIR_ERR_INTERNAL_ERROR
,
6750 _("security DOI string exceeds max %d bytes"),
6751 VIR_SECURITY_DOI_BUFLEN
-1);
6755 strcpy(secmodel
->doi
, p
);
6758 virObjectUnref(caps
);
6764 * qemuDomainSaveImageUpdateDef:
6765 * @driver: qemu driver data
6766 * @def: def of the domain from the save image
6767 * @newxml: user provided replacement XML
6769 * Returns the new domain definition in case @newxml is ABI compatible with the
6772 static virDomainDefPtr
6773 qemuDomainSaveImageUpdateDef(virQEMUDriverPtr driver
,
6774 virDomainDefPtr def
,
6777 virDomainDefPtr ret
= NULL
;
6778 virDomainDefPtr newdef_migr
= NULL
;
6779 virDomainDefPtr newdef
= NULL
;
6780 virCapsPtr caps
= NULL
;
6782 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
6785 if (!(newdef
= virDomainDefParseString(newxml
, caps
, driver
->xmlopt
, NULL
,
6786 VIR_DOMAIN_DEF_PARSE_INACTIVE
)))
6789 if (!(newdef_migr
= qemuDomainDefCopy(driver
,
6791 QEMU_DOMAIN_FORMAT_LIVE_FLAGS
|
6792 VIR_DOMAIN_XML_MIGRATABLE
)))
6795 if (!virDomainDefCheckABIStability(def
, newdef_migr
, driver
->xmlopt
)) {
6796 virErrorPtr err
= virSaveLastError();
6798 /* Due to a bug in older version of external snapshot creation
6799 * code, the XML saved in the save image was not a migratable
6800 * XML. To ensure backwards compatibility with the change of the
6801 * saved XML type, we need to check the ABI compatibility against
6802 * the user provided XML if the check against the migratable XML
6803 * fails. Snapshots created prior to v1.1.3 have this issue. */
6804 if (!virDomainDefCheckABIStability(def
, newdef
, driver
->xmlopt
)) {
6811 /* use the user provided XML */
6812 VIR_STEAL_PTR(ret
, newdef
);
6814 VIR_STEAL_PTR(ret
, newdef_migr
);
6818 virObjectUnref(caps
);
6819 virDomainDefFree(newdef
);
6820 virDomainDefFree(newdef_migr
);
6827 * qemuDomainSaveImageOpen:
6828 * @driver: qemu driver data
6829 * @path: path of the save image
6830 * @ret_def: returns domain definition created from the XML stored in the image
6831 * @ret_data: returns structure filled with data from the image header
6832 * @bypass_cache: bypass cache when opening the file
6833 * @wrapperFd: returns the file wrapper structure
6834 * @open_write: open the file for writing (for updates)
6835 * @unlink_corrupt: remove the image file if it is corrupted
6837 * Returns the opened fd of the save image file and fills the appropriate fields
6838 * on success. On error returns -1 on most failures, -3 if corrupt image was
6839 * unlinked (no error raised).
6841 static int ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
6842 qemuDomainSaveImageOpen(virQEMUDriverPtr driver
,
6844 virDomainDefPtr
*ret_def
,
6845 virQEMUSaveDataPtr
*ret_data
,
6847 virFileWrapperFdPtr
*wrapperFd
,
6849 bool unlink_corrupt
)
6852 virQEMUSaveDataPtr data
= NULL
;
6853 virQEMUSaveHeaderPtr header
;
6854 virDomainDefPtr def
= NULL
;
6855 int oflags
= open_write
? O_RDWR
: O_RDONLY
;
6856 virCapsPtr caps
= NULL
;
6861 int directFlag
= virFileDirectFdFlag();
6862 if (directFlag
< 0) {
6863 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
6864 _("bypass cache unsupported by this system"));
6867 oflags
|= directFlag
;
6870 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
6873 if ((fd
= qemuOpenFile(driver
, NULL
, path
, oflags
, NULL
)) < 0)
6876 !(*wrapperFd
= virFileWrapperFdNew(&fd
, path
,
6877 VIR_FILE_WRAPPER_BYPASS_CACHE
)))
6880 if (VIR_ALLOC(data
) < 0)
6883 header
= &data
->header
;
6884 if (saferead(fd
, header
, sizeof(*header
)) != sizeof(*header
)) {
6885 if (unlink_corrupt
) {
6886 if (VIR_CLOSE(fd
) < 0 || unlink(path
) < 0) {
6887 virReportSystemError(errno
,
6888 _("cannot remove corrupt file: %s"),
6894 virReportError(VIR_ERR_OPERATION_FAILED
,
6895 "%s", _("failed to read qemu header"));
6900 if (memcmp(header
->magic
, QEMU_SAVE_MAGIC
, sizeof(header
->magic
)) != 0) {
6901 const char *msg
= _("image magic is incorrect");
6903 if (memcmp(header
->magic
, QEMU_SAVE_PARTIAL
,
6904 sizeof(header
->magic
)) == 0) {
6905 msg
= _("save image is incomplete");
6906 if (unlink_corrupt
) {
6907 if (VIR_CLOSE(fd
) < 0 || unlink(path
) < 0) {
6908 virReportSystemError(errno
,
6909 _("cannot remove corrupt file: %s"),
6917 virReportError(VIR_ERR_OPERATION_FAILED
, "%s", msg
);
6921 if (header
->version
> QEMU_SAVE_VERSION
) {
6922 /* convert endianess and try again */
6923 bswap_header(header
);
6926 if (header
->version
> QEMU_SAVE_VERSION
) {
6927 virReportError(VIR_ERR_OPERATION_FAILED
,
6928 _("image version is not supported (%d > %d)"),
6929 header
->version
, QEMU_SAVE_VERSION
);
6933 if (header
->data_len
<= 0) {
6934 virReportError(VIR_ERR_OPERATION_FAILED
,
6935 _("invalid header data length: %d"), header
->data_len
);
6939 if (header
->cookieOffset
)
6940 xml_len
= header
->cookieOffset
;
6942 xml_len
= header
->data_len
;
6944 cookie_len
= header
->data_len
- xml_len
;
6946 if (VIR_ALLOC_N(data
->xml
, xml_len
) < 0)
6949 if (saferead(fd
, data
->xml
, xml_len
) != xml_len
) {
6950 virReportError(VIR_ERR_OPERATION_FAILED
,
6951 "%s", _("failed to read domain XML"));
6955 if (cookie_len
> 0) {
6956 if (VIR_ALLOC_N(data
->cookie
, cookie_len
) < 0)
6959 if (saferead(fd
, data
->cookie
, cookie_len
) != cookie_len
) {
6960 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
6961 _("failed to read cookie"));
6966 /* Create a domain from this XML */
6967 if (!(def
= virDomainDefParseString(data
->xml
, caps
, driver
->xmlopt
, NULL
,
6968 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
6969 VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
)))
6976 virObjectUnref(caps
);
6980 virDomainDefFree(def
);
6981 virQEMUSaveDataFree(data
);
6982 VIR_FORCE_CLOSE(fd
);
6986 static int ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6)
6987 qemuDomainSaveImageStartVM(virConnectPtr conn
,
6988 virQEMUDriverPtr driver
,
6991 virQEMUSaveDataPtr data
,
6994 qemuDomainAsyncJob asyncJob
)
6997 bool restored
= false;
6998 virObjectEventPtr event
;
6999 int intermediatefd
= -1;
7000 virCommandPtr cmd
= NULL
;
7001 char *errbuf
= NULL
;
7002 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
7003 virQEMUSaveHeaderPtr header
= &data
->header
;
7004 qemuDomainSaveCookiePtr cookie
= NULL
;
7006 if (virSaveCookieParseString(data
->cookie
, (virObjectPtr
*)&cookie
,
7007 virDomainXMLOptionGetSaveCookie(driver
->xmlopt
)) < 0)
7010 if ((header
->version
== 2) &&
7011 (header
->compressed
!= QEMU_SAVE_FORMAT_RAW
)) {
7012 if (!(cmd
= qemuCompressGetCommand(header
->compressed
)))
7015 intermediatefd
= *fd
;
7018 virCommandSetInputFD(cmd
, intermediatefd
);
7019 virCommandSetOutputFD(cmd
, fd
);
7020 virCommandSetErrorBuffer(cmd
, &errbuf
);
7021 virCommandDoAsyncIO(cmd
);
7023 if (virCommandRunAsync(cmd
, NULL
) < 0) {
7024 *fd
= intermediatefd
;
7029 /* No cookie means libvirt which saved the domain was too old to mess up
7030 * the CPU definitions.
7033 qemuDomainFixupCPUs(vm
, &cookie
->cpu
) < 0)
7036 if (qemuProcessStart(conn
, driver
, vm
, cookie
? cookie
->cpu
: NULL
,
7037 asyncJob
, "stdio", *fd
, path
, NULL
,
7038 VIR_NETDEV_VPORT_PROFILE_OP_RESTORE
,
7039 VIR_QEMU_PROCESS_START_PAUSED
|
7040 VIR_QEMU_PROCESS_START_GEN_VMID
) == 0)
7043 if (intermediatefd
!= -1) {
7044 virErrorPtr orig_err
= NULL
;
7047 /* if there was an error setting up qemu, the intermediate
7048 * process will wait forever to write to stdout, so we
7049 * must manually kill it and ignore any error related to
7052 orig_err
= virSaveLastError();
7053 VIR_FORCE_CLOSE(intermediatefd
);
7054 VIR_FORCE_CLOSE(*fd
);
7057 if (virCommandWait(cmd
, NULL
) < 0) {
7058 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_FAILED
, asyncJob
, 0);
7061 VIR_DEBUG("Decompression binary stderr: %s", NULLSTR(errbuf
));
7064 virSetError(orig_err
);
7065 virFreeError(orig_err
);
7068 VIR_FORCE_CLOSE(intermediatefd
);
7070 if (VIR_CLOSE(*fd
) < 0) {
7071 virReportSystemError(errno
, _("cannot close file: %s"), path
);
7075 virDomainAuditStart(vm
, "restored", restored
);
7079 /* qemuProcessStart doesn't unset the qemu error reporting infrastructure
7080 * in case of migration (which is used in this case) so we need to reset it
7081 * so that the handle to virtlogd is not held open unnecessarily */
7082 qemuMonitorSetDomainLog(qemuDomainGetMonitor(vm
), NULL
, NULL
, NULL
);
7084 event
= virDomainEventLifecycleNewFromObj(vm
,
7085 VIR_DOMAIN_EVENT_STARTED
,
7086 VIR_DOMAIN_EVENT_STARTED_RESTORED
);
7087 virObjectEventStateQueue(driver
->domainEventState
, event
);
7090 /* If it was running before, resume it now unless caller requested pause. */
7091 if (header
->was_running
&& !start_paused
) {
7092 if (qemuProcessStartCPUs(driver
, vm
,
7093 VIR_DOMAIN_RUNNING_RESTORED
,
7095 if (virGetLastErrorCode() == VIR_ERR_OK
)
7096 virReportError(VIR_ERR_OPERATION_FAILED
,
7097 "%s", _("failed to resume domain"));
7100 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0) {
7101 VIR_WARN("Failed to save status on vm %s", vm
->def
->name
);
7105 int detail
= (start_paused
? VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
:
7106 VIR_DOMAIN_EVENT_SUSPENDED_RESTORED
);
7107 event
= virDomainEventLifecycleNewFromObj(vm
,
7108 VIR_DOMAIN_EVENT_SUSPENDED
,
7110 virObjectEventStateQueue(driver
->domainEventState
, event
);
7116 virObjectUnref(cookie
);
7117 virCommandFree(cmd
);
7119 if (qemuSecurityRestoreSavedStateLabel(driver
, vm
, path
) < 0)
7120 VIR_WARN("failed to restore save state label on %s", path
);
7121 virObjectUnref(cfg
);
7126 qemuDomainRestoreFlags(virConnectPtr conn
,
7131 virQEMUDriverPtr driver
= conn
->privateData
;
7132 qemuDomainObjPrivatePtr priv
= NULL
;
7133 virDomainDefPtr def
= NULL
;
7134 virDomainObjPtr vm
= NULL
;
7135 char *xmlout
= NULL
;
7136 const char *newxml
= dxml
;
7139 virQEMUSaveDataPtr data
= NULL
;
7140 virFileWrapperFdPtr wrapperFd
= NULL
;
7141 bool hook_taint
= false;
7143 virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE
|
7144 VIR_DOMAIN_SAVE_RUNNING
|
7145 VIR_DOMAIN_SAVE_PAUSED
, -1);
7148 virNWFilterReadLockFilterUpdates();
7150 fd
= qemuDomainSaveImageOpen(driver
, path
, &def
, &data
,
7151 (flags
& VIR_DOMAIN_SAVE_BYPASS_CACHE
) != 0,
7152 &wrapperFd
, false, false);
7156 if (virDomainRestoreFlagsEnsureACL(conn
, def
) < 0)
7159 if (virHookPresent(VIR_HOOK_DRIVER_QEMU
)) {
7162 if ((hookret
= virHookCall(VIR_HOOK_DRIVER_QEMU
, def
->name
,
7163 VIR_HOOK_QEMU_OP_RESTORE
,
7164 VIR_HOOK_SUBOP_BEGIN
,
7166 dxml
? dxml
: data
->xml
,
7170 if (hookret
== 0 && !virStringIsEmpty(xmlout
)) {
7171 VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout
);
7178 virDomainDefPtr tmp
;
7179 if (!(tmp
= qemuDomainSaveImageUpdateDef(driver
, def
, newxml
)))
7182 virDomainDefFree(def
);
7186 if (!(vm
= virDomainObjListAdd(driver
->domains
, def
,
7188 VIR_DOMAIN_OBJ_LIST_ADD_LIVE
|
7189 VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE
,
7194 if (flags
& VIR_DOMAIN_SAVE_RUNNING
)
7195 data
->header
.was_running
= 1;
7196 else if (flags
& VIR_DOMAIN_SAVE_PAUSED
)
7197 data
->header
.was_running
= 0;
7200 priv
= vm
->privateData
;
7201 priv
->hookRun
= true;
7204 if (qemuProcessBeginJob(driver
, vm
, VIR_DOMAIN_JOB_OPERATION_RESTORE
,
7208 ret
= qemuDomainSaveImageStartVM(conn
, driver
, vm
, &fd
, data
, path
,
7209 false, QEMU_ASYNC_JOB_START
);
7211 qemuProcessEndJob(driver
, vm
);
7214 virDomainDefFree(def
);
7215 VIR_FORCE_CLOSE(fd
);
7216 if (virFileWrapperFdClose(wrapperFd
) < 0)
7218 virFileWrapperFdFree(wrapperFd
);
7219 virQEMUSaveDataFree(data
);
7222 qemuDomainRemoveInactiveJob(driver
, vm
);
7223 virDomainObjEndAPI(&vm
);
7224 virNWFilterUnlockFilterUpdates();
7229 qemuDomainRestore(virConnectPtr conn
,
7232 return qemuDomainRestoreFlags(conn
, path
, NULL
, 0);
7236 qemuDomainSaveImageGetXMLDesc(virConnectPtr conn
, const char *path
,
7239 virQEMUDriverPtr driver
= conn
->privateData
;
7241 virDomainDefPtr def
= NULL
;
7243 virQEMUSaveDataPtr data
= NULL
;
7245 virCheckFlags(VIR_DOMAIN_SAVE_IMAGE_XML_SECURE
, NULL
);
7247 fd
= qemuDomainSaveImageOpen(driver
, path
, &def
, &data
,
7248 false, NULL
, false, false);
7253 if (virDomainSaveImageGetXMLDescEnsureACL(conn
, def
, flags
) < 0)
7256 ret
= qemuDomainDefFormatXML(driver
, def
, flags
);
7259 virQEMUSaveDataFree(data
);
7260 virDomainDefFree(def
);
7261 VIR_FORCE_CLOSE(fd
);
7266 qemuDomainSaveImageDefineXML(virConnectPtr conn
, const char *path
,
7267 const char *dxml
, unsigned int flags
)
7269 virQEMUDriverPtr driver
= conn
->privateData
;
7271 virDomainDefPtr def
= NULL
;
7272 virDomainDefPtr newdef
= NULL
;
7274 virQEMUSaveDataPtr data
= NULL
;
7277 virCheckFlags(VIR_DOMAIN_SAVE_RUNNING
|
7278 VIR_DOMAIN_SAVE_PAUSED
, -1);
7280 if (flags
& VIR_DOMAIN_SAVE_RUNNING
)
7282 else if (flags
& VIR_DOMAIN_SAVE_PAUSED
)
7285 fd
= qemuDomainSaveImageOpen(driver
, path
, &def
, &data
,
7286 false, NULL
, true, false);
7291 if (virDomainSaveImageDefineXMLEnsureACL(conn
, def
) < 0)
7294 if (STREQ(data
->xml
, dxml
) &&
7295 (state
< 0 || state
== data
->header
.was_running
)) {
7296 /* no change to the XML */
7302 data
->header
.was_running
= state
;
7304 if (!(newdef
= qemuDomainSaveImageUpdateDef(driver
, def
, dxml
)))
7307 VIR_FREE(data
->xml
);
7309 if (!(data
->xml
= qemuDomainDefFormatXML(driver
, newdef
,
7310 VIR_DOMAIN_XML_INACTIVE
|
7311 VIR_DOMAIN_XML_SECURE
|
7312 VIR_DOMAIN_XML_MIGRATABLE
)))
7315 if (lseek(fd
, 0, SEEK_SET
) != 0) {
7316 virReportSystemError(errno
, _("cannot seek in '%s'"), path
);
7320 if (virQEMUSaveDataWrite(data
, fd
, path
) < 0)
7323 if (VIR_CLOSE(fd
) < 0) {
7324 virReportSystemError(errno
, _("failed to write header data to '%s'"), path
);
7331 virDomainDefFree(def
);
7332 virDomainDefFree(newdef
);
7333 VIR_FORCE_CLOSE(fd
);
7334 virQEMUSaveDataFree(data
);
7339 qemuDomainManagedSaveGetXMLDesc(virDomainPtr dom
, unsigned int flags
)
7341 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
7345 virDomainDefPtr def
= NULL
;
7347 virQEMUSaveDataPtr data
= NULL
;
7349 virCheckFlags(VIR_DOMAIN_SAVE_IMAGE_XML_SECURE
, NULL
);
7351 if (!(vm
= qemuDomObjFromDomain(dom
)))
7354 if (virDomainManagedSaveGetXMLDescEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
7357 if (!(path
= qemuDomainManagedSavePath(driver
, vm
)))
7360 if (!virFileExists(path
)) {
7361 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
7362 _("domain does not have managed save image"));
7366 if ((fd
= qemuDomainSaveImageOpen(driver
, path
, &def
, &data
,
7367 false, NULL
, false, false)) < 0)
7370 ret
= qemuDomainDefFormatXML(driver
, def
, flags
);
7373 virQEMUSaveDataFree(data
);
7374 virDomainDefFree(def
);
7375 VIR_FORCE_CLOSE(fd
);
7376 virDomainObjEndAPI(&vm
);
7382 qemuDomainManagedSaveDefineXML(virDomainPtr dom
, const char *dxml
,
7385 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
7386 virConnectPtr conn
= dom
->conn
;
7391 if (!(vm
= qemuDomObjFromDomain(dom
)))
7394 if (virDomainManagedSaveDefineXMLEnsureACL(conn
, vm
->def
) < 0)
7397 if (!(path
= qemuDomainManagedSavePath(driver
, vm
)))
7400 if (!virFileExists(path
)) {
7401 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
7402 _("domain does not have managed save image"));
7406 ret
= qemuDomainSaveImageDefineXML(conn
, path
, dxml
, flags
);
7409 virDomainObjEndAPI(&vm
);
7414 /* Return 0 on success, 1 if incomplete saved image was silently unlinked,
7415 * and -1 on failure with error raised. */
7417 qemuDomainObjRestore(virConnectPtr conn
,
7418 virQEMUDriverPtr driver
,
7423 qemuDomainAsyncJob asyncJob
)
7425 virDomainDefPtr def
= NULL
;
7426 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
7429 char *xmlout
= NULL
;
7430 virQEMUSaveDataPtr data
= NULL
;
7431 virFileWrapperFdPtr wrapperFd
= NULL
;
7433 fd
= qemuDomainSaveImageOpen(driver
, path
, &def
, &data
,
7434 bypass_cache
, &wrapperFd
, false, true);
7441 if (virHookPresent(VIR_HOOK_DRIVER_QEMU
)) {
7444 if ((hookret
= virHookCall(VIR_HOOK_DRIVER_QEMU
, def
->name
,
7445 VIR_HOOK_QEMU_OP_RESTORE
,
7446 VIR_HOOK_SUBOP_BEGIN
,
7447 NULL
, data
->xml
, &xmlout
)) < 0)
7450 if (hookret
== 0 && !virStringIsEmpty(xmlout
)) {
7451 virDomainDefPtr tmp
;
7453 VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout
);
7455 if (!(tmp
= qemuDomainSaveImageUpdateDef(driver
, def
, xmlout
)))
7458 virDomainDefFree(def
);
7460 priv
->hookRun
= true;
7464 if (STRNEQ(vm
->def
->name
, def
->name
) ||
7465 memcmp(vm
->def
->uuid
, def
->uuid
, VIR_UUID_BUFLEN
)) {
7466 char vm_uuidstr
[VIR_UUID_STRING_BUFLEN
];
7467 char def_uuidstr
[VIR_UUID_STRING_BUFLEN
];
7468 virUUIDFormat(vm
->def
->uuid
, vm_uuidstr
);
7469 virUUIDFormat(def
->uuid
, def_uuidstr
);
7470 virReportError(VIR_ERR_OPERATION_FAILED
,
7471 _("cannot restore domain '%s' uuid %s from a file"
7472 " which belongs to domain '%s' uuid %s"),
7473 vm
->def
->name
, vm_uuidstr
,
7474 def
->name
, def_uuidstr
);
7478 virDomainObjAssignDef(vm
, def
, true, NULL
);
7481 ret
= qemuDomainSaveImageStartVM(conn
, driver
, vm
, &fd
, data
, path
,
7482 start_paused
, asyncJob
);
7485 virQEMUSaveDataFree(data
);
7487 virDomainDefFree(def
);
7488 VIR_FORCE_CLOSE(fd
);
7489 if (virFileWrapperFdClose(wrapperFd
) < 0)
7491 virFileWrapperFdFree(wrapperFd
);
7497 *qemuDomainGetXMLDesc(virDomainPtr dom
,
7500 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
7504 virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS
| VIR_DOMAIN_XML_UPDATE_CPU
|
7505 VIR_DOMAIN_XML_SNAPSHOTS
| VIR_DOMAIN_XML_CHECKPOINTS
, NULL
);
7507 if (!(vm
= qemuDomObjFromDomain(dom
)))
7510 if (virDomainGetXMLDescEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
7513 qemuDomainUpdateCurrentMemorySize(vm
);
7515 if ((flags
& VIR_DOMAIN_XML_MIGRATABLE
))
7516 flags
|= QEMU_DOMAIN_FORMAT_LIVE_FLAGS
;
7518 /* The CPU is already updated in the domain's live definition, we need to
7519 * ignore the VIR_DOMAIN_XML_UPDATE_CPU flag.
7521 if (virDomainObjIsActive(vm
) &&
7522 !(flags
& VIR_DOMAIN_XML_INACTIVE
))
7523 flags
&= ~VIR_DOMAIN_XML_UPDATE_CPU
;
7525 ret
= qemuDomainFormatXML(driver
, vm
, flags
);
7528 virDomainObjEndAPI(&vm
);
7533 static char *qemuConnectDomainXMLFromNative(virConnectPtr conn
,
7538 virQEMUDriverPtr driver
= conn
->privateData
;
7539 virDomainDefPtr def
= NULL
;
7541 virCapsPtr caps
= NULL
;
7543 virCheckFlags(0, NULL
);
7545 if (virConnectDomainXMLFromNativeEnsureACL(conn
) < 0)
7548 if (STRNEQ(format
, QEMU_CONFIG_FORMAT_ARGV
)) {
7549 virReportError(VIR_ERR_INVALID_ARG
,
7550 _("unsupported config type %s"), format
);
7554 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
7557 def
= qemuParseCommandLineString(driver
->qemuCapsCache
,
7558 caps
, driver
->xmlopt
, config
,
7563 if (!def
->name
&& VIR_STRDUP(def
->name
, "unnamed") < 0)
7566 xml
= qemuDomainDefFormatXML(driver
, def
, VIR_DOMAIN_XML_INACTIVE
);
7569 virDomainDefFree(def
);
7570 virObjectUnref(caps
);
7574 static char *qemuConnectDomainXMLToNative(virConnectPtr conn
,
7576 const char *xmlData
,
7579 virQEMUDriverPtr driver
= conn
->privateData
;
7580 virDomainObjPtr vm
= NULL
;
7581 virCommandPtr cmd
= NULL
;
7584 virQEMUDriverConfigPtr cfg
;
7585 virCapsPtr caps
= NULL
;
7587 virCheckFlags(0, NULL
);
7589 cfg
= virQEMUDriverGetConfig(driver
);
7591 if (virConnectDomainXMLToNativeEnsureACL(conn
) < 0)
7594 if (STRNEQ(format
, QEMU_CONFIG_FORMAT_ARGV
)) {
7595 virReportError(VIR_ERR_INVALID_ARG
,
7596 _("unsupported config type %s"), format
);
7600 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
7603 if (!(vm
= virDomainObjNew(driver
->xmlopt
)))
7606 if (!(vm
->def
= virDomainDefParseString(xmlData
, caps
, driver
->xmlopt
, NULL
,
7607 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
7608 VIR_DOMAIN_DEF_PARSE_ABI_UPDATE
)))
7611 /* Since we're just exporting args, we can't do bridge/network/direct
7612 * setups, since libvirt will normally create TAP/macvtap devices
7613 * directly. We convert those configs into generic 'ethernet'
7614 * config and assume the user has suitable 'ifup-qemu' scripts
7616 for (i
= 0; i
< vm
->def
->nnets
; i
++) {
7617 virDomainNetDefPtr net
= vm
->def
->nets
[i
];
7618 unsigned int bootIndex
= net
->info
.bootIndex
;
7619 char *model
= net
->model
;
7620 virMacAddr mac
= net
->mac
;
7621 char *script
= net
->script
;
7626 virDomainNetDefClear(net
);
7628 net
->type
= VIR_DOMAIN_NET_TYPE_ETHERNET
;
7629 net
->info
.bootIndex
= bootIndex
;
7632 net
->script
= script
;
7635 if (!(cmd
= qemuProcessCreatePretendCmd(driver
, vm
, NULL
,
7636 qemuCheckFips(), true,
7637 VIR_QEMU_PROCESS_START_COLD
)))
7640 ret
= virCommandToString(cmd
, false);
7643 virCommandFree(cmd
);
7645 virObjectUnref(caps
);
7646 virObjectUnref(cfg
);
7651 static int qemuConnectListDefinedDomains(virConnectPtr conn
,
7652 char **const names
, int nnames
) {
7653 virQEMUDriverPtr driver
= conn
->privateData
;
7656 if (virConnectListDefinedDomainsEnsureACL(conn
) < 0)
7659 ret
= virDomainObjListGetInactiveNames(driver
->domains
, names
, nnames
,
7660 virConnectListDefinedDomainsCheckACL
,
7667 static int qemuConnectNumOfDefinedDomains(virConnectPtr conn
)
7669 virQEMUDriverPtr driver
= conn
->privateData
;
7672 if (virConnectNumOfDefinedDomainsEnsureACL(conn
) < 0)
7675 ret
= virDomainObjListNumOfDomains(driver
->domains
, false,
7676 virConnectNumOfDefinedDomainsCheckACL
,
7685 qemuDomainObjStart(virConnectPtr conn
,
7686 virQEMUDriverPtr driver
,
7689 qemuDomainAsyncJob asyncJob
)
7693 bool start_paused
= (flags
& VIR_DOMAIN_START_PAUSED
) != 0;
7694 bool autodestroy
= (flags
& VIR_DOMAIN_START_AUTODESTROY
) != 0;
7695 bool bypass_cache
= (flags
& VIR_DOMAIN_START_BYPASS_CACHE
) != 0;
7696 bool force_boot
= (flags
& VIR_DOMAIN_START_FORCE_BOOT
) != 0;
7697 unsigned int start_flags
= VIR_QEMU_PROCESS_START_COLD
;
7698 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
7700 start_flags
|= start_paused
? VIR_QEMU_PROCESS_START_PAUSED
: 0;
7701 start_flags
|= autodestroy
? VIR_QEMU_PROCESS_START_AUTODESTROY
: 0;
7704 * If there is a managed saved state restore it instead of starting
7705 * from scratch. The old state is removed once the restoring succeeded.
7707 managed_save
= qemuDomainManagedSavePath(driver
, vm
);
7712 if (virFileExists(managed_save
)) {
7714 if (unlink(managed_save
) < 0) {
7715 virReportSystemError(errno
,
7716 _("cannot remove managed save file %s"),
7720 vm
->hasManagedSave
= false;
7722 virDomainJobOperation op
= priv
->job
.current
->operation
;
7723 priv
->job
.current
->operation
= VIR_DOMAIN_JOB_OPERATION_RESTORE
;
7725 ret
= qemuDomainObjRestore(conn
, driver
, vm
, managed_save
,
7726 start_paused
, bypass_cache
, asyncJob
);
7729 if (unlink(managed_save
) < 0)
7730 VIR_WARN("Failed to remove the managed state %s", managed_save
);
7732 vm
->hasManagedSave
= false;
7735 } else if (ret
< 0) {
7736 VIR_WARN("Unable to restore from managed state %s. "
7737 "Maybe the file is corrupted?", managed_save
);
7740 VIR_WARN("Ignoring incomplete managed state %s", managed_save
);
7741 priv
->job
.current
->operation
= op
;
7742 vm
->hasManagedSave
= false;
7747 ret
= qemuProcessStart(conn
, driver
, vm
, NULL
, asyncJob
,
7748 NULL
, -1, NULL
, NULL
,
7749 VIR_NETDEV_VPORT_PROFILE_OP_CREATE
, start_flags
);
7750 virDomainAuditStart(vm
, "booted", ret
>= 0);
7752 virObjectEventPtr event
=
7753 virDomainEventLifecycleNewFromObj(vm
,
7754 VIR_DOMAIN_EVENT_STARTED
,
7755 VIR_DOMAIN_EVENT_STARTED_BOOTED
);
7756 virObjectEventStateQueue(driver
->domainEventState
, event
);
7758 event
= virDomainEventLifecycleNewFromObj(vm
,
7759 VIR_DOMAIN_EVENT_SUSPENDED
,
7760 VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
);
7761 virObjectEventStateQueue(driver
->domainEventState
, event
);
7766 VIR_FREE(managed_save
);
7771 qemuDomainCreateWithFlags(virDomainPtr dom
, unsigned int flags
)
7773 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
7777 virCheckFlags(VIR_DOMAIN_START_PAUSED
|
7778 VIR_DOMAIN_START_AUTODESTROY
|
7779 VIR_DOMAIN_START_BYPASS_CACHE
|
7780 VIR_DOMAIN_START_FORCE_BOOT
, -1);
7782 virNWFilterReadLockFilterUpdates();
7784 if (!(vm
= qemuDomObjFromDomain(dom
)))
7787 if (virDomainCreateWithFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
7790 if (qemuProcessBeginJob(driver
, vm
, VIR_DOMAIN_JOB_OPERATION_START
,
7794 if (virDomainObjIsActive(vm
)) {
7795 virReportError(VIR_ERR_OPERATION_INVALID
,
7796 "%s", _("domain is already running"));
7800 if (qemuDomainObjStart(dom
->conn
, driver
, vm
, flags
,
7801 QEMU_ASYNC_JOB_START
) < 0)
7804 dom
->id
= vm
->def
->id
;
7808 qemuProcessEndJob(driver
, vm
);
7811 virDomainObjEndAPI(&vm
);
7812 virNWFilterUnlockFilterUpdates();
7817 qemuDomainCreate(virDomainPtr dom
)
7819 return qemuDomainCreateWithFlags(dom
, 0);
7823 qemuDomainDefineXMLFlags(virConnectPtr conn
,
7827 virQEMUDriverPtr driver
= conn
->privateData
;
7828 virDomainDefPtr def
= NULL
;
7829 virDomainDefPtr oldDef
= NULL
;
7830 virDomainObjPtr vm
= NULL
;
7831 virDomainPtr dom
= NULL
;
7832 virObjectEventPtr event
= NULL
;
7833 virQEMUDriverConfigPtr cfg
;
7834 virCapsPtr caps
= NULL
;
7835 unsigned int parse_flags
= VIR_DOMAIN_DEF_PARSE_INACTIVE
|
7836 VIR_DOMAIN_DEF_PARSE_ABI_UPDATE
;
7838 virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE
, NULL
);
7840 if (flags
& VIR_DOMAIN_DEFINE_VALIDATE
)
7841 parse_flags
|= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA
;
7843 cfg
= virQEMUDriverGetConfig(driver
);
7845 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
7848 if (!(def
= virDomainDefParseString(xml
, caps
, driver
->xmlopt
,
7849 NULL
, parse_flags
)))
7852 if (virXMLCheckIllegalChars("name", def
->name
, "\n") < 0)
7855 if (virDomainDefineXMLFlagsEnsureACL(conn
, def
) < 0)
7858 if (!(vm
= virDomainObjListAdd(driver
->domains
, def
,
7866 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
7867 vm
->newDef
? vm
->newDef
: vm
->def
) < 0) {
7869 /* There is backup so this VM was defined before.
7870 * Just restore the backup. */
7871 VIR_INFO("Restoring domain '%s' definition", vm
->def
->name
);
7872 if (virDomainObjIsActive(vm
))
7873 vm
->newDef
= oldDef
;
7878 /* Brand new domain. Remove it */
7879 VIR_INFO("Deleting domain '%s'", vm
->def
->name
);
7881 qemuDomainRemoveInactiveJob(driver
, vm
);
7886 event
= virDomainEventLifecycleNewFromObj(vm
,
7887 VIR_DOMAIN_EVENT_DEFINED
,
7889 VIR_DOMAIN_EVENT_DEFINED_ADDED
:
7890 VIR_DOMAIN_EVENT_DEFINED_UPDATED
);
7892 VIR_INFO("Creating domain '%s'", vm
->def
->name
);
7893 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
7896 virDomainDefFree(oldDef
);
7897 virDomainDefFree(def
);
7898 virDomainObjEndAPI(&vm
);
7899 virObjectEventStateQueue(driver
->domainEventState
, event
);
7900 virObjectUnref(caps
);
7901 virObjectUnref(cfg
);
7906 qemuDomainDefineXML(virConnectPtr conn
, const char *xml
)
7908 return qemuDomainDefineXMLFlags(conn
, xml
, 0);
7912 qemuDomainUndefineFlags(virDomainPtr dom
,
7915 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
7917 virObjectEventPtr event
= NULL
;
7921 virQEMUDriverConfigPtr cfg
= NULL
;
7923 virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE
|
7924 VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA
|
7925 VIR_DOMAIN_UNDEFINE_NVRAM
|
7926 VIR_DOMAIN_UNDEFINE_KEEP_NVRAM
, -1);
7928 if ((flags
& VIR_DOMAIN_UNDEFINE_NVRAM
) &&
7929 (flags
& VIR_DOMAIN_UNDEFINE_KEEP_NVRAM
)) {
7930 virReportError(VIR_ERR_OPERATION_INVALID
,
7931 "%s", _("cannot both keep and delete nvram"));
7935 if (!(vm
= qemuDomObjFromDomain(dom
)))
7938 cfg
= virQEMUDriverGetConfig(driver
);
7940 if (virDomainUndefineFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
7943 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
7946 if (!vm
->persistent
) {
7947 virReportError(VIR_ERR_OPERATION_INVALID
,
7948 "%s", _("cannot undefine transient domain"));
7952 if (!virDomainObjIsActive(vm
) &&
7953 (nsnapshots
= virDomainSnapshotObjListNum(vm
->snapshots
, NULL
, 0))) {
7954 if (!(flags
& VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA
)) {
7955 virReportError(VIR_ERR_OPERATION_INVALID
,
7956 _("cannot delete inactive domain with %d "
7961 if (qemuDomainSnapshotDiscardAllMetadata(driver
, vm
) < 0)
7964 /* TODO: Restrict deletion if checkpoints exist? */
7966 name
= qemuDomainManagedSavePath(driver
, vm
);
7970 if (virFileExists(name
)) {
7971 if (flags
& VIR_DOMAIN_UNDEFINE_MANAGED_SAVE
) {
7972 if (unlink(name
) < 0) {
7973 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
7974 _("Failed to remove domain managed "
7979 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
7980 _("Refusing to undefine while domain managed "
7981 "save image exists"));
7986 if (vm
->def
->os
.loader
&&
7987 vm
->def
->os
.loader
->nvram
&&
7988 virFileExists(vm
->def
->os
.loader
->nvram
)) {
7989 if ((flags
& VIR_DOMAIN_UNDEFINE_NVRAM
)) {
7990 if (unlink(vm
->def
->os
.loader
->nvram
) < 0) {
7991 virReportSystemError(errno
,
7992 _("failed to remove nvram: %s"),
7993 vm
->def
->os
.loader
->nvram
);
7996 } else if (!(flags
& VIR_DOMAIN_UNDEFINE_KEEP_NVRAM
)) {
7997 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
7998 _("cannot undefine domain with nvram"));
8003 if (virDomainDeleteConfig(cfg
->configDir
, cfg
->autostartDir
, vm
) < 0)
8006 event
= virDomainEventLifecycleNewFromObj(vm
,
8007 VIR_DOMAIN_EVENT_UNDEFINED
,
8008 VIR_DOMAIN_EVENT_UNDEFINED_REMOVED
);
8010 VIR_INFO("Undefining domain '%s'", vm
->def
->name
);
8012 /* If the domain is active, keep it running but set it as transient.
8013 * domainDestroy and domainShutdown will take care of removing the
8014 * domain obj from the hash table.
8017 if (!virDomainObjIsActive(vm
))
8018 qemuDomainRemoveInactive(driver
, vm
);
8022 qemuDomainObjEndJob(driver
, vm
);
8026 virDomainObjEndAPI(&vm
);
8027 virObjectEventStateQueue(driver
->domainEventState
, event
);
8028 virObjectUnref(cfg
);
8033 qemuDomainUndefine(virDomainPtr dom
)
8035 return qemuDomainUndefineFlags(dom
, 0);
8039 qemuDomainAttachDeviceLive(virDomainObjPtr vm
,
8040 virDomainDeviceDefPtr dev
,
8041 virQEMUDriverPtr driver
)
8044 const char *alias
= NULL
;
8046 switch ((virDomainDeviceType
)dev
->type
) {
8047 case VIR_DOMAIN_DEVICE_DISK
:
8048 qemuDomainObjCheckDiskTaint(driver
, vm
, dev
->data
.disk
, NULL
);
8049 ret
= qemuDomainAttachDeviceDiskLive(driver
, vm
, dev
);
8051 alias
= dev
->data
.disk
->info
.alias
;
8052 dev
->data
.disk
= NULL
;
8056 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8057 ret
= qemuDomainAttachControllerDevice(driver
, vm
, dev
->data
.controller
);
8059 alias
= dev
->data
.controller
->info
.alias
;
8060 dev
->data
.controller
= NULL
;
8064 case VIR_DOMAIN_DEVICE_LEASE
:
8065 ret
= qemuDomainAttachLease(driver
, vm
,
8068 dev
->data
.lease
= NULL
;
8071 case VIR_DOMAIN_DEVICE_NET
:
8072 qemuDomainObjCheckNetTaint(driver
, vm
, dev
->data
.net
, NULL
);
8073 ret
= qemuDomainAttachNetDevice(driver
, vm
, dev
->data
.net
);
8075 alias
= dev
->data
.net
->info
.alias
;
8076 dev
->data
.net
= NULL
;
8080 case VIR_DOMAIN_DEVICE_HOSTDEV
:
8081 qemuDomainObjCheckHostdevTaint(driver
, vm
, dev
->data
.hostdev
, NULL
);
8082 ret
= qemuDomainAttachHostDevice(driver
, vm
,
8085 alias
= dev
->data
.hostdev
->info
->alias
;
8086 dev
->data
.hostdev
= NULL
;
8090 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8091 ret
= qemuDomainAttachRedirdevDevice(driver
, vm
,
8092 dev
->data
.redirdev
);
8094 alias
= dev
->data
.redirdev
->info
.alias
;
8095 dev
->data
.redirdev
= NULL
;
8099 case VIR_DOMAIN_DEVICE_CHR
:
8100 ret
= qemuDomainAttachChrDevice(driver
, vm
,
8103 alias
= dev
->data
.chr
->info
.alias
;
8104 dev
->data
.chr
= NULL
;
8108 case VIR_DOMAIN_DEVICE_RNG
:
8109 ret
= qemuDomainAttachRNGDevice(driver
, vm
,
8112 alias
= dev
->data
.rng
->info
.alias
;
8113 dev
->data
.rng
= NULL
;
8117 case VIR_DOMAIN_DEVICE_MEMORY
:
8118 /* note that qemuDomainAttachMemory always consumes dev->data.memory
8119 * and dispatches DeviceAdded event on success */
8120 ret
= qemuDomainAttachMemory(driver
, vm
,
8122 dev
->data
.memory
= NULL
;
8125 case VIR_DOMAIN_DEVICE_SHMEM
:
8126 ret
= qemuDomainAttachShmemDevice(driver
, vm
,
8129 alias
= dev
->data
.shmem
->info
.alias
;
8130 dev
->data
.shmem
= NULL
;
8134 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8135 ret
= qemuDomainAttachWatchdog(driver
, vm
,
8136 dev
->data
.watchdog
);
8138 alias
= dev
->data
.watchdog
->info
.alias
;
8139 dev
->data
.watchdog
= NULL
;
8143 case VIR_DOMAIN_DEVICE_INPUT
:
8144 ret
= qemuDomainAttachInputDevice(driver
, vm
, dev
->data
.input
);
8146 alias
= dev
->data
.input
->info
.alias
;
8147 dev
->data
.input
= NULL
;
8151 case VIR_DOMAIN_DEVICE_VSOCK
:
8152 ret
= qemuDomainAttachVsockDevice(driver
, vm
, dev
->data
.vsock
);
8154 alias
= dev
->data
.vsock
->info
.alias
;
8155 dev
->data
.vsock
= NULL
;
8159 case VIR_DOMAIN_DEVICE_NONE
:
8160 case VIR_DOMAIN_DEVICE_FS
:
8161 case VIR_DOMAIN_DEVICE_SOUND
:
8162 case VIR_DOMAIN_DEVICE_VIDEO
:
8163 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8164 case VIR_DOMAIN_DEVICE_HUB
:
8165 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8166 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8167 case VIR_DOMAIN_DEVICE_NVRAM
:
8168 case VIR_DOMAIN_DEVICE_TPM
:
8169 case VIR_DOMAIN_DEVICE_PANIC
:
8170 case VIR_DOMAIN_DEVICE_IOMMU
:
8171 case VIR_DOMAIN_DEVICE_LAST
:
8172 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
8173 _("live attach of device '%s' is not supported"),
8174 virDomainDeviceTypeToString(dev
->type
));
8179 /* queue the event before the alias has a chance to get freed
8180 * if the domain disappears while qemuDomainUpdateDeviceList
8182 virObjectEventPtr event
;
8183 event
= virDomainEventDeviceAddedNewFromObj(vm
, alias
);
8184 virObjectEventStateQueue(driver
->domainEventState
, event
);
8188 ret
= qemuDomainUpdateDeviceList(driver
, vm
, QEMU_ASYNC_JOB_NONE
);
8194 qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver
,
8196 virDomainDeviceDefPtr dev
,
8199 virDomainControllerDefPtr cont
= dev
->data
.controller
;
8202 switch (cont
->type
) {
8203 case VIR_DOMAIN_CONTROLLER_TYPE_SCSI
:
8204 ret
= qemuDomainDetachControllerDevice(driver
, vm
, dev
, async
);
8207 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
8208 _("'%s' controller cannot be hot unplugged."),
8209 virDomainControllerTypeToString(cont
->type
));
8215 qemuDomainDetachDeviceLive(virDomainObjPtr vm
,
8216 virDomainDeviceDefPtr dev
,
8217 virQEMUDriverPtr driver
,
8222 switch ((virDomainDeviceType
)dev
->type
) {
8223 case VIR_DOMAIN_DEVICE_DISK
:
8224 ret
= qemuDomainDetachDeviceDiskLive(driver
, vm
, dev
, async
);
8226 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8227 ret
= qemuDomainDetachDeviceControllerLive(driver
, vm
, dev
, async
);
8229 case VIR_DOMAIN_DEVICE_LEASE
:
8230 ret
= qemuDomainDetachLease(driver
, vm
, dev
->data
.lease
);
8232 case VIR_DOMAIN_DEVICE_NET
:
8233 ret
= qemuDomainDetachNetDevice(driver
, vm
, dev
, async
);
8235 case VIR_DOMAIN_DEVICE_HOSTDEV
:
8236 ret
= qemuDomainDetachHostDevice(driver
, vm
, dev
, async
);
8238 case VIR_DOMAIN_DEVICE_CHR
:
8239 ret
= qemuDomainDetachChrDevice(driver
, vm
, dev
->data
.chr
, async
);
8241 case VIR_DOMAIN_DEVICE_RNG
:
8242 ret
= qemuDomainDetachRNGDevice(driver
, vm
, dev
->data
.rng
, async
);
8244 case VIR_DOMAIN_DEVICE_MEMORY
:
8245 ret
= qemuDomainDetachMemoryDevice(driver
, vm
, dev
->data
.memory
, async
);
8247 case VIR_DOMAIN_DEVICE_SHMEM
:
8248 ret
= qemuDomainDetachShmemDevice(driver
, vm
, dev
->data
.shmem
, async
);
8250 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8251 ret
= qemuDomainDetachWatchdog(driver
, vm
, dev
->data
.watchdog
, async
);
8253 case VIR_DOMAIN_DEVICE_INPUT
:
8254 ret
= qemuDomainDetachInputDevice(vm
, dev
->data
.input
, async
);
8256 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8257 ret
= qemuDomainDetachRedirdevDevice(driver
, vm
, dev
->data
.redirdev
, async
);
8260 case VIR_DOMAIN_DEVICE_VSOCK
:
8261 ret
= qemuDomainDetachVsockDevice(vm
, dev
->data
.vsock
, async
);
8264 case VIR_DOMAIN_DEVICE_FS
:
8265 case VIR_DOMAIN_DEVICE_SOUND
:
8266 case VIR_DOMAIN_DEVICE_VIDEO
:
8267 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8268 case VIR_DOMAIN_DEVICE_HUB
:
8269 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8270 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8271 case VIR_DOMAIN_DEVICE_NVRAM
:
8272 case VIR_DOMAIN_DEVICE_NONE
:
8273 case VIR_DOMAIN_DEVICE_TPM
:
8274 case VIR_DOMAIN_DEVICE_PANIC
:
8275 case VIR_DOMAIN_DEVICE_IOMMU
:
8276 case VIR_DOMAIN_DEVICE_LAST
:
8277 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
8278 _("live detach of device '%s' is not supported"),
8279 virDomainDeviceTypeToString(dev
->type
));
8284 ret
= qemuDomainUpdateDeviceList(driver
, vm
, QEMU_ASYNC_JOB_NONE
);
8290 qemuDomainChangeDiskLive(virDomainObjPtr vm
,
8291 virDomainDeviceDefPtr dev
,
8292 virQEMUDriverPtr driver
,
8295 virDomainDiskDefPtr disk
= dev
->data
.disk
;
8296 virDomainDiskDefPtr orig_disk
= NULL
;
8297 virDomainDeviceDef oldDev
= { .type
= dev
->type
};
8300 if (!(orig_disk
= virDomainDiskFindByBusAndDst(vm
->def
,
8301 disk
->bus
, disk
->dst
))) {
8302 virReportError(VIR_ERR_INTERNAL_ERROR
,
8303 _("No device with bus '%s' and target '%s'"),
8304 virDomainDiskBusTypeToString(disk
->bus
),
8309 oldDev
.data
.disk
= orig_disk
;
8310 if (virDomainDefCompatibleDevice(vm
->def
, dev
, &oldDev
,
8311 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8315 if (!qemuDomainDiskChangeSupported(disk
, orig_disk
))
8318 if (!virStorageSourceIsSameLocation(disk
->src
, orig_disk
->src
)) {
8319 /* Disk source can be changed only for removable devices */
8320 if (disk
->device
!= VIR_DOMAIN_DISK_DEVICE_CDROM
&&
8321 disk
->device
!= VIR_DOMAIN_DISK_DEVICE_FLOPPY
) {
8322 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
8323 _("disk source can be changed only in removable "
8328 if (qemuDomainChangeEjectableMedia(driver
, vm
, orig_disk
,
8329 dev
->data
.disk
->src
, force
) < 0)
8332 dev
->data
.disk
->src
= NULL
;
8335 orig_disk
->startupPolicy
= dev
->data
.disk
->startupPolicy
;
8336 orig_disk
->snapshot
= dev
->data
.disk
->snapshot
;
8344 qemuDomainUpdateDeviceLive(virDomainObjPtr vm
,
8345 virDomainDeviceDefPtr dev
,
8349 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
8350 virDomainDeviceDef oldDev
= { .type
= dev
->type
};
8354 switch ((virDomainDeviceType
)dev
->type
) {
8355 case VIR_DOMAIN_DEVICE_DISK
:
8356 qemuDomainObjCheckDiskTaint(driver
, vm
, dev
->data
.disk
, NULL
);
8357 ret
= qemuDomainChangeDiskLive(vm
, dev
, driver
, force
);
8360 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8361 if ((idx
= qemuDomainFindGraphicsIndex(vm
->def
, dev
->data
.graphics
)) >= 0) {
8362 oldDev
.data
.graphics
= vm
->def
->graphics
[idx
];
8363 if (virDomainDefCompatibleDevice(vm
->def
, dev
, &oldDev
,
8364 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8369 ret
= qemuDomainChangeGraphics(driver
, vm
, dev
->data
.graphics
);
8372 case VIR_DOMAIN_DEVICE_NET
:
8373 if ((idx
= virDomainNetFindIdx(vm
->def
, dev
->data
.net
)) >= 0) {
8374 oldDev
.data
.net
= vm
->def
->nets
[idx
];
8375 if (virDomainDefCompatibleDevice(vm
->def
, dev
, &oldDev
,
8376 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8381 ret
= qemuDomainChangeNet(driver
, vm
, dev
);
8384 case VIR_DOMAIN_DEVICE_FS
:
8385 case VIR_DOMAIN_DEVICE_INPUT
:
8386 case VIR_DOMAIN_DEVICE_SOUND
:
8387 case VIR_DOMAIN_DEVICE_VIDEO
:
8388 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8389 case VIR_DOMAIN_DEVICE_HUB
:
8390 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8391 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8392 case VIR_DOMAIN_DEVICE_NVRAM
:
8393 case VIR_DOMAIN_DEVICE_RNG
:
8394 case VIR_DOMAIN_DEVICE_SHMEM
:
8395 case VIR_DOMAIN_DEVICE_LEASE
:
8396 case VIR_DOMAIN_DEVICE_HOSTDEV
:
8397 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8398 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8399 case VIR_DOMAIN_DEVICE_MEMORY
:
8400 case VIR_DOMAIN_DEVICE_CHR
:
8401 case VIR_DOMAIN_DEVICE_NONE
:
8402 case VIR_DOMAIN_DEVICE_TPM
:
8403 case VIR_DOMAIN_DEVICE_PANIC
:
8404 case VIR_DOMAIN_DEVICE_IOMMU
:
8405 case VIR_DOMAIN_DEVICE_VSOCK
:
8406 case VIR_DOMAIN_DEVICE_LAST
:
8407 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
8408 _("live update of device '%s' is not supported"),
8409 virDomainDeviceTypeToString(dev
->type
));
8417 qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef
,
8418 virDomainDeviceDefPtr dev
,
8420 unsigned int parse_flags
,
8421 virDomainXMLOptionPtr xmlopt
)
8423 virDomainDiskDefPtr disk
;
8424 virDomainNetDefPtr net
;
8425 virDomainHostdevDefPtr hostdev
;
8426 virDomainLeaseDefPtr lease
;
8427 virDomainControllerDefPtr controller
;
8428 virDomainFSDefPtr fs
;
8429 virDomainRedirdevDefPtr redirdev
;
8430 virDomainShmemDefPtr shmem
;
8432 switch ((virDomainDeviceType
)dev
->type
) {
8433 case VIR_DOMAIN_DEVICE_DISK
:
8434 disk
= dev
->data
.disk
;
8435 if (virDomainDiskIndexByName(vmdef
, disk
->dst
, true) >= 0) {
8436 virReportError(VIR_ERR_OPERATION_INVALID
,
8437 _("target %s already exists"), disk
->dst
);
8440 if (virDomainDiskTranslateSourcePool(disk
) < 0)
8442 if (qemuCheckDiskConfig(disk
, NULL
) < 0)
8444 if (virDomainDiskInsert(vmdef
, disk
))
8446 /* vmdef has the pointer. Generic codes for vmdef will do all jobs */
8447 dev
->data
.disk
= NULL
;
8450 case VIR_DOMAIN_DEVICE_NET
:
8451 net
= dev
->data
.net
;
8452 if (virDomainNetInsert(vmdef
, net
))
8454 dev
->data
.net
= NULL
;
8457 case VIR_DOMAIN_DEVICE_HOSTDEV
:
8458 hostdev
= dev
->data
.hostdev
;
8459 if (virDomainHostdevFind(vmdef
, hostdev
, NULL
) >= 0) {
8460 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
8461 _("device is already in the domain configuration"));
8464 if (virDomainHostdevInsert(vmdef
, hostdev
))
8466 dev
->data
.hostdev
= NULL
;
8469 case VIR_DOMAIN_DEVICE_LEASE
:
8470 lease
= dev
->data
.lease
;
8471 if (virDomainLeaseIndex(vmdef
, lease
) >= 0) {
8472 virReportError(VIR_ERR_OPERATION_INVALID
,
8473 _("Lease %s in lockspace %s already exists"),
8474 lease
->key
, NULLSTR(lease
->lockspace
));
8477 if (virDomainLeaseInsert(vmdef
, lease
) < 0)
8480 /* vmdef has the pointer. Generic codes for vmdef will do all jobs */
8481 dev
->data
.lease
= NULL
;
8484 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8485 controller
= dev
->data
.controller
;
8486 if (controller
->idx
!= -1 &&
8487 virDomainControllerFind(vmdef
, controller
->type
,
8488 controller
->idx
) >= 0) {
8489 virReportError(VIR_ERR_OPERATION_INVALID
,
8490 _("controller index='%d' already exists"),
8495 if (virDomainControllerInsert(vmdef
, controller
) < 0)
8497 dev
->data
.controller
= NULL
;
8501 case VIR_DOMAIN_DEVICE_CHR
:
8502 if (qemuDomainChrInsert(vmdef
, dev
->data
.chr
) < 0)
8504 dev
->data
.chr
= NULL
;
8507 case VIR_DOMAIN_DEVICE_FS
:
8509 if (virDomainFSIndexByName(vmdef
, fs
->dst
) >= 0) {
8510 virReportError(VIR_ERR_OPERATION_INVALID
,
8511 "%s", _("Target already exists"));
8515 if (virDomainFSInsert(vmdef
, fs
) < 0)
8517 dev
->data
.fs
= NULL
;
8520 case VIR_DOMAIN_DEVICE_RNG
:
8521 if (dev
->data
.rng
->info
.type
!= VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
&&
8522 virDomainDefHasDeviceAddress(vmdef
, &dev
->data
.rng
->info
)) {
8523 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
8524 _("a device with the same address already exists "));
8528 if (VIR_APPEND_ELEMENT(vmdef
->rngs
, vmdef
->nrngs
, dev
->data
.rng
) < 0)
8530 dev
->data
.rng
= NULL
;
8534 case VIR_DOMAIN_DEVICE_MEMORY
:
8535 if (vmdef
->nmems
== vmdef
->mem
.memory_slots
) {
8536 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
8537 _("no free memory device slot available"));
8541 vmdef
->mem
.cur_balloon
+= dev
->data
.memory
->size
;
8543 if (virDomainMemoryInsert(vmdef
, dev
->data
.memory
) < 0)
8545 dev
->data
.memory
= NULL
;
8548 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8549 redirdev
= dev
->data
.redirdev
;
8551 if (VIR_APPEND_ELEMENT(vmdef
->redirdevs
, vmdef
->nredirdevs
, redirdev
) < 0)
8553 dev
->data
.redirdev
= NULL
;
8556 case VIR_DOMAIN_DEVICE_SHMEM
:
8557 shmem
= dev
->data
.shmem
;
8558 if (virDomainShmemDefFind(vmdef
, shmem
) >= 0) {
8559 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
8560 _("device is already in the domain configuration"));
8563 if (virDomainShmemDefInsert(vmdef
, shmem
) < 0)
8565 dev
->data
.shmem
= NULL
;
8568 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8569 if (vmdef
->watchdog
) {
8570 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
8571 _("domain already has a watchdog"));
8574 VIR_STEAL_PTR(vmdef
->watchdog
, dev
->data
.watchdog
);
8577 case VIR_DOMAIN_DEVICE_INPUT
:
8578 if (VIR_APPEND_ELEMENT(vmdef
->inputs
, vmdef
->ninputs
, dev
->data
.input
) < 0)
8582 case VIR_DOMAIN_DEVICE_VSOCK
:
8584 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
8585 _("domain already has a vsock device"));
8588 VIR_STEAL_PTR(vmdef
->vsock
, dev
->data
.vsock
);
8591 case VIR_DOMAIN_DEVICE_SOUND
:
8592 case VIR_DOMAIN_DEVICE_VIDEO
:
8593 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8594 case VIR_DOMAIN_DEVICE_HUB
:
8595 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8596 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8597 case VIR_DOMAIN_DEVICE_NVRAM
:
8598 case VIR_DOMAIN_DEVICE_NONE
:
8599 case VIR_DOMAIN_DEVICE_TPM
:
8600 case VIR_DOMAIN_DEVICE_PANIC
:
8601 case VIR_DOMAIN_DEVICE_IOMMU
:
8602 case VIR_DOMAIN_DEVICE_LAST
:
8603 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
8604 _("persistent attach of device '%s' is not supported"),
8605 virDomainDeviceTypeToString(dev
->type
));
8609 if (virDomainDefPostParse(vmdef
, caps
, parse_flags
, xmlopt
, NULL
) < 0)
8617 qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef
,
8618 virDomainDeviceDefPtr dev
,
8620 unsigned int parse_flags
,
8621 virDomainXMLOptionPtr xmlopt
)
8623 virDomainDiskDefPtr disk
, det_disk
;
8624 virDomainNetDefPtr net
;
8625 virDomainHostdevDefPtr hostdev
, det_hostdev
;
8626 virDomainLeaseDefPtr lease
, det_lease
;
8627 virDomainControllerDefPtr cont
, det_cont
;
8628 virDomainChrDefPtr chr
;
8629 virDomainFSDefPtr fs
;
8630 virDomainMemoryDefPtr mem
;
8633 switch ((virDomainDeviceType
)dev
->type
) {
8634 case VIR_DOMAIN_DEVICE_DISK
:
8635 disk
= dev
->data
.disk
;
8636 if (!(det_disk
= virDomainDiskRemoveByName(vmdef
, disk
->dst
))) {
8637 virReportError(VIR_ERR_DEVICE_MISSING
,
8638 _("no target device %s"), disk
->dst
);
8641 virDomainDiskDefFree(det_disk
);
8644 case VIR_DOMAIN_DEVICE_NET
:
8645 net
= dev
->data
.net
;
8646 if ((idx
= virDomainNetFindIdx(vmdef
, net
)) < 0)
8649 /* this is guaranteed to succeed */
8650 virDomainNetDefFree(virDomainNetRemove(vmdef
, idx
));
8653 case VIR_DOMAIN_DEVICE_HOSTDEV
: {
8654 hostdev
= dev
->data
.hostdev
;
8655 if ((idx
= virDomainHostdevFind(vmdef
, hostdev
, &det_hostdev
)) < 0) {
8656 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8657 _("device not present in domain configuration"));
8660 virDomainHostdevRemove(vmdef
, idx
);
8661 virDomainHostdevDefFree(det_hostdev
);
8665 case VIR_DOMAIN_DEVICE_LEASE
:
8666 lease
= dev
->data
.lease
;
8667 if (!(det_lease
= virDomainLeaseRemove(vmdef
, lease
))) {
8668 virReportError(VIR_ERR_DEVICE_MISSING
,
8669 _("Lease %s in lockspace %s does not exist"),
8670 lease
->key
, NULLSTR(lease
->lockspace
));
8673 virDomainLeaseDefFree(det_lease
);
8676 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8677 cont
= dev
->data
.controller
;
8678 if ((idx
= virDomainControllerFind(vmdef
, cont
->type
,
8680 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8681 _("device not present in domain configuration"));
8684 det_cont
= virDomainControllerRemove(vmdef
, idx
);
8685 virDomainControllerDefFree(det_cont
);
8689 case VIR_DOMAIN_DEVICE_CHR
:
8690 if (!(chr
= qemuDomainChrRemove(vmdef
, dev
->data
.chr
)))
8693 virDomainChrDefFree(chr
);
8696 case VIR_DOMAIN_DEVICE_FS
:
8698 idx
= virDomainFSIndexByName(vmdef
, fs
->dst
);
8700 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8701 _("no matching filesystem device was found"));
8705 fs
= virDomainFSRemove(vmdef
, idx
);
8706 virDomainFSDefFree(fs
);
8709 case VIR_DOMAIN_DEVICE_RNG
:
8710 if ((idx
= virDomainRNGFind(vmdef
, dev
->data
.rng
)) < 0) {
8711 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8712 _("no matching RNG device was found"));
8716 virDomainRNGDefFree(virDomainRNGRemove(vmdef
, idx
));
8719 case VIR_DOMAIN_DEVICE_MEMORY
:
8720 if ((idx
= virDomainMemoryFindInactiveByDef(vmdef
,
8721 dev
->data
.memory
)) < 0) {
8722 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8723 _("matching memory device was not found"));
8726 mem
= virDomainMemoryRemove(vmdef
, idx
);
8727 vmdef
->mem
.cur_balloon
-= mem
->size
;
8728 virDomainMemoryDefFree(mem
);
8731 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8732 if ((idx
= virDomainRedirdevDefFind(vmdef
,
8733 dev
->data
.redirdev
)) < 0) {
8734 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8735 _("no matching redirdev was not found"));
8739 virDomainRedirdevDefFree(virDomainRedirdevDefRemove(vmdef
, idx
));
8742 case VIR_DOMAIN_DEVICE_SHMEM
:
8743 if ((idx
= virDomainShmemDefFind(vmdef
, dev
->data
.shmem
)) < 0) {
8744 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8745 _("matching shmem device was not found"));
8749 virDomainShmemDefFree(virDomainShmemDefRemove(vmdef
, idx
));
8753 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8754 if (!vmdef
->watchdog
) {
8755 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8756 _("domain has no watchdog"));
8759 virDomainWatchdogDefFree(vmdef
->watchdog
);
8760 vmdef
->watchdog
= NULL
;
8763 case VIR_DOMAIN_DEVICE_INPUT
:
8764 if ((idx
= virDomainInputDefFind(vmdef
, dev
->data
.input
)) < 0) {
8765 virReportError(VIR_ERR_DEVICE_MISSING
, "%s",
8766 _("matching input device not found"));
8769 VIR_DELETE_ELEMENT(vmdef
->inputs
, idx
, vmdef
->ninputs
);
8772 case VIR_DOMAIN_DEVICE_VSOCK
:
8773 if (!vmdef
->vsock
||
8774 !virDomainVsockDefEquals(dev
->data
.vsock
, vmdef
->vsock
)) {
8775 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
8776 _("matching vsock device not found"));
8779 virDomainVsockDefFree(vmdef
->vsock
);
8780 vmdef
->vsock
= NULL
;
8783 case VIR_DOMAIN_DEVICE_SOUND
:
8784 case VIR_DOMAIN_DEVICE_VIDEO
:
8785 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8786 case VIR_DOMAIN_DEVICE_HUB
:
8787 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8788 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8789 case VIR_DOMAIN_DEVICE_NVRAM
:
8790 case VIR_DOMAIN_DEVICE_NONE
:
8791 case VIR_DOMAIN_DEVICE_TPM
:
8792 case VIR_DOMAIN_DEVICE_PANIC
:
8793 case VIR_DOMAIN_DEVICE_IOMMU
:
8794 case VIR_DOMAIN_DEVICE_LAST
:
8795 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
8796 _("persistent detach of device '%s' is not supported"),
8797 virDomainDeviceTypeToString(dev
->type
));
8801 if (virDomainDefPostParse(vmdef
, caps
, parse_flags
, xmlopt
, NULL
) < 0)
8808 qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef
,
8809 virDomainDeviceDefPtr dev
,
8811 unsigned int parse_flags
,
8812 virDomainXMLOptionPtr xmlopt
)
8814 virDomainDiskDefPtr newDisk
;
8815 virDomainGraphicsDefPtr newGraphics
;
8816 virDomainNetDefPtr net
;
8817 virDomainDeviceDef oldDev
= { .type
= dev
->type
};
8820 switch ((virDomainDeviceType
)dev
->type
) {
8821 case VIR_DOMAIN_DEVICE_DISK
:
8822 newDisk
= dev
->data
.disk
;
8823 if ((pos
= virDomainDiskIndexByName(vmdef
, newDisk
->dst
, false)) < 0) {
8824 virReportError(VIR_ERR_INVALID_ARG
,
8825 _("target %s doesn't exist."), newDisk
->dst
);
8829 oldDev
.data
.disk
= vmdef
->disks
[pos
];
8830 if (virDomainDefCompatibleDevice(vmdef
, dev
, &oldDev
,
8831 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8835 virDomainDiskDefFree(vmdef
->disks
[pos
]);
8836 vmdef
->disks
[pos
] = newDisk
;
8837 dev
->data
.disk
= NULL
;
8840 case VIR_DOMAIN_DEVICE_GRAPHICS
:
8841 newGraphics
= dev
->data
.graphics
;
8842 pos
= qemuDomainFindGraphicsIndex(vmdef
, newGraphics
);
8844 virReportError(VIR_ERR_INVALID_ARG
,
8845 _("cannot find existing graphics type '%s' device to modify"),
8846 virDomainGraphicsTypeToString(newGraphics
->type
));
8850 oldDev
.data
.graphics
= vmdef
->graphics
[pos
];
8851 if (virDomainDefCompatibleDevice(vmdef
, dev
, &oldDev
,
8852 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8856 virDomainGraphicsDefFree(vmdef
->graphics
[pos
]);
8857 vmdef
->graphics
[pos
] = newGraphics
;
8858 dev
->data
.graphics
= NULL
;
8861 case VIR_DOMAIN_DEVICE_NET
:
8862 net
= dev
->data
.net
;
8863 if ((pos
= virDomainNetFindIdx(vmdef
, net
)) < 0)
8866 oldDev
.data
.net
= vmdef
->nets
[pos
];
8867 if (virDomainDefCompatibleDevice(vmdef
, dev
, &oldDev
,
8868 VIR_DOMAIN_DEVICE_ACTION_UPDATE
,
8872 virDomainNetDefFree(vmdef
->nets
[pos
]);
8873 vmdef
->nets
[pos
] = net
;
8874 dev
->data
.net
= NULL
;
8877 case VIR_DOMAIN_DEVICE_FS
:
8878 case VIR_DOMAIN_DEVICE_INPUT
:
8879 case VIR_DOMAIN_DEVICE_SOUND
:
8880 case VIR_DOMAIN_DEVICE_VIDEO
:
8881 case VIR_DOMAIN_DEVICE_WATCHDOG
:
8882 case VIR_DOMAIN_DEVICE_HUB
:
8883 case VIR_DOMAIN_DEVICE_SMARTCARD
:
8884 case VIR_DOMAIN_DEVICE_MEMBALLOON
:
8885 case VIR_DOMAIN_DEVICE_NVRAM
:
8886 case VIR_DOMAIN_DEVICE_RNG
:
8887 case VIR_DOMAIN_DEVICE_SHMEM
:
8888 case VIR_DOMAIN_DEVICE_LEASE
:
8889 case VIR_DOMAIN_DEVICE_HOSTDEV
:
8890 case VIR_DOMAIN_DEVICE_CONTROLLER
:
8891 case VIR_DOMAIN_DEVICE_REDIRDEV
:
8892 case VIR_DOMAIN_DEVICE_CHR
:
8893 case VIR_DOMAIN_DEVICE_MEMORY
:
8894 case VIR_DOMAIN_DEVICE_NONE
:
8895 case VIR_DOMAIN_DEVICE_TPM
:
8896 case VIR_DOMAIN_DEVICE_PANIC
:
8897 case VIR_DOMAIN_DEVICE_IOMMU
:
8898 case VIR_DOMAIN_DEVICE_VSOCK
:
8899 case VIR_DOMAIN_DEVICE_LAST
:
8900 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
8901 _("persistent update of device '%s' is not supported"),
8902 virDomainDeviceTypeToString(dev
->type
));
8906 if (virDomainDefPostParse(vmdef
, caps
, parse_flags
, xmlopt
, NULL
) < 0)
8913 qemuDomainAttachDeviceLiveAndConfig(virDomainObjPtr vm
,
8914 virQEMUDriverPtr driver
,
8918 virDomainDefPtr vmdef
= NULL
;
8919 virQEMUDriverConfigPtr cfg
= NULL
;
8920 virDomainDeviceDefPtr devConf
= NULL
;
8921 virDomainDeviceDefPtr devLive
= NULL
;
8923 virCapsPtr caps
= NULL
;
8924 unsigned int parse_flags
= VIR_DOMAIN_DEF_PARSE_INACTIVE
|
8925 VIR_DOMAIN_DEF_PARSE_ABI_UPDATE
;
8927 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
8928 VIR_DOMAIN_AFFECT_CONFIG
, -1);
8930 cfg
= virQEMUDriverGetConfig(driver
);
8932 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
8935 /* The config and live post processing address auto-generation algorithms
8936 * rely on the correct vm->def or vm->newDef being passed, so call the
8937 * device parse based on which definition is in use */
8938 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
8939 vmdef
= virDomainObjCopyPersistentDef(vm
, caps
, driver
->xmlopt
);
8943 if (!(devConf
= virDomainDeviceDefParse(xml
, vmdef
, caps
,
8944 driver
->xmlopt
, parse_flags
)))
8947 if (virDomainDefCompatibleDevice(vmdef
, devConf
, NULL
,
8948 VIR_DOMAIN_DEVICE_ACTION_ATTACH
,
8952 if ((ret
= qemuDomainAttachDeviceConfig(vmdef
, devConf
, caps
,
8954 driver
->xmlopt
)) < 0)
8958 if (flags
& VIR_DOMAIN_AFFECT_LIVE
) {
8959 if (!(devLive
= virDomainDeviceDefParse(xml
, vm
->def
, caps
,
8960 driver
->xmlopt
, parse_flags
)))
8963 if (virDomainDeviceValidateAliasForHotplug(vm
, devLive
, flags
) < 0)
8966 if (virDomainDefCompatibleDevice(vm
->def
, devLive
, NULL
,
8967 VIR_DOMAIN_DEVICE_ACTION_ATTACH
,
8971 if ((ret
= qemuDomainAttachDeviceLive(vm
, devLive
, driver
)) < 0)
8974 * update domain status forcibly because the domain status may be
8975 * changed even if we failed to attach the device. For example,
8976 * a new controller may be created.
8978 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0) {
8984 /* Finally, if no error until here, we can save config. */
8985 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
8986 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, vmdef
);
8988 virDomainObjAssignDef(vm
, vmdef
, false, NULL
);
8994 virDomainDefFree(vmdef
);
8995 virDomainDeviceDefFree(devConf
);
8996 virDomainDeviceDefFree(devLive
);
8997 virObjectUnref(cfg
);
8998 virObjectUnref(caps
);
9004 qemuDomainAttachDeviceFlags(virDomainPtr dom
,
9008 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9009 virDomainObjPtr vm
= NULL
;
9012 virNWFilterReadLockFilterUpdates();
9014 if (!(vm
= qemuDomObjFromDomain(dom
)))
9017 if (virDomainAttachDeviceFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
9020 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9023 if (virDomainObjUpdateModificationImpact(vm
, &flags
) < 0)
9026 if (qemuDomainAttachDeviceLiveAndConfig(vm
, driver
, xml
, flags
) < 0)
9032 qemuDomainObjEndJob(driver
, vm
);
9035 virDomainObjEndAPI(&vm
);
9036 virNWFilterUnlockFilterUpdates();
9040 static int qemuDomainAttachDevice(virDomainPtr dom
, const char *xml
)
9042 return qemuDomainAttachDeviceFlags(dom
, xml
,
9043 VIR_DOMAIN_AFFECT_LIVE
);
9047 static int qemuDomainUpdateDeviceFlags(virDomainPtr dom
,
9051 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9052 virDomainObjPtr vm
= NULL
;
9053 virDomainDefPtr vmdef
= NULL
;
9054 virDomainDeviceDefPtr dev
= NULL
, dev_copy
= NULL
;
9055 bool force
= (flags
& VIR_DOMAIN_DEVICE_MODIFY_FORCE
) != 0;
9057 virQEMUDriverConfigPtr cfg
= NULL
;
9058 virCapsPtr caps
= NULL
;
9059 unsigned int parse_flags
= 0;
9061 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
9062 VIR_DOMAIN_AFFECT_CONFIG
|
9063 VIR_DOMAIN_DEVICE_MODIFY_FORCE
, -1);
9065 virNWFilterReadLockFilterUpdates();
9067 cfg
= virQEMUDriverGetConfig(driver
);
9069 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
9072 if (!(vm
= qemuDomObjFromDomain(dom
)))
9075 if (virDomainUpdateDeviceFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
9078 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9081 if (virDomainObjUpdateModificationImpact(vm
, &flags
) < 0)
9084 if ((flags
& VIR_DOMAIN_AFFECT_CONFIG
) &&
9085 !(flags
& VIR_DOMAIN_AFFECT_LIVE
))
9086 parse_flags
|= VIR_DOMAIN_DEF_PARSE_INACTIVE
;
9088 dev
= dev_copy
= virDomainDeviceDefParse(xml
, vm
->def
,
9089 caps
, driver
->xmlopt
,
9094 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
&&
9095 flags
& VIR_DOMAIN_AFFECT_LIVE
) {
9096 /* If we are affecting both CONFIG and LIVE
9097 * create a deep copy of device as adding
9098 * to CONFIG takes one instance.
9100 dev_copy
= virDomainDeviceDefCopy(dev
, vm
->def
, caps
, driver
->xmlopt
);
9105 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
9106 /* Make a copy for updated domain. */
9107 vmdef
= virDomainObjCopyPersistentDef(vm
, caps
, driver
->xmlopt
);
9111 /* virDomainDefCompatibleDevice call is delayed until we know the
9112 * device we're going to update. */
9113 if ((ret
= qemuDomainUpdateDeviceConfig(vmdef
, dev
, caps
,
9115 driver
->xmlopt
)) < 0)
9119 if (flags
& VIR_DOMAIN_AFFECT_LIVE
) {
9120 /* virDomainDefCompatibleDevice call is delayed until we know the
9121 * device we're going to update. */
9122 if ((ret
= qemuDomainUpdateDeviceLive(vm
, dev_copy
, dom
, force
)) < 0)
9125 * update domain status forcibly because the domain status may be
9126 * changed even if we failed to attach the device. For example,
9127 * a new controller may be created.
9129 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0) {
9135 /* Finally, if no error until here, we can save config. */
9136 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
9137 ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, vmdef
);
9139 virDomainObjAssignDef(vm
, vmdef
, false, NULL
);
9145 qemuDomainObjEndJob(driver
, vm
);
9148 virDomainDefFree(vmdef
);
9149 if (dev
!= dev_copy
)
9150 virDomainDeviceDefFree(dev_copy
);
9151 virDomainDeviceDefFree(dev
);
9152 virDomainObjEndAPI(&vm
);
9153 virObjectUnref(caps
);
9154 virObjectUnref(cfg
);
9155 virNWFilterUnlockFilterUpdates();
9160 qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr driver
,
9165 virCapsPtr caps
= NULL
;
9166 virQEMUDriverConfigPtr cfg
= NULL
;
9167 virDomainDeviceDefPtr dev
= NULL
, dev_copy
= NULL
;
9168 unsigned int parse_flags
= VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
;
9169 virDomainDefPtr vmdef
= NULL
;
9172 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
9173 VIR_DOMAIN_AFFECT_CONFIG
, -1);
9175 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
9178 cfg
= virQEMUDriverGetConfig(driver
);
9180 if ((flags
& VIR_DOMAIN_AFFECT_CONFIG
) &&
9181 !(flags
& VIR_DOMAIN_AFFECT_LIVE
))
9182 parse_flags
|= VIR_DOMAIN_DEF_PARSE_INACTIVE
;
9184 dev
= dev_copy
= virDomainDeviceDefParse(xml
, vm
->def
,
9185 caps
, driver
->xmlopt
,
9190 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
&&
9191 flags
& VIR_DOMAIN_AFFECT_LIVE
) {
9192 /* If we are affecting both CONFIG and LIVE
9193 * create a deep copy of device as adding
9194 * to CONFIG takes one instance.
9196 dev_copy
= virDomainDeviceDefCopy(dev
, vm
->def
, caps
, driver
->xmlopt
);
9201 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
9202 /* Make a copy for updated domain. */
9203 vmdef
= virDomainObjCopyPersistentDef(vm
, caps
, driver
->xmlopt
);
9207 if (qemuDomainDetachDeviceConfig(vmdef
, dev
, caps
,
9209 driver
->xmlopt
) < 0)
9213 if (flags
& VIR_DOMAIN_AFFECT_LIVE
) {
9214 if (qemuDomainDetachDeviceLive(vm
, dev_copy
, driver
, false) < 0)
9217 * update domain status forcibly because the domain status may be
9218 * changed even if we failed to attach the device. For example,
9219 * a new controller may be created.
9221 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, caps
) < 0)
9225 /* Finally, if no error until here, we can save config. */
9226 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
) {
9227 if (virDomainSaveConfig(cfg
->configDir
, caps
, vmdef
) < 0)
9230 virDomainObjAssignDef(vm
, vmdef
, false, NULL
);
9237 virObjectUnref(caps
);
9238 virObjectUnref(cfg
);
9239 if (dev
!= dev_copy
)
9240 virDomainDeviceDefFree(dev_copy
);
9241 virDomainDeviceDefFree(dev
);
9242 virDomainDefFree(vmdef
);
9248 qemuDomainDetachDeviceAliasLiveAndConfig(virQEMUDriverPtr driver
,
9253 virCapsPtr caps
= NULL
;
9254 virQEMUDriverConfigPtr cfg
= NULL
;
9255 virDomainDefPtr def
= NULL
;
9256 virDomainDefPtr persistentDef
= NULL
;
9257 virDomainDefPtr vmdef
= NULL
;
9258 unsigned int parse_flags
= VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
;
9261 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
9262 VIR_DOMAIN_AFFECT_CONFIG
, -1);
9264 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
9267 cfg
= virQEMUDriverGetConfig(driver
);
9269 if ((flags
& VIR_DOMAIN_AFFECT_CONFIG
) &&
9270 !(flags
& VIR_DOMAIN_AFFECT_LIVE
))
9271 parse_flags
|= VIR_DOMAIN_DEF_PARSE_INACTIVE
;
9273 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
9276 if (persistentDef
) {
9277 virDomainDeviceDef dev
;
9279 if (!(vmdef
= virDomainObjCopyPersistentDef(vm
, caps
, driver
->xmlopt
)))
9282 if (virDomainDefFindDevice(vmdef
, alias
, &dev
, true) < 0)
9285 if (qemuDomainDetachDeviceConfig(vmdef
, &dev
, caps
,
9286 parse_flags
, driver
->xmlopt
) < 0)
9291 virDomainDeviceDef dev
;
9293 if (virDomainDefFindDevice(def
, alias
, &dev
, true) < 0)
9296 if (qemuDomainDetachDeviceLive(vm
, &dev
, driver
, true) < 0)
9301 if (virDomainSaveConfig(cfg
->configDir
, caps
, vmdef
) < 0)
9303 virDomainObjAssignDef(vm
, vmdef
, false, NULL
);
9309 virDomainDefFree(vmdef
);
9310 virObjectUnref(cfg
);
9311 virObjectUnref(caps
);
9317 qemuDomainDetachDeviceFlags(virDomainPtr dom
,
9321 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9322 virDomainObjPtr vm
= NULL
;
9325 if (!(vm
= qemuDomObjFromDomain(dom
)))
9328 if (virDomainDetachDeviceFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
9331 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9334 if (virDomainObjUpdateModificationImpact(vm
, &flags
) < 0)
9337 if (qemuDomainDetachDeviceLiveAndConfig(driver
, vm
, xml
, flags
) < 0)
9343 qemuDomainObjEndJob(driver
, vm
);
9346 virDomainObjEndAPI(&vm
);
9352 qemuDomainDetachDeviceAlias(virDomainPtr dom
,
9356 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9357 virDomainObjPtr vm
= NULL
;
9360 if (!(vm
= qemuDomObjFromDomain(dom
)))
9363 if (virDomainDetachDeviceAliasEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
9366 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9369 if (virDomainObjUpdateModificationImpact(vm
, &flags
) < 0)
9372 if (qemuDomainDetachDeviceAliasLiveAndConfig(driver
, vm
, alias
, flags
) < 0)
9378 qemuDomainObjEndJob(driver
, vm
);
9381 virDomainObjEndAPI(&vm
);
9386 static int qemuDomainDetachDevice(virDomainPtr dom
, const char *xml
)
9388 return qemuDomainDetachDeviceFlags(dom
, xml
,
9389 VIR_DOMAIN_AFFECT_LIVE
);
9392 static int qemuDomainGetAutostart(virDomainPtr dom
,
9398 if (!(vm
= qemuDomObjFromDomain(dom
)))
9401 if (virDomainGetAutostartEnsureACL(dom
->conn
, vm
->def
) < 0)
9404 *autostart
= vm
->autostart
;
9408 virDomainObjEndAPI(&vm
);
9412 static int qemuDomainSetAutostart(virDomainPtr dom
,
9415 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9417 char *configFile
= NULL
, *autostartLink
= NULL
;
9419 virQEMUDriverConfigPtr cfg
= NULL
;
9421 if (!(vm
= qemuDomObjFromDomain(dom
)))
9424 cfg
= virQEMUDriverGetConfig(driver
);
9426 if (virDomainSetAutostartEnsureACL(dom
->conn
, vm
->def
) < 0)
9429 if (!vm
->persistent
) {
9430 virReportError(VIR_ERR_OPERATION_INVALID
,
9431 "%s", _("cannot set autostart for transient domain"));
9435 autostart
= (autostart
!= 0);
9437 if (vm
->autostart
!= autostart
) {
9438 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9441 if (!(configFile
= virDomainConfigFile(cfg
->configDir
, vm
->def
->name
)))
9444 if (!(autostartLink
= virDomainConfigFile(cfg
->autostartDir
,
9449 if (virFileMakePath(cfg
->autostartDir
) < 0) {
9450 virReportSystemError(errno
,
9451 _("cannot create autostart directory %s"),
9456 if (symlink(configFile
, autostartLink
) < 0) {
9457 virReportSystemError(errno
,
9458 _("Failed to create symlink '%s to '%s'"),
9459 autostartLink
, configFile
);
9463 if (unlink(autostartLink
) < 0 &&
9466 virReportSystemError(errno
,
9467 _("Failed to delete symlink '%s'"),
9473 vm
->autostart
= autostart
;
9476 qemuDomainObjEndJob(driver
, vm
);
9481 VIR_FREE(configFile
);
9482 VIR_FREE(autostartLink
);
9483 virDomainObjEndAPI(&vm
);
9484 virObjectUnref(cfg
);
9489 static char *qemuDomainGetSchedulerType(virDomainPtr dom
,
9493 virDomainObjPtr vm
= NULL
;
9494 qemuDomainObjPrivatePtr priv
;
9495 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9497 if (!(vm
= qemuDomObjFromDomain(dom
)))
9500 priv
= vm
->privateData
;
9502 if (virDomainGetSchedulerTypeEnsureACL(dom
->conn
, vm
->def
) < 0)
9505 if (!virQEMUDriverIsPrivileged(driver
)) {
9506 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
9507 _("CPU tuning is not available in session mode"));
9511 /* Domain not running, thus no cgroups - return defaults */
9512 if (!virDomainObjIsActive(vm
)) {
9515 ignore_value(VIR_STRDUP(ret
, "posix"));
9519 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPU
)) {
9520 virReportError(VIR_ERR_OPERATION_INVALID
,
9521 "%s", _("cgroup CPU controller is not mounted"));
9526 if (virCgroupSupportsCpuBW(priv
->cgroup
))
9532 ignore_value(VIR_STRDUP(ret
, "posix"));
9535 virDomainObjEndAPI(&vm
);
9539 /* blkioDeviceStr in the form of /device/path,weight,/device/path,weight
9540 * for example, /dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0,800
9543 qemuDomainParseBlkioDeviceStr(char *blkioDeviceStr
, const char *type
,
9544 virBlkioDevicePtr
*dev
, size_t *size
)
9550 virBlkioDevicePtr result
= NULL
;
9555 if (STREQ(blkioDeviceStr
, ""))
9558 temp
= blkioDeviceStr
;
9560 temp
= strchr(temp
, ',');
9567 /* A valid string must have even number of fields, hence an odd
9568 * number of commas. */
9572 ndevices
= (nsep
+ 1) / 2;
9574 if (VIR_ALLOC_N(result
, ndevices
) < 0)
9578 temp
= blkioDeviceStr
;
9587 if (VIR_STRNDUP(result
[i
].path
, temp
, p
- temp
) < 0)
9593 if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
)) {
9594 if (virStrToLong_uip(temp
, &p
, 10, &result
[i
].weight
) < 0)
9596 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
)) {
9597 if (virStrToLong_uip(temp
, &p
, 10, &result
[i
].riops
) < 0)
9599 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
)) {
9600 if (virStrToLong_uip(temp
, &p
, 10, &result
[i
].wiops
) < 0)
9602 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
)) {
9603 if (virStrToLong_ullp(temp
, &p
, 10, &result
[i
].rbps
) < 0)
9605 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9606 if (virStrToLong_ullp(temp
, &p
, 10, &result
[i
].wbps
) < 0)
9609 virReportError(VIR_ERR_INVALID_ARG
,
9610 _("unknown parameter '%s'"), type
);
9632 virReportError(VIR_ERR_INVALID_ARG
,
9633 _("unable to parse blkio device '%s' '%s'"),
9634 type
, blkioDeviceStr
);
9638 virReportError(VIR_ERR_INVALID_ARG
,
9639 _("invalid value '%s' for parameter '%s' of device '%s'"),
9640 temp
, type
, result
[i
].path
);
9644 virBlkioDeviceArrayClear(result
, ndevices
);
9650 /* Modify dest_array to reflect all blkio device changes described in
9653 qemuDomainMergeBlkioDevice(virBlkioDevicePtr
*dest_array
,
9655 virBlkioDevicePtr src_array
,
9660 virBlkioDevicePtr dest
, src
;
9662 for (i
= 0; i
< src_size
; i
++) {
9665 src
= &src_array
[i
];
9666 for (j
= 0; j
< *dest_size
; j
++) {
9667 dest
= &(*dest_array
)[j
];
9668 if (STREQ(src
->path
, dest
->path
)) {
9671 if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
)) {
9672 dest
->weight
= src
->weight
;
9673 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
)) {
9674 dest
->riops
= src
->riops
;
9675 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
)) {
9676 dest
->wiops
= src
->wiops
;
9677 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
)) {
9678 dest
->rbps
= src
->rbps
;
9679 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9680 dest
->wbps
= src
->wbps
;
9682 virReportError(VIR_ERR_INVALID_ARG
, _("Unknown parameter %s"),
9690 if (!src
->weight
&& !src
->riops
&& !src
->wiops
&& !src
->rbps
&& !src
->wbps
)
9692 if (VIR_EXPAND_N(*dest_array
, *dest_size
, 1) < 0)
9694 dest
= &(*dest_array
)[*dest_size
- 1];
9696 if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
)) {
9697 dest
->weight
= src
->weight
;
9698 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
)) {
9699 dest
->riops
= src
->riops
;
9700 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
)) {
9701 dest
->wiops
= src
->wiops
;
9702 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
)) {
9703 dest
->rbps
= src
->rbps
;
9704 } else if (STREQ(type
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9705 dest
->wbps
= src
->wbps
;
9707 *dest_size
= *dest_size
- 1;
9711 dest
->path
= src
->path
;
9720 qemuDomainSetBlkioParameters(virDomainPtr dom
,
9721 virTypedParameterPtr params
,
9725 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9727 virDomainObjPtr vm
= NULL
;
9728 virDomainDefPtr def
;
9729 virDomainDefPtr persistentDef
;
9731 virQEMUDriverConfigPtr cfg
= NULL
;
9732 qemuDomainObjPrivatePtr priv
;
9734 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
9735 VIR_DOMAIN_AFFECT_CONFIG
, -1);
9736 if (virTypedParamsValidate(params
, nparams
,
9737 VIR_DOMAIN_BLKIO_WEIGHT
,
9738 VIR_TYPED_PARAM_UINT
,
9739 VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
,
9740 VIR_TYPED_PARAM_STRING
,
9741 VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
,
9742 VIR_TYPED_PARAM_STRING
,
9743 VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
,
9744 VIR_TYPED_PARAM_STRING
,
9745 VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
,
9746 VIR_TYPED_PARAM_STRING
,
9747 VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
,
9748 VIR_TYPED_PARAM_STRING
,
9752 if (!(vm
= qemuDomObjFromDomain(dom
)))
9755 priv
= vm
->privateData
;
9756 cfg
= virQEMUDriverGetConfig(driver
);
9758 if (virDomainSetBlkioParametersEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
9761 if (!virQEMUDriverIsPrivileged(driver
)) {
9762 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
9763 _("Block I/O tuning is not available in session mode"));
9767 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
9770 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
9773 if (flags
& VIR_DOMAIN_AFFECT_LIVE
) {
9774 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_BLKIO
)) {
9775 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
9776 _("blkio cgroup isn't mounted"));
9783 for (i
= 0; i
< nparams
; i
++) {
9784 virTypedParameterPtr param
= ¶ms
[i
];
9786 if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_WEIGHT
)) {
9787 if (virCgroupSetBlkioWeight(priv
->cgroup
, param
->value
.ui
) < 0 ||
9788 virCgroupGetBlkioWeight(priv
->cgroup
, &def
->blkio
.weight
) < 0)
9790 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
) ||
9791 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
) ||
9792 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
) ||
9793 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
) ||
9794 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9796 virBlkioDevicePtr devices
= NULL
;
9799 if (qemuDomainParseBlkioDeviceStr(param
->value
.s
,
9807 if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
)) {
9808 for (j
= 0; j
< ndevices
; j
++) {
9809 if (virCgroupSetBlkioDeviceWeight(priv
->cgroup
,
9811 devices
[j
].weight
) < 0 ||
9812 virCgroupGetBlkioDeviceWeight(priv
->cgroup
,
9814 &devices
[j
].weight
) < 0) {
9819 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
)) {
9820 for (j
= 0; j
< ndevices
; j
++) {
9821 if (virCgroupSetBlkioDeviceReadIops(priv
->cgroup
,
9823 devices
[j
].riops
) < 0 ||
9824 virCgroupGetBlkioDeviceReadIops(priv
->cgroup
,
9826 &devices
[j
].riops
) < 0) {
9831 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
)) {
9832 for (j
= 0; j
< ndevices
; j
++) {
9833 if (virCgroupSetBlkioDeviceWriteIops(priv
->cgroup
,
9835 devices
[j
].wiops
) < 0 ||
9836 virCgroupGetBlkioDeviceWriteIops(priv
->cgroup
,
9838 &devices
[j
].wiops
) < 0) {
9843 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
)) {
9844 for (j
= 0; j
< ndevices
; j
++) {
9845 if (virCgroupSetBlkioDeviceReadBps(priv
->cgroup
,
9847 devices
[j
].rbps
) < 0 ||
9848 virCgroupGetBlkioDeviceReadBps(priv
->cgroup
,
9850 &devices
[j
].rbps
) < 0) {
9855 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9856 for (j
= 0; j
< ndevices
; j
++) {
9857 if (virCgroupSetBlkioDeviceWriteBps(priv
->cgroup
,
9859 devices
[j
].wbps
) < 0 ||
9860 virCgroupGetBlkioDeviceWriteBps(priv
->cgroup
,
9862 &devices
[j
].wbps
) < 0) {
9868 virReportError(VIR_ERR_INVALID_ARG
, _("Unknown blkio parameter %s"),
9871 virBlkioDeviceArrayClear(devices
, ndevices
);
9877 if (j
!= ndevices
||
9878 qemuDomainMergeBlkioDevice(&def
->blkio
.devices
,
9879 &def
->blkio
.ndevices
,
9880 devices
, ndevices
, param
->field
) < 0)
9882 virBlkioDeviceArrayClear(devices
, ndevices
);
9887 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
9892 if (persistentDef
) {
9893 for (i
= 0; i
< nparams
; i
++) {
9894 virTypedParameterPtr param
= ¶ms
[i
];
9896 if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_WEIGHT
)) {
9897 persistentDef
->blkio
.weight
= param
->value
.ui
;
9898 } else if (STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT
) ||
9899 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS
) ||
9900 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS
) ||
9901 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS
) ||
9902 STREQ(param
->field
, VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS
)) {
9903 virBlkioDevicePtr devices
= NULL
;
9906 if (qemuDomainParseBlkioDeviceStr(param
->value
.s
,
9913 if (qemuDomainMergeBlkioDevice(&persistentDef
->blkio
.devices
,
9914 &persistentDef
->blkio
.ndevices
,
9915 devices
, ndevices
, param
->field
) < 0)
9917 virBlkioDeviceArrayClear(devices
, ndevices
);
9922 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
9927 qemuDomainObjEndJob(driver
, vm
);
9930 virDomainObjEndAPI(&vm
);
9931 virObjectUnref(cfg
);
9937 qemuDomainGetBlkioParameters(virDomainPtr dom
,
9938 virTypedParameterPtr params
,
9942 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
9943 virDomainObjPtr vm
= NULL
;
9944 virDomainDefPtr def
= NULL
;
9945 virDomainDefPtr persistentDef
= NULL
;
9946 int maxparams
= QEMU_NB_BLKIO_PARAM
;
9949 qemuDomainObjPrivatePtr priv
;
9951 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
9952 VIR_DOMAIN_AFFECT_CONFIG
|
9953 VIR_TYPED_PARAM_STRING_OKAY
, -1);
9955 /* We blindly return a string, and let libvirt.c and
9956 * remote_driver.c do the filtering on behalf of older clients
9957 * that can't parse it. */
9958 flags
&= ~VIR_TYPED_PARAM_STRING_OKAY
;
9960 if (!(vm
= qemuDomObjFromDomain(dom
)))
9963 priv
= vm
->privateData
;
9965 if (virDomainGetBlkioParametersEnsureACL(dom
->conn
, vm
->def
) < 0)
9968 if (!virQEMUDriverIsPrivileged(driver
)) {
9969 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
9970 _("Block I/O tuning is not available in session mode"));
9974 if ((*nparams
) == 0) {
9975 /* Current number of blkio parameters supported by cgroups */
9976 *nparams
= QEMU_NB_BLKIO_PARAM
;
9979 } else if (*nparams
< maxparams
) {
9980 maxparams
= *nparams
;
9985 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
9989 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_BLKIO
)) {
9990 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
9991 _("blkio cgroup isn't mounted"));
9995 /* fill blkio weight here */
9996 if (virCgroupGetBlkioWeight(priv
->cgroup
, &val
) < 0)
9998 if (virTypedParameterAssign(&(params
[(*nparams
)++]),
9999 VIR_DOMAIN_BLKIO_WEIGHT
,
10000 VIR_TYPED_PARAM_UINT
, val
) < 0)
10003 if (virDomainGetBlkioParametersAssignFromDef(def
, params
, nparams
,
10007 } else if (persistentDef
) {
10008 /* fill blkio weight here */
10009 if (virTypedParameterAssign(&(params
[(*nparams
)++]),
10010 VIR_DOMAIN_BLKIO_WEIGHT
,
10011 VIR_TYPED_PARAM_UINT
,
10012 persistentDef
->blkio
.weight
) < 0)
10015 if (virDomainGetBlkioParametersAssignFromDef(persistentDef
, params
,
10016 nparams
, maxparams
) < 0)
10023 virDomainObjEndAPI(&vm
);
10028 qemuDomainSetMemoryParameters(virDomainPtr dom
,
10029 virTypedParameterPtr params
,
10031 unsigned int flags
)
10033 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10034 virDomainDefPtr def
= NULL
;
10035 virDomainDefPtr persistentDef
= NULL
;
10036 virDomainObjPtr vm
= NULL
;
10037 unsigned long long swap_hard_limit
;
10038 unsigned long long hard_limit
= 0;
10039 unsigned long long soft_limit
= 0;
10040 bool set_swap_hard_limit
= false;
10041 bool set_hard_limit
= false;
10042 bool set_soft_limit
= false;
10043 virQEMUDriverConfigPtr cfg
= NULL
;
10046 qemuDomainObjPrivatePtr priv
;
10048 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10049 VIR_DOMAIN_AFFECT_CONFIG
, -1);
10051 if (virTypedParamsValidate(params
, nparams
,
10052 VIR_DOMAIN_MEMORY_HARD_LIMIT
,
10053 VIR_TYPED_PARAM_ULLONG
,
10054 VIR_DOMAIN_MEMORY_SOFT_LIMIT
,
10055 VIR_TYPED_PARAM_ULLONG
,
10056 VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT
,
10057 VIR_TYPED_PARAM_ULLONG
,
10062 if (!(vm
= qemuDomObjFromDomain(dom
)))
10065 priv
= vm
->privateData
;
10066 cfg
= virQEMUDriverGetConfig(driver
);
10068 if (virDomainSetMemoryParametersEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
10071 if (!virQEMUDriverIsPrivileged(driver
)) {
10072 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
10073 _("Memory tuning is not available in session mode"));
10077 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
10080 /* QEMU and LXC implementation are identical */
10081 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
10085 !virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_MEMORY
)) {
10086 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
10087 _("cgroup memory controller is not mounted"));
10091 #define VIR_GET_LIMIT_PARAMETER(PARAM, VALUE) \
10092 if ((rc = virTypedParamsGetULLong(params, nparams, PARAM, &VALUE)) < 0) \
10096 set_ ## VALUE = true;
10098 VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT
, swap_hard_limit
)
10099 VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_HARD_LIMIT
, hard_limit
)
10100 VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_SOFT_LIMIT
, soft_limit
)
10102 #undef VIR_GET_LIMIT_PARAMETER
10104 /* Swap hard limit must be greater than hard limit. */
10105 if (set_swap_hard_limit
|| set_hard_limit
) {
10106 unsigned long long mem_limit
= vm
->def
->mem
.hard_limit
;
10107 unsigned long long swap_limit
= vm
->def
->mem
.swap_hard_limit
;
10109 if (set_swap_hard_limit
)
10110 swap_limit
= swap_hard_limit
;
10112 if (set_hard_limit
)
10113 mem_limit
= hard_limit
;
10115 if (mem_limit
> swap_limit
) {
10116 virReportError(VIR_ERR_INVALID_ARG
, "%s",
10117 _("memory hard_limit tunable value must be lower "
10118 "than or equal to swap_hard_limit"));
10123 #define VIR_SET_MEM_PARAMETER(FUNC, VALUE) \
10124 if (set_ ## VALUE) { \
10126 if ((rc = FUNC(priv->cgroup, VALUE)) < 0) \
10128 def->mem.VALUE = VALUE; \
10131 if (persistentDef) \
10132 persistentDef->mem.VALUE = VALUE; \
10135 /* Soft limit doesn't clash with the others */
10136 VIR_SET_MEM_PARAMETER(virCgroupSetMemorySoftLimit
, soft_limit
);
10138 /* set hard limit before swap hard limit if decreasing it */
10139 if (def
&& def
->mem
.hard_limit
> hard_limit
) {
10140 VIR_SET_MEM_PARAMETER(virCgroupSetMemoryHardLimit
, hard_limit
);
10141 /* inhibit changing the limit a second time */
10142 set_hard_limit
= false;
10145 VIR_SET_MEM_PARAMETER(virCgroupSetMemSwapHardLimit
, swap_hard_limit
);
10147 /* otherwise increase it after swap hard limit */
10148 VIR_SET_MEM_PARAMETER(virCgroupSetMemoryHardLimit
, hard_limit
);
10150 #undef VIR_SET_MEM_PARAMETER
10153 virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
10156 if (persistentDef
&&
10157 virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
10159 /* QEMU and LXC implementations are identical */
10164 qemuDomainObjEndJob(driver
, vm
);
10167 virDomainObjEndAPI(&vm
);
10168 virObjectUnref(cfg
);
10173 #define QEMU_ASSIGN_MEM_PARAM(index, name, value) \
10174 if (index < *nparams && \
10175 virTypedParameterAssign(¶ms[index], name, VIR_TYPED_PARAM_ULLONG, \
10180 qemuDomainGetMemoryParameters(virDomainPtr dom
,
10181 virTypedParameterPtr params
,
10183 unsigned int flags
)
10185 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10186 virDomainObjPtr vm
= NULL
;
10187 virDomainDefPtr persistentDef
= NULL
;
10189 qemuDomainObjPrivatePtr priv
;
10190 unsigned long long swap_hard_limit
, mem_hard_limit
, mem_soft_limit
;
10192 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10193 VIR_DOMAIN_AFFECT_CONFIG
|
10194 VIR_TYPED_PARAM_STRING_OKAY
, -1);
10196 if (!(vm
= qemuDomObjFromDomain(dom
)))
10199 priv
= vm
->privateData
;
10201 if (virDomainGetMemoryParametersEnsureACL(dom
->conn
, vm
->def
) < 0)
10204 if (!virQEMUDriverIsPrivileged(driver
)) {
10205 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
10206 _("Memory tuning is not available in session mode"));
10210 if (virDomainObjGetDefs(vm
, flags
, NULL
, &persistentDef
) < 0)
10213 if ((*nparams
) == 0) {
10214 /* Current number of memory parameters supported by cgroups */
10215 *nparams
= QEMU_NB_MEM_PARAM
;
10220 if (persistentDef
) {
10221 mem_hard_limit
= persistentDef
->mem
.hard_limit
;
10222 mem_soft_limit
= persistentDef
->mem
.soft_limit
;
10223 swap_hard_limit
= persistentDef
->mem
.swap_hard_limit
;
10225 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_MEMORY
)) {
10226 virReportError(VIR_ERR_OPERATION_INVALID
,
10227 "%s", _("cgroup memory controller is not mounted"));
10231 if (virCgroupGetMemoryHardLimit(priv
->cgroup
, &mem_hard_limit
) < 0)
10234 if (virCgroupGetMemorySoftLimit(priv
->cgroup
, &mem_soft_limit
) < 0)
10237 if (virCgroupGetMemSwapHardLimit(priv
->cgroup
, &swap_hard_limit
) < 0) {
10238 if (!virLastErrorIsSystemErrno(ENOENT
) &&
10239 !virLastErrorIsSystemErrno(EOPNOTSUPP
))
10241 swap_hard_limit
= VIR_DOMAIN_MEMORY_PARAM_UNLIMITED
;
10245 QEMU_ASSIGN_MEM_PARAM(0, VIR_DOMAIN_MEMORY_HARD_LIMIT
, mem_hard_limit
);
10246 QEMU_ASSIGN_MEM_PARAM(1, VIR_DOMAIN_MEMORY_SOFT_LIMIT
, mem_soft_limit
);
10247 QEMU_ASSIGN_MEM_PARAM(2, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT
, swap_hard_limit
);
10249 if (QEMU_NB_MEM_PARAM
< *nparams
)
10250 *nparams
= QEMU_NB_MEM_PARAM
;
10254 virDomainObjEndAPI(&vm
);
10257 #undef QEMU_ASSIGN_MEM_PARAM
10260 qemuDomainSetNumaParamsLive(virDomainObjPtr vm
,
10261 virBitmapPtr nodeset
)
10263 virCgroupPtr cgroup_temp
= NULL
;
10264 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
10265 char *nodeset_str
= NULL
;
10266 virDomainNumatuneMemMode mode
;
10270 if (virDomainNumatuneGetMode(vm
->def
->numa
, -1, &mode
) == 0 &&
10271 mode
!= VIR_DOMAIN_NUMATUNE_MEM_STRICT
) {
10272 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
10273 _("change of nodeset for running domain "
10274 "requires strict numa mode"));
10278 if (!virNumaNodesetIsAvailable(nodeset
))
10281 /* Ensure the cpuset string is formatted before passing to cgroup */
10282 if (!(nodeset_str
= virBitmapFormat(nodeset
)))
10285 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_EMULATOR
, 0,
10286 false, &cgroup_temp
) < 0 ||
10287 virCgroupSetCpusetMems(cgroup_temp
, nodeset_str
) < 0)
10289 virCgroupFree(&cgroup_temp
);
10291 for (i
= 0; i
< virDomainDefGetVcpusMax(vm
->def
); i
++) {
10292 virDomainVcpuDefPtr vcpu
= virDomainDefGetVcpu(vm
->def
, i
);
10297 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_VCPU
, i
,
10298 false, &cgroup_temp
) < 0 ||
10299 virCgroupSetCpusetMems(cgroup_temp
, nodeset_str
) < 0)
10301 virCgroupFree(&cgroup_temp
);
10304 for (i
= 0; i
< vm
->def
->niothreadids
; i
++) {
10305 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_IOTHREAD
,
10306 vm
->def
->iothreadids
[i
]->iothread_id
,
10307 false, &cgroup_temp
) < 0 ||
10308 virCgroupSetCpusetMems(cgroup_temp
, nodeset_str
) < 0)
10310 virCgroupFree(&cgroup_temp
);
10315 VIR_FREE(nodeset_str
);
10316 virCgroupFree(&cgroup_temp
);
10322 qemuDomainSetNumaParameters(virDomainPtr dom
,
10323 virTypedParameterPtr params
,
10325 unsigned int flags
)
10327 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10329 virDomainDefPtr def
;
10330 virDomainDefPtr persistentDef
;
10331 virDomainObjPtr vm
= NULL
;
10333 virQEMUDriverConfigPtr cfg
= NULL
;
10334 qemuDomainObjPrivatePtr priv
;
10335 virBitmapPtr nodeset
= NULL
;
10336 virDomainNumatuneMemMode config_mode
;
10339 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10340 VIR_DOMAIN_AFFECT_CONFIG
, -1);
10342 if (virTypedParamsValidate(params
, nparams
,
10343 VIR_DOMAIN_NUMA_MODE
,
10344 VIR_TYPED_PARAM_INT
,
10345 VIR_DOMAIN_NUMA_NODESET
,
10346 VIR_TYPED_PARAM_STRING
,
10350 if (!(vm
= qemuDomObjFromDomain(dom
)))
10353 priv
= vm
->privateData
;
10354 cfg
= virQEMUDriverGetConfig(driver
);
10356 if (virDomainSetNumaParametersEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
10359 for (i
= 0; i
< nparams
; i
++) {
10360 virTypedParameterPtr param
= ¶ms
[i
];
10362 if (STREQ(param
->field
, VIR_DOMAIN_NUMA_MODE
)) {
10363 mode
= param
->value
.i
;
10365 if (mode
< 0 || mode
>= VIR_DOMAIN_NUMATUNE_MEM_LAST
) {
10366 virReportError(VIR_ERR_INVALID_ARG
,
10367 _("unsupported numatune mode: '%d'"), mode
);
10371 } else if (STREQ(param
->field
, VIR_DOMAIN_NUMA_NODESET
)) {
10372 if (virBitmapParse(param
->value
.s
, &nodeset
,
10373 VIR_DOMAIN_CPUMASK_LEN
) < 0)
10376 if (virBitmapIsAllClear(nodeset
)) {
10377 virReportError(VIR_ERR_OPERATION_INVALID
,
10378 _("Invalid nodeset of 'numatune': %s"),
10385 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
10388 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
10392 if (!virQEMUDriverIsPrivileged(driver
)) {
10393 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
10394 _("NUMA tuning is not available in session mode"));
10398 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPUSET
)) {
10399 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
10400 _("cgroup cpuset controller is not mounted"));
10405 virDomainNumatuneGetMode(def
->numa
, -1, &config_mode
) == 0 &&
10406 config_mode
!= mode
) {
10407 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
10408 _("can't change numatune mode for running domain"));
10413 qemuDomainSetNumaParamsLive(vm
, nodeset
) < 0)
10416 if (virDomainNumatuneSet(def
->numa
,
10417 def
->placement_mode
==
10418 VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC
,
10419 -1, mode
, nodeset
) < 0)
10422 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
10426 if (persistentDef
) {
10427 if (virDomainNumatuneSet(persistentDef
->numa
,
10428 persistentDef
->placement_mode
==
10429 VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC
,
10430 -1, mode
, nodeset
) < 0)
10433 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
10440 qemuDomainObjEndJob(driver
, vm
);
10443 virBitmapFree(nodeset
);
10444 virDomainObjEndAPI(&vm
);
10445 virObjectUnref(cfg
);
10450 qemuDomainGetNumaParameters(virDomainPtr dom
,
10451 virTypedParameterPtr params
,
10453 unsigned int flags
)
10456 virDomainObjPtr vm
= NULL
;
10457 virDomainNumatuneMemMode tmpmode
= VIR_DOMAIN_NUMATUNE_MEM_STRICT
;
10458 qemuDomainObjPrivatePtr priv
;
10459 char *nodeset
= NULL
;
10461 virDomainDefPtr def
= NULL
;
10463 virBitmapPtr autoNodeset
= NULL
;
10465 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10466 VIR_DOMAIN_AFFECT_CONFIG
|
10467 VIR_TYPED_PARAM_STRING_OKAY
, -1);
10469 if (!(vm
= qemuDomObjFromDomain(dom
)))
10471 priv
= vm
->privateData
;
10473 if (virDomainGetNumaParametersEnsureACL(dom
->conn
, vm
->def
) < 0)
10476 if (!(def
= virDomainObjGetOneDefState(vm
, flags
, &live
)))
10480 autoNodeset
= priv
->autoNodeset
;
10482 if ((*nparams
) == 0) {
10483 *nparams
= QEMU_NB_NUMA_PARAM
;
10488 for (i
= 0; i
< QEMU_NB_NUMA_PARAM
&& i
< *nparams
; i
++) {
10489 virMemoryParameterPtr param
= ¶ms
[i
];
10492 case 0: /* fill numa mode here */
10493 ignore_value(virDomainNumatuneGetMode(def
->numa
, -1, &tmpmode
));
10495 if (virTypedParameterAssign(param
, VIR_DOMAIN_NUMA_MODE
,
10496 VIR_TYPED_PARAM_INT
, tmpmode
) < 0)
10501 case 1: /* fill numa nodeset here */
10502 nodeset
= virDomainNumatuneFormatNodeset(def
->numa
, autoNodeset
, -1);
10504 virTypedParameterAssign(param
, VIR_DOMAIN_NUMA_NODESET
,
10505 VIR_TYPED_PARAM_STRING
, nodeset
) < 0)
10511 /* coverity[dead_error_begin] */
10514 /* should not hit here */
10518 if (*nparams
> QEMU_NB_NUMA_PARAM
)
10519 *nparams
= QEMU_NB_NUMA_PARAM
;
10524 virDomainObjEndAPI(&vm
);
10529 qemuSetGlobalBWLive(virCgroupPtr cgroup
, unsigned long long period
,
10532 if (period
== 0 && quota
== 0)
10535 if (qemuSetupCgroupVcpuBW(cgroup
, period
, quota
) < 0)
10542 qemuDomainSetPerfEvents(virDomainPtr dom
,
10543 virTypedParameterPtr params
,
10545 unsigned int flags
)
10547 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10549 virDomainObjPtr vm
= NULL
;
10550 virQEMUDriverConfigPtr cfg
= NULL
;
10551 qemuDomainObjPrivatePtr priv
;
10552 virDomainDefPtr def
;
10553 virDomainDefPtr persistentDef
;
10555 virPerfEventType type
;
10558 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10559 VIR_DOMAIN_AFFECT_CONFIG
, -1);
10561 if (virTypedParamsValidate(params
, nparams
,
10562 VIR_PERF_PARAM_CMT
, VIR_TYPED_PARAM_BOOLEAN
,
10563 VIR_PERF_PARAM_MBMT
, VIR_TYPED_PARAM_BOOLEAN
,
10564 VIR_PERF_PARAM_MBML
, VIR_TYPED_PARAM_BOOLEAN
,
10565 VIR_PERF_PARAM_CPU_CYCLES
, VIR_TYPED_PARAM_BOOLEAN
,
10566 VIR_PERF_PARAM_INSTRUCTIONS
, VIR_TYPED_PARAM_BOOLEAN
,
10567 VIR_PERF_PARAM_CACHE_REFERENCES
, VIR_TYPED_PARAM_BOOLEAN
,
10568 VIR_PERF_PARAM_CACHE_MISSES
, VIR_TYPED_PARAM_BOOLEAN
,
10569 VIR_PERF_PARAM_BRANCH_INSTRUCTIONS
, VIR_TYPED_PARAM_BOOLEAN
,
10570 VIR_PERF_PARAM_BRANCH_MISSES
, VIR_TYPED_PARAM_BOOLEAN
,
10571 VIR_PERF_PARAM_BUS_CYCLES
, VIR_TYPED_PARAM_BOOLEAN
,
10572 VIR_PERF_PARAM_STALLED_CYCLES_FRONTEND
, VIR_TYPED_PARAM_BOOLEAN
,
10573 VIR_PERF_PARAM_STALLED_CYCLES_BACKEND
, VIR_TYPED_PARAM_BOOLEAN
,
10574 VIR_PERF_PARAM_REF_CPU_CYCLES
, VIR_TYPED_PARAM_BOOLEAN
,
10575 VIR_PERF_PARAM_CPU_CLOCK
, VIR_TYPED_PARAM_BOOLEAN
,
10576 VIR_PERF_PARAM_TASK_CLOCK
, VIR_TYPED_PARAM_BOOLEAN
,
10577 VIR_PERF_PARAM_PAGE_FAULTS
, VIR_TYPED_PARAM_BOOLEAN
,
10578 VIR_PERF_PARAM_CONTEXT_SWITCHES
, VIR_TYPED_PARAM_BOOLEAN
,
10579 VIR_PERF_PARAM_CPU_MIGRATIONS
, VIR_TYPED_PARAM_BOOLEAN
,
10580 VIR_PERF_PARAM_PAGE_FAULTS_MIN
, VIR_TYPED_PARAM_BOOLEAN
,
10581 VIR_PERF_PARAM_PAGE_FAULTS_MAJ
, VIR_TYPED_PARAM_BOOLEAN
,
10582 VIR_PERF_PARAM_ALIGNMENT_FAULTS
, VIR_TYPED_PARAM_BOOLEAN
,
10583 VIR_PERF_PARAM_EMULATION_FAULTS
, VIR_TYPED_PARAM_BOOLEAN
,
10587 if (!(vm
= qemuDomObjFromDomain(dom
)))
10590 cfg
= virQEMUDriverGetConfig(driver
);
10591 priv
= vm
->privateData
;
10593 if (virDomainSetPerfEventsEnsureACL(dom
->conn
, vm
->def
) < 0)
10596 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
10599 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
10603 for (i
= 0; i
< nparams
; i
++) {
10604 virTypedParameterPtr param
= ¶ms
[i
];
10605 enabled
= param
->value
.b
;
10606 type
= virPerfEventTypeFromString(param
->field
);
10608 if (!enabled
&& virPerfEventDisable(priv
->perf
, type
) < 0)
10610 if (enabled
&& virPerfEventEnable(priv
->perf
, type
, vm
->pid
) < 0)
10613 def
->perf
.events
[type
] = enabled
?
10614 VIR_TRISTATE_BOOL_YES
: VIR_TRISTATE_BOOL_NO
;
10617 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
10621 if (persistentDef
) {
10622 for (i
= 0; i
< nparams
; i
++) {
10623 virTypedParameterPtr param
= ¶ms
[i
];
10624 enabled
= param
->value
.b
;
10625 type
= virPerfEventTypeFromString(param
->field
);
10627 persistentDef
->perf
.events
[type
] = enabled
?
10628 VIR_TRISTATE_BOOL_YES
: VIR_TRISTATE_BOOL_NO
;
10631 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
10638 qemuDomainObjEndJob(driver
, vm
);
10641 virDomainObjEndAPI(&vm
);
10642 virObjectUnref(cfg
);
10647 qemuDomainGetPerfEvents(virDomainPtr dom
,
10648 virTypedParameterPtr
*params
,
10650 unsigned int flags
)
10652 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10653 virDomainObjPtr vm
= NULL
;
10654 qemuDomainObjPrivatePtr priv
;
10655 virDomainDefPtr def
;
10656 virTypedParameterPtr par
= NULL
;
10662 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10663 VIR_DOMAIN_AFFECT_CONFIG
|
10664 VIR_TYPED_PARAM_STRING_OKAY
, -1);
10666 if (!(vm
= qemuDomObjFromDomain(dom
)))
10669 if (virDomainGetPerfEventsEnsureACL(dom
->conn
, vm
->def
) < 0)
10672 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
10675 if (virDomainObjUpdateModificationImpact(vm
, &flags
) < 0)
10678 if (!(def
= virDomainObjGetOneDef(vm
, flags
)))
10681 priv
= vm
->privateData
;
10683 for (i
= 0; i
< VIR_PERF_EVENT_LAST
; i
++) {
10686 if (flags
& VIR_DOMAIN_AFFECT_CONFIG
)
10687 perf_enabled
= def
->perf
.events
[i
] == VIR_TRISTATE_BOOL_YES
;
10689 perf_enabled
= virPerfEventIsEnabled(priv
->perf
, i
);
10691 if (virTypedParamsAddBoolean(&par
, &npar
, &maxpar
,
10692 virPerfEventTypeToString(i
),
10704 qemuDomainObjEndJob(driver
, vm
);
10707 virDomainObjEndAPI(&vm
);
10708 virTypedParamsFree(par
, npar
);
10713 qemuSetVcpusBWLive(virDomainObjPtr vm
, virCgroupPtr cgroup
,
10714 unsigned long long period
, long long quota
)
10717 virCgroupPtr cgroup_vcpu
= NULL
;
10719 if (period
== 0 && quota
== 0)
10722 if (!qemuDomainHasVcpuPids(vm
))
10725 for (i
= 0; i
< virDomainDefGetVcpusMax(vm
->def
); i
++) {
10726 virDomainVcpuDefPtr vcpu
= virDomainDefGetVcpu(vm
->def
, i
);
10731 if (virCgroupNewThread(cgroup
, VIR_CGROUP_THREAD_VCPU
, i
,
10732 false, &cgroup_vcpu
) < 0)
10735 if (qemuSetupCgroupVcpuBW(cgroup_vcpu
, period
, quota
) < 0)
10738 virCgroupFree(&cgroup_vcpu
);
10744 virCgroupFree(&cgroup_vcpu
);
10749 qemuSetEmulatorBandwidthLive(virCgroupPtr cgroup
,
10750 unsigned long long period
,
10753 virCgroupPtr cgroup_emulator
= NULL
;
10755 if (period
== 0 && quota
== 0)
10758 if (virCgroupNewThread(cgroup
, VIR_CGROUP_THREAD_EMULATOR
, 0,
10759 false, &cgroup_emulator
) < 0)
10762 if (qemuSetupCgroupVcpuBW(cgroup_emulator
, period
, quota
) < 0)
10765 virCgroupFree(&cgroup_emulator
);
10769 virCgroupFree(&cgroup_emulator
);
10775 qemuSetIOThreadsBWLive(virDomainObjPtr vm
, virCgroupPtr cgroup
,
10776 unsigned long long period
, long long quota
)
10779 virCgroupPtr cgroup_iothread
= NULL
;
10781 if (period
== 0 && quota
== 0)
10784 if (!vm
->def
->niothreadids
)
10787 for (i
= 0; i
< vm
->def
->niothreadids
; i
++) {
10788 if (virCgroupNewThread(cgroup
, VIR_CGROUP_THREAD_IOTHREAD
,
10789 vm
->def
->iothreadids
[i
]->iothread_id
,
10790 false, &cgroup_iothread
) < 0)
10793 if (qemuSetupCgroupVcpuBW(cgroup_iothread
, period
, quota
) < 0)
10796 virCgroupFree(&cgroup_iothread
);
10802 virCgroupFree(&cgroup_iothread
);
10807 #define SCHED_RANGE_CHECK(VAR, NAME, MIN, MAX) \
10808 if (((VAR) > 0 && (VAR) < (MIN)) || (VAR) > (MAX)) { \
10809 virReportError(VIR_ERR_INVALID_ARG, \
10810 _("value of '%s' is out of range [%lld, %lld]"), \
10817 qemuDomainSetSchedulerParametersFlags(virDomainPtr dom
,
10818 virTypedParameterPtr params
,
10820 unsigned int flags
)
10822 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
10824 virDomainObjPtr vm
= NULL
;
10825 virDomainDefPtr def
= NULL
;
10826 virDomainDefPtr persistentDef
= NULL
;
10827 virDomainDefPtr persistentDefCopy
= NULL
;
10828 unsigned long long value_ul
;
10832 virQEMUDriverConfigPtr cfg
= NULL
;
10833 virCapsPtr caps
= NULL
;
10834 qemuDomainObjPrivatePtr priv
;
10835 virObjectEventPtr event
= NULL
;
10836 virTypedParameterPtr eventParams
= NULL
;
10837 int eventNparams
= 0;
10838 int eventMaxNparams
= 0;
10840 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
10841 VIR_DOMAIN_AFFECT_CONFIG
, -1);
10842 if (virTypedParamsValidate(params
, nparams
,
10843 VIR_DOMAIN_SCHEDULER_CPU_SHARES
,
10844 VIR_TYPED_PARAM_ULLONG
,
10845 VIR_DOMAIN_SCHEDULER_VCPU_PERIOD
,
10846 VIR_TYPED_PARAM_ULLONG
,
10847 VIR_DOMAIN_SCHEDULER_VCPU_QUOTA
,
10848 VIR_TYPED_PARAM_LLONG
,
10849 VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD
,
10850 VIR_TYPED_PARAM_ULLONG
,
10851 VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA
,
10852 VIR_TYPED_PARAM_LLONG
,
10853 VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD
,
10854 VIR_TYPED_PARAM_ULLONG
,
10855 VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA
,
10856 VIR_TYPED_PARAM_LLONG
,
10857 VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD
,
10858 VIR_TYPED_PARAM_ULLONG
,
10859 VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA
,
10860 VIR_TYPED_PARAM_LLONG
,
10864 if (!(vm
= qemuDomObjFromDomain(dom
)))
10867 priv
= vm
->privateData
;
10868 cfg
= virQEMUDriverGetConfig(driver
);
10870 if (virDomainSetSchedulerParametersFlagsEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
10873 if (!virQEMUDriverIsPrivileged(driver
)) {
10874 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
10875 _("CPU tuning is not available in session mode"));
10879 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
10882 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
10885 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
10888 if (persistentDef
) {
10889 /* Make a copy for updated domain. */
10890 if (!(persistentDefCopy
= virDomainObjCopyPersistentDef(vm
, caps
,
10896 !virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPU
)) {
10897 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
10898 _("cgroup CPU controller is not mounted"));
10902 for (i
= 0; i
< nparams
; i
++) {
10903 virTypedParameterPtr param
= ¶ms
[i
];
10904 value_ul
= param
->value
.ul
;
10905 value_l
= param
->value
.l
;
10907 if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_CPU_SHARES
)) {
10909 unsigned long long val
;
10910 if (virCgroupSetCpuShares(priv
->cgroup
, value_ul
) < 0)
10913 if (virCgroupGetCpuShares(priv
->cgroup
, &val
) < 0)
10916 def
->cputune
.shares
= val
;
10917 def
->cputune
.sharesSpecified
= true;
10919 if (virTypedParamsAddULLong(&eventParams
, &eventNparams
,
10921 VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES
,
10926 if (persistentDef
) {
10927 persistentDefCopy
->cputune
.shares
= value_ul
;
10928 persistentDefCopy
->cputune
.sharesSpecified
= true;
10932 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD
)) {
10933 SCHED_RANGE_CHECK(value_ul
, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD
,
10934 QEMU_SCHED_MIN_PERIOD
, QEMU_SCHED_MAX_PERIOD
);
10936 if (def
&& value_ul
) {
10937 if ((rc
= qemuSetVcpusBWLive(vm
, priv
->cgroup
, value_ul
, 0)))
10940 def
->cputune
.period
= value_ul
;
10942 if (virTypedParamsAddULLong(&eventParams
, &eventNparams
,
10944 VIR_DOMAIN_TUNABLE_CPU_VCPU_PERIOD
,
10950 persistentDefCopy
->cputune
.period
= value_ul
;
10952 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA
)) {
10953 SCHED_RANGE_CHECK(value_l
, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA
,
10954 QEMU_SCHED_MIN_QUOTA
, QEMU_SCHED_MAX_QUOTA
);
10956 if (def
&& value_l
) {
10957 if ((rc
= qemuSetVcpusBWLive(vm
, priv
->cgroup
, 0, value_l
)))
10960 def
->cputune
.quota
= value_l
;
10962 if (virTypedParamsAddLLong(&eventParams
, &eventNparams
,
10964 VIR_DOMAIN_TUNABLE_CPU_VCPU_QUOTA
,
10970 persistentDefCopy
->cputune
.quota
= value_l
;
10972 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD
)) {
10973 SCHED_RANGE_CHECK(value_ul
, VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD
,
10974 QEMU_SCHED_MIN_PERIOD
, QEMU_SCHED_MAX_PERIOD
);
10976 if (def
&& value_ul
) {
10977 if ((rc
= qemuSetGlobalBWLive(priv
->cgroup
, value_ul
, 0)))
10980 def
->cputune
.global_period
= value_ul
;
10982 if (virTypedParamsAddULLong(&eventParams
, &eventNparams
,
10984 VIR_DOMAIN_TUNABLE_CPU_GLOBAL_PERIOD
,
10990 persistentDefCopy
->cputune
.global_period
= value_ul
;
10992 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA
)) {
10993 SCHED_RANGE_CHECK(value_l
, VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA
,
10994 QEMU_SCHED_MIN_QUOTA
, QEMU_SCHED_MAX_QUOTA
);
10996 if (def
&& value_l
) {
10997 if ((rc
= qemuSetGlobalBWLive(priv
->cgroup
, 0, value_l
)))
11000 def
->cputune
.global_quota
= value_l
;
11002 if (virTypedParamsAddLLong(&eventParams
, &eventNparams
,
11004 VIR_DOMAIN_TUNABLE_CPU_GLOBAL_QUOTA
,
11010 persistentDefCopy
->cputune
.global_quota
= value_l
;
11012 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD
)) {
11013 SCHED_RANGE_CHECK(value_ul
, VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD
,
11014 QEMU_SCHED_MIN_PERIOD
, QEMU_SCHED_MAX_PERIOD
);
11016 if (def
&& value_ul
) {
11017 if ((rc
= qemuSetEmulatorBandwidthLive(priv
->cgroup
,
11021 def
->cputune
.emulator_period
= value_ul
;
11023 if (virTypedParamsAddULLong(&eventParams
, &eventNparams
,
11025 VIR_DOMAIN_TUNABLE_CPU_EMULATOR_PERIOD
,
11031 persistentDefCopy
->cputune
.emulator_period
= value_ul
;
11033 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA
)) {
11034 SCHED_RANGE_CHECK(value_l
, VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA
,
11035 QEMU_SCHED_MIN_QUOTA
, QEMU_SCHED_MAX_QUOTA
);
11037 if (def
&& value_l
) {
11038 if ((rc
= qemuSetEmulatorBandwidthLive(priv
->cgroup
,
11042 def
->cputune
.emulator_quota
= value_l
;
11044 if (virTypedParamsAddLLong(&eventParams
, &eventNparams
,
11046 VIR_DOMAIN_TUNABLE_CPU_EMULATOR_QUOTA
,
11052 persistentDefCopy
->cputune
.emulator_quota
= value_l
;
11054 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD
)) {
11055 SCHED_RANGE_CHECK(value_ul
, VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD
,
11056 QEMU_SCHED_MIN_PERIOD
, QEMU_SCHED_MAX_PERIOD
);
11058 if (def
&& value_ul
) {
11059 if ((rc
= qemuSetIOThreadsBWLive(vm
, priv
->cgroup
, value_ul
, 0)))
11062 def
->cputune
.iothread_period
= value_ul
;
11064 if (virTypedParamsAddULLong(&eventParams
, &eventNparams
,
11066 VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_PERIOD
,
11072 persistentDefCopy
->cputune
.iothread_period
= value_ul
;
11074 } else if (STREQ(param
->field
, VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA
)) {
11075 SCHED_RANGE_CHECK(value_l
, VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA
,
11076 QEMU_SCHED_MIN_QUOTA
, QEMU_SCHED_MAX_QUOTA
);
11078 if (def
&& value_l
) {
11079 if ((rc
= qemuSetIOThreadsBWLive(vm
, priv
->cgroup
, 0, value_l
)))
11082 def
->cputune
.iothread_quota
= value_l
;
11084 if (virTypedParamsAddLLong(&eventParams
, &eventNparams
,
11086 VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_QUOTA
,
11092 persistentDefCopy
->cputune
.iothread_quota
= value_l
;
11096 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
11099 if (eventNparams
) {
11100 event
= virDomainEventTunableNewFromDom(dom
, eventParams
, eventNparams
);
11102 virObjectEventStateQueue(driver
->domainEventState
, event
);
11105 if (persistentDef
) {
11106 rc
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDefCopy
);
11110 virDomainObjAssignDef(vm
, persistentDefCopy
, false, NULL
);
11111 persistentDefCopy
= NULL
;
11117 qemuDomainObjEndJob(driver
, vm
);
11120 virDomainDefFree(persistentDefCopy
);
11121 virDomainObjEndAPI(&vm
);
11123 virTypedParamsFree(eventParams
, eventNparams
);
11124 virObjectUnref(caps
);
11125 virObjectUnref(cfg
);
11128 #undef SCHED_RANGE_CHECK
11131 qemuDomainSetSchedulerParameters(virDomainPtr dom
,
11132 virTypedParameterPtr params
,
11135 return qemuDomainSetSchedulerParametersFlags(dom
,
11138 VIR_DOMAIN_AFFECT_CURRENT
);
11142 qemuGetVcpuBWLive(virCgroupPtr cgroup
, unsigned long long *period
,
11145 if (virCgroupGetCpuCfsPeriod(cgroup
, period
) < 0)
11148 if (virCgroupGetCpuCfsQuota(cgroup
, quota
) < 0)
11155 qemuGetVcpusBWLive(virDomainObjPtr vm
,
11156 unsigned long long *period
, long long *quota
)
11158 virCgroupPtr cgroup_vcpu
= NULL
;
11159 qemuDomainObjPrivatePtr priv
= NULL
;
11163 priv
= vm
->privateData
;
11164 if (!qemuDomainHasVcpuPids(vm
)) {
11165 /* We do not create sub dir for each vcpu */
11166 rc
= qemuGetVcpuBWLive(priv
->cgroup
, period
, quota
);
11171 *quota
/= virDomainDefGetVcpus(vm
->def
);
11175 /* get period and quota for vcpu0 */
11176 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_VCPU
, 0,
11177 false, &cgroup_vcpu
) < 0)
11180 rc
= qemuGetVcpuBWLive(cgroup_vcpu
, period
, quota
);
11188 virCgroupFree(&cgroup_vcpu
);
11193 qemuGetEmulatorBandwidthLive(virCgroupPtr cgroup
,
11194 unsigned long long *period
,
11197 virCgroupPtr cgroup_emulator
= NULL
;
11200 /* get period and quota for emulator */
11201 if (virCgroupNewThread(cgroup
, VIR_CGROUP_THREAD_EMULATOR
, 0,
11202 false, &cgroup_emulator
) < 0)
11205 if (qemuGetVcpuBWLive(cgroup_emulator
, period
, quota
) < 0)
11211 virCgroupFree(&cgroup_emulator
);
11216 qemuGetIOThreadsBWLive(virDomainObjPtr vm
,
11217 unsigned long long *period
, long long *quota
)
11219 virCgroupPtr cgroup_iothread
= NULL
;
11220 qemuDomainObjPrivatePtr priv
= NULL
;
11224 priv
= vm
->privateData
;
11225 if (!vm
->def
->niothreadids
) {
11226 /* We do not create sub dir for each iothread */
11227 if ((rc
= qemuGetVcpuBWLive(priv
->cgroup
, period
, quota
)) < 0)
11233 /* get period and quota for the "first" IOThread */
11234 if (virCgroupNewThread(priv
->cgroup
, VIR_CGROUP_THREAD_IOTHREAD
,
11235 vm
->def
->iothreadids
[0]->iothread_id
,
11236 false, &cgroup_iothread
) < 0)
11239 rc
= qemuGetVcpuBWLive(cgroup_iothread
, period
, quota
);
11247 virCgroupFree(&cgroup_iothread
);
11253 qemuGetGlobalBWLive(virCgroupPtr cgroup
, unsigned long long *period
,
11256 if (qemuGetVcpuBWLive(cgroup
, period
, quota
) < 0)
11263 qemuDomainGetSchedulerParametersFlags(virDomainPtr dom
,
11264 virTypedParameterPtr params
,
11266 unsigned int flags
)
11268 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
11269 virDomainObjPtr vm
= NULL
;
11270 virDomainCputune data
= {0};
11272 bool cpu_bw_status
= true;
11273 virDomainDefPtr persistentDef
;
11274 virDomainDefPtr def
;
11275 qemuDomainObjPrivatePtr priv
;
11276 int maxparams
= *nparams
;
11280 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
11281 VIR_DOMAIN_AFFECT_CONFIG
|
11282 VIR_TYPED_PARAM_STRING_OKAY
, -1);
11284 if (!(vm
= qemuDomObjFromDomain(dom
)))
11287 priv
= vm
->privateData
;
11289 if (virDomainGetSchedulerParametersFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
11292 if (!virQEMUDriverIsPrivileged(driver
)) {
11293 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
11294 _("CPU tuning is not available in session mode"));
11298 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
11301 if (persistentDef
) {
11302 data
= persistentDef
->cputune
;
11304 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPU
)) {
11305 virReportError(VIR_ERR_OPERATION_INVALID
,
11306 "%s", _("cgroup CPU controller is not mounted"));
11310 if (virCgroupGetCpuShares(priv
->cgroup
, &data
.shares
) < 0)
11313 if (virCgroupSupportsCpuBW(priv
->cgroup
)) {
11314 if (maxparams
> 1 &&
11315 qemuGetVcpusBWLive(vm
, &data
.period
, &data
.quota
) < 0)
11318 if (maxparams
> 3 &&
11319 qemuGetEmulatorBandwidthLive(priv
->cgroup
, &data
.emulator_period
,
11320 &data
.emulator_quota
) < 0)
11323 if (maxparams
> 5 &&
11324 qemuGetGlobalBWLive(priv
->cgroup
, &data
.global_period
,
11325 &data
.global_quota
) < 0)
11328 if (maxparams
> 7 &&
11329 qemuGetIOThreadsBWLive(vm
, &data
.iothread_period
,
11330 &data
.iothread_quota
) < 0)
11333 cpu_bw_status
= false;
11337 #define QEMU_SCHED_ASSIGN(param, name, type) \
11338 if (*nparams < maxparams && \
11339 virTypedParameterAssign(&(params[(*nparams)++]), \
11340 VIR_DOMAIN_SCHEDULER_ ## name, \
11341 VIR_TYPED_PARAM_ ## type, \
11345 QEMU_SCHED_ASSIGN(shares
, CPU_SHARES
, ULLONG
);
11347 if (cpu_bw_status
) {
11348 QEMU_SCHED_ASSIGN(period
, VCPU_PERIOD
, ULLONG
);
11349 QEMU_SCHED_ASSIGN(quota
, VCPU_QUOTA
, LLONG
);
11351 QEMU_SCHED_ASSIGN(emulator_period
, EMULATOR_PERIOD
, ULLONG
);
11352 QEMU_SCHED_ASSIGN(emulator_quota
, EMULATOR_QUOTA
, LLONG
);
11354 QEMU_SCHED_ASSIGN(global_period
, GLOBAL_PERIOD
, ULLONG
);
11355 QEMU_SCHED_ASSIGN(global_quota
, GLOBAL_QUOTA
, LLONG
);
11357 QEMU_SCHED_ASSIGN(iothread_period
, IOTHREAD_PERIOD
, ULLONG
);
11358 QEMU_SCHED_ASSIGN(iothread_quota
, IOTHREAD_QUOTA
, LLONG
);
11361 #undef QEMU_SCHED_ASSIGN
11366 virDomainObjEndAPI(&vm
);
11371 qemuDomainGetSchedulerParameters(virDomainPtr dom
,
11372 virTypedParameterPtr params
,
11375 return qemuDomainGetSchedulerParametersFlags(dom
, params
, nparams
,
11376 VIR_DOMAIN_AFFECT_CURRENT
);
11380 * Resize a block device while a guest is running. Resize to a lower size
11381 * is supported, but should be used with extreme caution. Note that it
11382 * only supports to resize image files, it can't resize block devices
11383 * like LVM volumes.
11386 qemuDomainBlockResize(virDomainPtr dom
,
11388 unsigned long long size
,
11389 unsigned int flags
)
11391 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
11392 virDomainObjPtr vm
;
11393 qemuDomainObjPrivatePtr priv
;
11395 char *device
= NULL
;
11396 const char *nodename
= NULL
;
11397 virDomainDiskDefPtr disk
= NULL
;
11399 virCheckFlags(VIR_DOMAIN_BLOCK_RESIZE_BYTES
, -1);
11401 /* We prefer operating on bytes. */
11402 if ((flags
& VIR_DOMAIN_BLOCK_RESIZE_BYTES
) == 0) {
11403 if (size
> ULLONG_MAX
/ 1024) {
11404 virReportError(VIR_ERR_OVERFLOW
,
11405 _("size must be less than %llu"),
11406 ULLONG_MAX
/ 1024);
11412 if (!(vm
= qemuDomObjFromDomain(dom
)))
11415 priv
= vm
->privateData
;
11417 if (virDomainBlockResizeEnsureACL(dom
->conn
, vm
->def
) < 0)
11420 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
11423 if (virDomainObjCheckActive(vm
) < 0)
11426 if (!(disk
= virDomainDiskByName(vm
->def
, path
, false))) {
11427 virReportError(VIR_ERR_INVALID_ARG
,
11428 _("disk '%s' was not found in the domain config"), path
);
11432 /* qcow2 and qed must be sized on 512 byte blocks/sectors,
11433 * so adjust size if necessary to round up.
11435 if (disk
->src
->format
== VIR_STORAGE_FILE_QCOW2
||
11436 disk
->src
->format
== VIR_STORAGE_FILE_QED
)
11437 size
= VIR_ROUND_UP(size
, 512);
11439 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
)) {
11440 if (virStorageSourceIsEmpty(disk
->src
) || disk
->src
->readonly
) {
11441 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
11442 _("can't resize empty or readonly disk '%s'"),
11447 nodename
= disk
->src
->nodeformat
;
11449 if (!(device
= qemuAliasDiskDriveFromDisk(disk
)))
11453 qemuDomainObjEnterMonitor(driver
, vm
);
11454 if (qemuMonitorBlockResize(priv
->mon
, device
, nodename
, size
) < 0) {
11455 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
11458 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
11464 qemuDomainObjEndJob(driver
, vm
);
11468 virDomainObjEndAPI(&vm
);
11474 qemuDomainBlockStatsGatherTotals(qemuBlockStatsPtr data
,
11475 qemuBlockStatsPtr total
)
11477 #define QEMU_BLOCK_STAT_TOTAL(NAME) \
11478 if (data->NAME > 0) \
11479 total->NAME += data->NAME
11481 QEMU_BLOCK_STAT_TOTAL(wr_bytes
);
11482 QEMU_BLOCK_STAT_TOTAL(wr_req
);
11483 QEMU_BLOCK_STAT_TOTAL(rd_bytes
);
11484 QEMU_BLOCK_STAT_TOTAL(rd_req
);
11485 QEMU_BLOCK_STAT_TOTAL(flush_req
);
11486 QEMU_BLOCK_STAT_TOTAL(wr_total_times
);
11487 QEMU_BLOCK_STAT_TOTAL(rd_total_times
);
11488 QEMU_BLOCK_STAT_TOTAL(flush_total_times
);
11489 #undef QEMU_BLOCK_STAT_TOTAL
11495 * qemuDomainBlocksStatsGather:
11496 * @driver: driver object
11497 * @vm: domain object
11498 * @path: to gather the statistics for
11499 * @capacity: refresh capacity of the backing image
11500 * @retstats: returns pointer to structure holding the stats
11502 * Gathers the block statistics for use in qemuDomainBlockStats* APIs.
11504 * Returns -1 on error; number of filled block statistics on success.
11507 qemuDomainBlocksStatsGather(virQEMUDriverPtr driver
,
11508 virDomainObjPtr vm
,
11511 qemuBlockStatsPtr
*retstats
)
11513 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
11514 bool blockdev
= virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
);
11515 virDomainDiskDefPtr disk
= NULL
;
11516 virHashTablePtr blockstats
= NULL
;
11517 qemuBlockStatsPtr stats
;
11521 const char *entryname
= NULL
;
11525 if (!(disk
= virDomainDiskByName(vm
->def
, path
, false))) {
11526 virReportError(VIR_ERR_INVALID_ARG
, _("invalid path: %s"), path
);
11531 entryname
= QEMU_DOMAIN_DISK_PRIVATE(disk
)->qomName
;
11533 if (!disk
->info
.alias
) {
11534 virReportError(VIR_ERR_INTERNAL_ERROR
,
11535 _("missing disk device alias name for %s"), disk
->dst
);
11539 entryname
= disk
->info
.alias
;
11543 qemuDomainObjEnterMonitor(driver
, vm
);
11544 nstats
= qemuMonitorGetAllBlockStatsInfo(priv
->mon
, &blockstats
, false);
11546 if (capacity
&& nstats
>= 0) {
11548 rc
= qemuMonitorBlockStatsUpdateCapacityBlockdev(priv
->mon
, blockstats
);
11550 rc
= qemuMonitorBlockStatsUpdateCapacity(priv
->mon
, blockstats
, false);
11553 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || nstats
< 0 || rc
< 0)
11556 if (VIR_ALLOC(*retstats
) < 0)
11560 if (!(stats
= virHashLookup(blockstats
, entryname
))) {
11561 virReportError(VIR_ERR_INTERNAL_ERROR
,
11562 _("cannot find statistics for device '%s'"), entryname
);
11566 **retstats
= *stats
;
11569 /* capacity are reported only per node-name so we need to transfer them */
11570 qemuBlockStatsPtr capstats
;
11572 if (disk
&& disk
->src
&&
11573 (capstats
= virHashLookup(blockstats
, disk
->src
->nodeformat
))) {
11574 (*retstats
)->capacity
= capstats
->capacity
;
11575 (*retstats
)->physical
= capstats
->physical
;
11576 (*retstats
)->wr_highest_offset
= capstats
->wr_highest_offset
;
11577 (*retstats
)->wr_highest_offset_valid
= capstats
->wr_highest_offset_valid
;
11578 (*retstats
)->write_threshold
= capstats
->write_threshold
;
11582 for (i
= 0; i
< vm
->def
->ndisks
; i
++) {
11583 disk
= vm
->def
->disks
[i
];
11584 entryname
= disk
->info
.alias
;
11587 entryname
= QEMU_DOMAIN_DISK_PRIVATE(disk
)->qomName
;
11592 if (!(stats
= virHashLookup(blockstats
, entryname
))) {
11593 virReportError(VIR_ERR_INTERNAL_ERROR
,
11594 _("cannot find statistics for device '%s'"), entryname
);
11598 qemuDomainBlockStatsGatherTotals(stats
, *retstats
);
11605 virHashFree(blockstats
);
11610 /* This uses the 'info blockstats' monitor command which was
11611 * integrated into both qemu & kvm in late 2007. If the command is
11612 * not supported we detect this and return the appropriate error.
11615 qemuDomainBlockStats(virDomainPtr dom
,
11617 virDomainBlockStatsPtr stats
)
11619 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
11620 qemuBlockStatsPtr blockstats
= NULL
;
11622 virDomainObjPtr vm
;
11624 if (!(vm
= qemuDomObjFromDomain(dom
)))
11627 if (virDomainBlockStatsEnsureACL(dom
->conn
, vm
->def
) < 0)
11630 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
11633 if (virDomainObjCheckActive(vm
) < 0)
11636 if (qemuDomainBlocksStatsGather(driver
, vm
, path
, false, &blockstats
) < 0)
11639 stats
->rd_req
= blockstats
->rd_req
;
11640 stats
->rd_bytes
= blockstats
->rd_bytes
;
11641 stats
->wr_req
= blockstats
->wr_req
;
11642 stats
->wr_bytes
= blockstats
->wr_bytes
;
11643 /* qemu doesn't report the error count */
11649 qemuDomainObjEndJob(driver
, vm
);
11652 virDomainObjEndAPI(&vm
);
11653 VIR_FREE(blockstats
);
11659 qemuDomainBlockStatsFlags(virDomainPtr dom
,
11661 virTypedParameterPtr params
,
11663 unsigned int flags
)
11665 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
11666 virDomainObjPtr vm
;
11667 qemuBlockStatsPtr blockstats
= NULL
;
11671 VIR_DEBUG("params=%p, flags=0x%x", params
, flags
);
11673 virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY
, -1);
11675 /* We don't return strings, and thus trivially support this flag. */
11676 flags
&= ~VIR_TYPED_PARAM_STRING_OKAY
;
11678 if (!(vm
= qemuDomObjFromDomain(dom
)))
11681 if (virDomainBlockStatsFlagsEnsureACL(dom
->conn
, vm
->def
) < 0)
11684 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
11687 if (virDomainObjCheckActive(vm
) < 0)
11690 if ((nstats
= qemuDomainBlocksStatsGather(driver
, vm
, path
, false,
11694 /* return count of supported stats */
11695 if (*nparams
== 0) {
11703 #define QEMU_BLOCK_STATS_ASSIGN_PARAM(VAR, NAME) \
11704 if (nstats < *nparams && (blockstats->VAR) != -1) { \
11705 if (virTypedParameterAssign(params + nstats, NAME, \
11706 VIR_TYPED_PARAM_LLONG, (blockstats->VAR)) < 0) \
11711 QEMU_BLOCK_STATS_ASSIGN_PARAM(wr_bytes
, VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES
);
11712 QEMU_BLOCK_STATS_ASSIGN_PARAM(wr_req
, VIR_DOMAIN_BLOCK_STATS_WRITE_REQ
);
11714 QEMU_BLOCK_STATS_ASSIGN_PARAM(rd_bytes
, VIR_DOMAIN_BLOCK_STATS_READ_BYTES
);
11715 QEMU_BLOCK_STATS_ASSIGN_PARAM(rd_req
, VIR_DOMAIN_BLOCK_STATS_READ_REQ
);
11717 QEMU_BLOCK_STATS_ASSIGN_PARAM(flush_req
, VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ
);
11719 QEMU_BLOCK_STATS_ASSIGN_PARAM(wr_total_times
,
11720 VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES
);
11721 QEMU_BLOCK_STATS_ASSIGN_PARAM(rd_total_times
,
11722 VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES
);
11723 QEMU_BLOCK_STATS_ASSIGN_PARAM(flush_total_times
,
11724 VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES
);
11725 #undef QEMU_BLOCK_STATS_ASSIGN_PARAM
11731 qemuDomainObjEndJob(driver
, vm
);
11734 VIR_FREE(blockstats
);
11735 virDomainObjEndAPI(&vm
);
11740 qemuDomainInterfaceStats(virDomainPtr dom
,
11741 const char *device
,
11742 virDomainInterfaceStatsPtr stats
)
11744 virDomainObjPtr vm
;
11745 virDomainNetDefPtr net
= NULL
;
11748 if (!(vm
= qemuDomObjFromDomain(dom
)))
11751 if (virDomainInterfaceStatsEnsureACL(dom
->conn
, vm
->def
) < 0)
11754 if (virDomainObjCheckActive(vm
) < 0)
11757 if (!(net
= virDomainNetFind(vm
->def
, device
)))
11760 if (virDomainNetGetActualType(net
) == VIR_DOMAIN_NET_TYPE_VHOSTUSER
) {
11761 if (virNetDevOpenvswitchInterfaceStats(net
->ifname
, stats
) < 0)
11764 if (virNetDevTapInterfaceStats(net
->ifname
, stats
,
11765 !virDomainNetTypeSharesHostView(net
)) < 0)
11771 virDomainObjEndAPI(&vm
);
11776 qemuDomainSetInterfaceParameters(virDomainPtr dom
,
11777 const char *device
,
11778 virTypedParameterPtr params
,
11780 unsigned int flags
)
11782 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
11784 virDomainObjPtr vm
= NULL
;
11785 virDomainDefPtr def
;
11786 virDomainDefPtr persistentDef
;
11788 virDomainNetDefPtr net
= NULL
, persistentNet
= NULL
;
11789 virNetDevBandwidthPtr bandwidth
= NULL
, newBandwidth
= NULL
;
11790 virQEMUDriverConfigPtr cfg
= NULL
;
11791 bool inboundSpecified
= false, outboundSpecified
= false;
11793 bool qosSupported
= true;
11795 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
11796 VIR_DOMAIN_AFFECT_CONFIG
, -1);
11797 if (virTypedParamsValidate(params
, nparams
,
11798 VIR_DOMAIN_BANDWIDTH_IN_AVERAGE
,
11799 VIR_TYPED_PARAM_UINT
,
11800 VIR_DOMAIN_BANDWIDTH_IN_PEAK
,
11801 VIR_TYPED_PARAM_UINT
,
11802 VIR_DOMAIN_BANDWIDTH_IN_BURST
,
11803 VIR_TYPED_PARAM_UINT
,
11804 VIR_DOMAIN_BANDWIDTH_IN_FLOOR
,
11805 VIR_TYPED_PARAM_UINT
,
11806 VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE
,
11807 VIR_TYPED_PARAM_UINT
,
11808 VIR_DOMAIN_BANDWIDTH_OUT_PEAK
,
11809 VIR_TYPED_PARAM_UINT
,
11810 VIR_DOMAIN_BANDWIDTH_OUT_BURST
,
11811 VIR_TYPED_PARAM_UINT
,
11815 if (!(vm
= qemuDomObjFromDomain(dom
)))
11818 cfg
= virQEMUDriverGetConfig(driver
);
11820 if (virDomainSetInterfaceParametersEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
11823 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
11826 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
11830 !(net
= virDomainNetFind(vm
->def
, device
)))
11833 if (persistentDef
&&
11834 !(persistentNet
= virDomainNetFind(persistentDef
, device
)))
11838 actualType
= virDomainNetGetActualType(net
);
11839 qosSupported
= virNetDevSupportBandwidth(actualType
);
11842 if (qosSupported
&& persistentNet
) {
11843 actualType
= virDomainNetGetActualType(persistentNet
);
11844 qosSupported
= virNetDevSupportBandwidth(actualType
);
11847 if (!qosSupported
) {
11848 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
11849 _("setting bandwidth on interfaces of "
11850 "type '%s' is not implemented yet"),
11851 virDomainNetTypeToString(actualType
));
11855 if ((VIR_ALLOC(bandwidth
) < 0) ||
11856 (VIR_ALLOC(bandwidth
->in
) < 0) ||
11857 (VIR_ALLOC(bandwidth
->out
) < 0))
11860 for (i
= 0; i
< nparams
; i
++) {
11861 virTypedParameterPtr param
= ¶ms
[i
];
11863 if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_IN_AVERAGE
)) {
11864 bandwidth
->in
->average
= param
->value
.ui
;
11865 inboundSpecified
= true;
11866 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_IN_PEAK
)) {
11867 bandwidth
->in
->peak
= param
->value
.ui
;
11868 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_IN_BURST
)) {
11869 bandwidth
->in
->burst
= param
->value
.ui
;
11870 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_IN_FLOOR
)) {
11871 bandwidth
->in
->floor
= param
->value
.ui
;
11872 inboundSpecified
= true;
11873 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE
)) {
11874 bandwidth
->out
->average
= param
->value
.ui
;
11875 outboundSpecified
= true;
11876 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_OUT_PEAK
)) {
11877 bandwidth
->out
->peak
= param
->value
.ui
;
11878 } else if (STREQ(param
->field
, VIR_DOMAIN_BANDWIDTH_OUT_BURST
)) {
11879 bandwidth
->out
->burst
= param
->value
.ui
;
11883 /* average or floor are mandatory, peak and burst are optional.
11884 * So if no average or floor is given, we free inbound/outbound
11885 * here which causes inbound/outbound to not be set. */
11886 if (!bandwidth
->in
->average
&& !bandwidth
->in
->floor
)
11887 VIR_FREE(bandwidth
->in
);
11888 if (!bandwidth
->out
->average
)
11889 VIR_FREE(bandwidth
->out
);
11892 if (VIR_ALLOC(newBandwidth
) < 0)
11895 /* virNetDevBandwidthSet() will clear any previous value of
11896 * bandwidth parameters, so merge with old bandwidth parameters
11897 * here to prevent them from being lost. */
11898 if (bandwidth
->in
||
11899 (!inboundSpecified
&& net
->bandwidth
&& net
->bandwidth
->in
)) {
11900 if (VIR_ALLOC(newBandwidth
->in
) < 0)
11903 memcpy(newBandwidth
->in
,
11904 bandwidth
->in
? bandwidth
->in
: net
->bandwidth
->in
,
11905 sizeof(*newBandwidth
->in
));
11907 if (bandwidth
->out
||
11908 (!outboundSpecified
&& net
->bandwidth
&& net
->bandwidth
->out
)) {
11909 if (VIR_ALLOC(newBandwidth
->out
) < 0)
11912 memcpy(newBandwidth
->out
,
11913 bandwidth
->out
? bandwidth
->out
: net
->bandwidth
->out
,
11914 sizeof(*newBandwidth
->out
));
11917 if (!virDomainNetBandwidthChangeAllowed(net
, newBandwidth
))
11920 if (virNetDevBandwidthSet(net
->ifname
, newBandwidth
, false,
11921 !virDomainNetTypeSharesHostView(net
)) < 0 ||
11922 virDomainNetBandwidthUpdate(net
, newBandwidth
) < 0) {
11923 ignore_value(virNetDevBandwidthSet(net
->ifname
,
11926 !virDomainNetTypeSharesHostView(net
)));
11930 virNetDevBandwidthFree(net
->bandwidth
);
11931 if (newBandwidth
->in
|| newBandwidth
->out
) {
11932 net
->bandwidth
= newBandwidth
;
11933 newBandwidth
= NULL
;
11935 net
->bandwidth
= NULL
;
11938 if (net
->type
== VIR_DOMAIN_NET_TYPE_NETWORK
) {
11939 virNetDevBandwidthFree(net
->data
.network
.actual
->bandwidth
);
11940 if (virNetDevBandwidthCopy(&net
->data
.network
.actual
->bandwidth
,
11941 net
->bandwidth
) < 0)
11945 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
11949 if (persistentNet
) {
11950 if (!persistentNet
->bandwidth
) {
11951 persistentNet
->bandwidth
= bandwidth
;
11954 if (bandwidth
->in
) {
11955 VIR_FREE(persistentNet
->bandwidth
->in
);
11956 persistentNet
->bandwidth
->in
= bandwidth
->in
;
11957 bandwidth
->in
= NULL
;
11958 } else if (inboundSpecified
) {
11959 VIR_FREE(persistentNet
->bandwidth
->in
);
11961 if (bandwidth
->out
) {
11962 VIR_FREE(persistentNet
->bandwidth
->out
);
11963 persistentNet
->bandwidth
->out
= bandwidth
->out
;
11964 bandwidth
->out
= NULL
;
11965 } else if (outboundSpecified
) {
11966 VIR_FREE(persistentNet
->bandwidth
->out
);
11970 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, persistentDef
) < 0)
11977 qemuDomainObjEndJob(driver
, vm
);
11980 virNetDevBandwidthFree(bandwidth
);
11981 virNetDevBandwidthFree(newBandwidth
);
11982 virDomainObjEndAPI(&vm
);
11983 virObjectUnref(cfg
);
11988 qemuDomainGetInterfaceParameters(virDomainPtr dom
,
11989 const char *device
,
11990 virTypedParameterPtr params
,
11992 unsigned int flags
)
11995 virDomainObjPtr vm
= NULL
;
11996 virDomainDefPtr def
= NULL
;
11997 virDomainNetDefPtr net
= NULL
;
12000 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
12001 VIR_DOMAIN_AFFECT_CONFIG
|
12002 VIR_TYPED_PARAM_STRING_OKAY
, -1);
12004 if (!(vm
= qemuDomObjFromDomain(dom
)))
12007 if (virDomainGetInterfaceParametersEnsureACL(dom
->conn
, vm
->def
) < 0)
12010 if (!(def
= virDomainObjGetOneDef(vm
, flags
)))
12013 if ((*nparams
) == 0) {
12014 *nparams
= QEMU_NB_BANDWIDTH_PARAM
;
12019 if (!(net
= virDomainNetFind(def
, device
)))
12022 for (i
= 0; i
< *nparams
&& i
< QEMU_NB_BANDWIDTH_PARAM
; i
++) {
12024 case 0: /* inbound.average */
12025 if (virTypedParameterAssign(¶ms
[i
],
12026 VIR_DOMAIN_BANDWIDTH_IN_AVERAGE
,
12027 VIR_TYPED_PARAM_UINT
, 0) < 0)
12029 if (net
->bandwidth
&& net
->bandwidth
->in
)
12030 params
[i
].value
.ui
= net
->bandwidth
->in
->average
;
12032 case 1: /* inbound.peak */
12033 if (virTypedParameterAssign(¶ms
[i
],
12034 VIR_DOMAIN_BANDWIDTH_IN_PEAK
,
12035 VIR_TYPED_PARAM_UINT
, 0) < 0)
12037 if (net
->bandwidth
&& net
->bandwidth
->in
)
12038 params
[i
].value
.ui
= net
->bandwidth
->in
->peak
;
12040 case 2: /* inbound.burst */
12041 if (virTypedParameterAssign(¶ms
[i
],
12042 VIR_DOMAIN_BANDWIDTH_IN_BURST
,
12043 VIR_TYPED_PARAM_UINT
, 0) < 0)
12045 if (net
->bandwidth
&& net
->bandwidth
->in
)
12046 params
[i
].value
.ui
= net
->bandwidth
->in
->burst
;
12048 case 3: /* inbound.floor */
12049 if (virTypedParameterAssign(¶ms
[i
],
12050 VIR_DOMAIN_BANDWIDTH_IN_FLOOR
,
12051 VIR_TYPED_PARAM_UINT
, 0) < 0)
12053 if (net
->bandwidth
&& net
->bandwidth
->in
)
12054 params
[i
].value
.ui
= net
->bandwidth
->in
->floor
;
12056 case 4: /* outbound.average */
12057 if (virTypedParameterAssign(¶ms
[i
],
12058 VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE
,
12059 VIR_TYPED_PARAM_UINT
, 0) < 0)
12061 if (net
->bandwidth
&& net
->bandwidth
->out
)
12062 params
[i
].value
.ui
= net
->bandwidth
->out
->average
;
12064 case 5: /* outbound.peak */
12065 if (virTypedParameterAssign(¶ms
[i
],
12066 VIR_DOMAIN_BANDWIDTH_OUT_PEAK
,
12067 VIR_TYPED_PARAM_UINT
, 0) < 0)
12069 if (net
->bandwidth
&& net
->bandwidth
->out
)
12070 params
[i
].value
.ui
= net
->bandwidth
->out
->peak
;
12072 case 6: /* outbound.burst */
12073 if (virTypedParameterAssign(¶ms
[i
],
12074 VIR_DOMAIN_BANDWIDTH_OUT_BURST
,
12075 VIR_TYPED_PARAM_UINT
, 0) < 0)
12077 if (net
->bandwidth
&& net
->bandwidth
->out
)
12078 params
[i
].value
.ui
= net
->bandwidth
->out
->burst
;
12080 /* coverity[dead_error_begin] */
12083 /* should not hit here */
12087 if (*nparams
> QEMU_NB_BANDWIDTH_PARAM
)
12088 *nparams
= QEMU_NB_BANDWIDTH_PARAM
;
12092 virDomainObjEndAPI(&vm
);
12096 /* This functions assumes that job QEMU_JOB_QUERY is started by a caller */
12098 qemuDomainMemoryStatsInternal(virQEMUDriverPtr driver
,
12099 virDomainObjPtr vm
,
12100 virDomainMemoryStatPtr stats
,
12101 unsigned int nr_stats
)
12107 if (virDomainObjCheckActive(vm
) < 0)
12110 if (virDomainDefHasMemballoon(vm
->def
)) {
12111 qemuDomainObjEnterMonitor(driver
, vm
);
12112 ret
= qemuMonitorGetMemoryStats(qemuDomainGetMonitor(vm
),
12113 vm
->def
->memballoon
, stats
, nr_stats
);
12114 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
12117 if (ret
< 0 || ret
>= nr_stats
)
12123 if (qemuGetProcessInfo(NULL
, NULL
, &rss
, vm
->pid
, 0) < 0) {
12124 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
12125 _("cannot get RSS for domain"));
12127 stats
[ret
].tag
= VIR_DOMAIN_MEMORY_STAT_RSS
;
12128 stats
[ret
].val
= rss
;
12136 qemuDomainMemoryStats(virDomainPtr dom
,
12137 virDomainMemoryStatPtr stats
,
12138 unsigned int nr_stats
,
12139 unsigned int flags
)
12141 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
12142 virDomainObjPtr vm
;
12145 virCheckFlags(0, -1);
12147 if (!(vm
= qemuDomObjFromDomain(dom
)))
12150 if (virDomainMemoryStatsEnsureACL(dom
->conn
, vm
->def
) < 0)
12153 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
12156 ret
= qemuDomainMemoryStatsInternal(driver
, vm
, stats
, nr_stats
);
12158 qemuDomainObjEndJob(driver
, vm
);
12161 virDomainObjEndAPI(&vm
);
12166 qemuDomainBlockPeek(virDomainPtr dom
,
12168 unsigned long long offset
, size_t size
,
12170 unsigned int flags
)
12172 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
12173 virDomainDiskDefPtr disk
= NULL
;
12174 virDomainObjPtr vm
;
12175 char *tmpbuf
= NULL
;
12179 virCheckFlags(0, -1);
12181 if (!(vm
= qemuDomObjFromDomain(dom
)))
12184 if (virDomainBlockPeekEnsureACL(dom
->conn
, vm
->def
) < 0)
12187 /* Check the path belongs to this domain. */
12188 if (!(disk
= virDomainDiskByName(vm
->def
, path
, true))) {
12189 virReportError(VIR_ERR_INVALID_ARG
,
12190 _("invalid disk or path '%s'"), path
);
12194 if (disk
->src
->format
!= VIR_STORAGE_FILE_RAW
) {
12195 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
12196 _("peeking is only supported for disk with 'raw' format not '%s'"),
12197 virStorageFileFormatTypeToString(disk
->src
->format
));
12201 if (qemuDomainStorageFileInit(driver
, vm
, disk
->src
, NULL
) < 0)
12204 if ((nread
= virStorageFileRead(disk
->src
, offset
, size
, &tmpbuf
)) < 0) {
12206 virReportError(VIR_ERR_INTERNAL_ERROR
,
12207 _("storage file reading is not supported for "
12208 "storage type %s (protocol: %s)"),
12209 virStorageTypeToString(disk
->src
->type
),
12210 virStorageNetProtocolTypeToString(disk
->src
->protocol
));
12215 if (nread
< size
) {
12216 virReportError(VIR_ERR_INVALID_ARG
,
12217 _("'%s' starting from %llu has only %zd bytes available"),
12218 path
, offset
, nread
);
12222 memcpy(buffer
, tmpbuf
, size
);
12228 virStorageFileDeinit(disk
->src
);
12229 virDomainObjEndAPI(&vm
);
12235 qemuDomainMemoryPeek(virDomainPtr dom
,
12236 unsigned long long offset
, size_t size
,
12238 unsigned int flags
)
12240 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
12241 virDomainObjPtr vm
;
12243 int fd
= -1, ret
= -1;
12244 qemuDomainObjPrivatePtr priv
;
12245 virQEMUDriverConfigPtr cfg
= NULL
;
12247 virCheckFlags(VIR_MEMORY_VIRTUAL
| VIR_MEMORY_PHYSICAL
, -1);
12249 if (!(vm
= qemuDomObjFromDomain(dom
)))
12252 cfg
= virQEMUDriverGetConfig(driver
);
12254 if (virDomainMemoryPeekEnsureACL(dom
->conn
, vm
->def
) < 0)
12257 if (flags
!= VIR_MEMORY_VIRTUAL
&& flags
!= VIR_MEMORY_PHYSICAL
) {
12258 virReportError(VIR_ERR_INVALID_ARG
,
12259 "%s", _("flags parameter must be VIR_MEMORY_VIRTUAL or VIR_MEMORY_PHYSICAL"));
12263 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
12266 if (virDomainObjCheckActive(vm
) < 0)
12269 if (virAsprintf(&tmp
, "%s/qemu.mem.XXXXXX", cfg
->cacheDir
) < 0)
12272 /* Create a temporary filename. */
12273 if ((fd
= mkostemp(tmp
, O_CLOEXEC
)) == -1) {
12274 virReportSystemError(errno
,
12275 _("mkostemp(\"%s\") failed"), tmp
);
12279 qemuSecuritySetSavedStateLabel(driver
, vm
, tmp
);
12281 priv
= vm
->privateData
;
12282 qemuDomainObjEnterMonitor(driver
, vm
);
12283 if (flags
== VIR_MEMORY_VIRTUAL
) {
12284 if (qemuMonitorSaveVirtualMemory(priv
->mon
, offset
, size
, tmp
) < 0) {
12285 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
12289 if (qemuMonitorSavePhysicalMemory(priv
->mon
, offset
, size
, tmp
) < 0) {
12290 ignore_value(qemuDomainObjExitMonitor(driver
, vm
));
12294 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
12297 /* Read the memory file into buffer. */
12298 if (saferead(fd
, buffer
, size
) == (ssize_t
)-1) {
12299 virReportSystemError(errno
,
12300 _("failed to read temporary file "
12301 "created with template %s"), tmp
);
12308 qemuDomainObjEndJob(driver
, vm
);
12311 VIR_FORCE_CLOSE(fd
);
12315 virDomainObjEndAPI(&vm
);
12316 virObjectUnref(cfg
);
12322 * @driver: qemu driver data
12323 * @cfg: driver configuration data
12324 * @vm: domain object
12325 * @src: storage source data
12326 * @ret_fd: pointer to return open'd file descriptor
12327 * @ret_sb: pointer to return stat buffer (local or remote)
12329 * For local storage, open the file using qemuOpenFile and then use
12330 * fstat() to grab the stat struct data for the caller.
12332 * For remote storage, attempt to access the file and grab the stat
12333 * struct data if the remote connection supports it.
12335 * Returns 0 on success with @ret_fd and @ret_sb populated, -1 on failure
12338 qemuDomainStorageOpenStat(virQEMUDriverPtr driver
,
12339 virQEMUDriverConfigPtr cfg
,
12340 virDomainObjPtr vm
,
12341 virStorageSourcePtr src
,
12343 struct stat
*ret_sb
)
12345 if (virStorageSourceIsLocalStorage(src
)) {
12346 if ((*ret_fd
= qemuOpenFile(driver
, vm
, src
->path
, O_RDONLY
,
12350 if (fstat(*ret_fd
, ret_sb
) < 0) {
12351 virReportSystemError(errno
, _("cannot stat file '%s'"), src
->path
);
12352 VIR_FORCE_CLOSE(*ret_fd
);
12356 if (virStorageFileInitAs(src
, cfg
->user
, cfg
->group
) < 0)
12359 if (virStorageFileStat(src
, ret_sb
) < 0) {
12360 virStorageFileDeinit(src
);
12361 virReportSystemError(errno
, _("failed to stat remote file '%s'"),
12362 NULLSTR(src
->path
));
12372 * @src: storage source data
12373 * @fd: file descriptor to close for local
12375 * If local, then just close the file descriptor.
12376 * else remote, then tear down the storage driver backend connection.
12379 qemuDomainStorageCloseStat(virStorageSourcePtr src
,
12382 if (virStorageSourceIsLocalStorage(src
))
12383 VIR_FORCE_CLOSE(*fd
);
12385 virStorageFileDeinit(src
);
12390 qemuDomainStorageUpdatePhysical(virQEMUDriverPtr driver
,
12391 virQEMUDriverConfigPtr cfg
,
12392 virDomainObjPtr vm
,
12393 virStorageSourcePtr src
)
12399 if (virStorageSourceIsEmpty(src
))
12402 if (qemuDomainStorageOpenStat(driver
, cfg
, vm
, src
, &fd
, &sb
) < 0)
12405 ret
= virStorageSourceUpdatePhysicalSize(src
, fd
, &sb
);
12407 qemuDomainStorageCloseStat(src
, &fd
);
12414 * @driver: qemu driver data
12415 * @cfg: driver configuration data
12416 * @vm: domain object
12417 * @src: storage source data
12419 * Refresh the capacity and allocation limits of a given storage source.
12421 * Assumes that the caller has already obtained a domain job and only
12422 * called for an offline domain. Being offline is particularly important
12423 * since reading a file while qemu is writing it risks the reader seeing
12424 * bogus data or avoiding opening a file in order to get stat data.
12426 * We always want to check current on-disk statistics (as users have been
12427 * known to change offline images behind our backs).
12429 * For read-only disks, nothing should be changing unless the user has
12430 * requested a block-commit action. For read-write disks, we know some
12431 * special cases: capacity should not change without a block-resize (where
12432 * capacity is the only stat that requires reading a file, and even then,
12433 * only for non-raw files); and physical size of a raw image or of a
12434 * block device should likewise not be changing without block-resize.
12435 * On the other hand, allocation of a raw file can change (if the file
12436 * is sparse, but the amount of sparseness changes due to writes or
12437 * punching holes), and physical size of a non-raw file can change.
12439 * Returns 0 on success, -1 on failure
12442 qemuStorageLimitsRefresh(virQEMUDriverPtr driver
,
12443 virQEMUDriverConfigPtr cfg
,
12444 virDomainObjPtr vm
,
12445 virStorageSourcePtr src
)
12453 if (qemuDomainStorageOpenStat(driver
, cfg
, vm
, src
, &fd
, &sb
) < 0)
12456 if (virStorageSourceIsLocalStorage(src
)) {
12457 if ((len
= virFileReadHeaderFD(fd
, VIR_STORAGE_MAX_HEADER
, &buf
)) < 0) {
12458 virReportSystemError(errno
, _("cannot read header '%s'"),
12463 if ((len
= virStorageFileRead(src
, 0, VIR_STORAGE_MAX_HEADER
, &buf
)) < 0)
12467 if (virStorageSourceUpdateBackingSizes(src
, fd
, &sb
) < 0)
12470 if (virStorageSourceUpdateCapacity(src
, buf
, len
, false) < 0)
12473 /* If guest is not using raw disk format and is on a host block
12474 * device, then leave the value unspecified, so caller knows to
12475 * query the highest allocated extent from QEMU
12477 if (virStorageSourceGetActualType(src
) == VIR_STORAGE_TYPE_BLOCK
&&
12478 src
->format
!= VIR_STORAGE_FILE_RAW
&&
12479 S_ISBLK(sb
.st_mode
))
12480 src
->allocation
= 0;
12486 qemuDomainStorageCloseStat(src
, &fd
);
12492 qemuDomainGetBlockInfo(virDomainPtr dom
,
12494 virDomainBlockInfoPtr info
,
12495 unsigned int flags
)
12497 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
12498 virDomainObjPtr vm
;
12500 virDomainDiskDefPtr disk
;
12501 virQEMUDriverConfigPtr cfg
= NULL
;
12502 qemuBlockStatsPtr entry
= NULL
;
12504 virCheckFlags(0, -1);
12506 if (!(vm
= qemuDomObjFromDomain(dom
)))
12509 cfg
= virQEMUDriverGetConfig(driver
);
12511 if (virDomainGetBlockInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
12514 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
12517 if (!(disk
= virDomainDiskByName(vm
->def
, path
, false))) {
12518 virReportError(VIR_ERR_INVALID_ARG
,
12519 _("invalid path %s not assigned to domain"), path
);
12523 if (virStorageSourceIsEmpty(disk
->src
)) {
12524 virReportError(VIR_ERR_INVALID_ARG
,
12525 _("disk '%s' does not currently have a source assigned"),
12530 /* for inactive domains we have to peek into the files */
12531 if (!virDomainObjIsActive(vm
)) {
12532 if ((qemuStorageLimitsRefresh(driver
, cfg
, vm
, disk
->src
)) < 0)
12535 info
->capacity
= disk
->src
->capacity
;
12536 info
->allocation
= disk
->src
->allocation
;
12537 info
->physical
= disk
->src
->physical
;
12543 if (qemuDomainBlocksStatsGather(driver
, vm
, path
, true, &entry
) < 0)
12546 if (!entry
->wr_highest_offset_valid
) {
12547 info
->allocation
= entry
->physical
;
12549 if (virStorageSourceGetActualType(disk
->src
) == VIR_STORAGE_TYPE_FILE
&&
12550 disk
->src
->format
== VIR_STORAGE_FILE_QCOW2
)
12551 info
->allocation
= entry
->physical
;
12553 info
->allocation
= entry
->wr_highest_offset
;
12556 /* Unlike GetStatsBlock, this API has defined the expected return values
12557 * for allocation and physical slightly differently.
12559 * Having a zero for either or if they're the same is an indication that
12560 * there's a sparse file backing this device. In this case, we'll force
12561 * the setting of physical based on the on disk file size.
12563 * Additionally, if qemu hasn't written to the file yet, then set the
12564 * allocation to whatever qemu returned for physical (e.g. the "actual-
12565 * size" from the json query) as that will match the expected allocation
12566 * value for this API. NB: May still be 0 for block. */
12567 if (entry
->physical
== 0 || info
->allocation
== 0 ||
12568 info
->allocation
== entry
->physical
) {
12569 if (info
->allocation
== 0)
12570 info
->allocation
= entry
->physical
;
12572 if (qemuDomainStorageUpdatePhysical(driver
, cfg
, vm
, disk
->src
) == 0) {
12573 info
->physical
= disk
->src
->physical
;
12575 virResetLastError();
12576 info
->physical
= entry
->physical
;
12579 info
->physical
= entry
->physical
;
12582 info
->capacity
= entry
->capacity
;
12587 qemuDomainObjEndJob(driver
, vm
);
12590 virDomainObjEndAPI(&vm
);
12591 virObjectUnref(cfg
);
12597 qemuConnectDomainEventRegister(virConnectPtr conn
,
12598 virConnectDomainEventCallback callback
,
12600 virFreeCallback freecb
)
12602 virQEMUDriverPtr driver
= conn
->privateData
;
12605 if (virConnectDomainEventRegisterEnsureACL(conn
) < 0)
12608 if (virDomainEventStateRegister(conn
,
12609 driver
->domainEventState
,
12610 callback
, opaque
, freecb
) < 0)
12621 qemuConnectDomainEventDeregister(virConnectPtr conn
,
12622 virConnectDomainEventCallback callback
)
12624 virQEMUDriverPtr driver
= conn
->privateData
;
12627 if (virConnectDomainEventDeregisterEnsureACL(conn
) < 0)
12630 if (virDomainEventStateDeregister(conn
,
12631 driver
->domainEventState
,
12643 qemuConnectDomainEventRegisterAny(virConnectPtr conn
,
12646 virConnectDomainEventGenericCallback callback
,
12648 virFreeCallback freecb
)
12650 virQEMUDriverPtr driver
= conn
->privateData
;
12653 if (virConnectDomainEventRegisterAnyEnsureACL(conn
) < 0)
12656 if (virDomainEventStateRegisterID(conn
,
12657 driver
->domainEventState
,
12659 callback
, opaque
, freecb
, &ret
) < 0)
12668 qemuConnectDomainEventDeregisterAny(virConnectPtr conn
,
12671 virQEMUDriverPtr driver
= conn
->privateData
;
12674 if (virConnectDomainEventDeregisterAnyEnsureACL(conn
) < 0)
12677 if (virObjectEventStateDeregisterID(conn
,
12678 driver
->domainEventState
,
12679 callbackID
, true) < 0)
12689 /*******************************************************************
12690 * Migration Protocol Version 2
12691 *******************************************************************/
12693 /* Prepare is the first step, and it runs on the destination host.
12695 * This version starts an empty VM listening on a localhost TCP port, and
12696 * sets up the corresponding virStream to handle the incoming data.
12699 qemuDomainMigratePrepareTunnel(virConnectPtr dconn
,
12701 unsigned long flags
,
12703 unsigned long resource ATTRIBUTE_UNUSED
,
12704 const char *dom_xml
)
12706 virQEMUDriverPtr driver
= dconn
->privateData
;
12707 virDomainDefPtr def
= NULL
;
12708 char *origname
= NULL
;
12709 qemuMigrationParamsPtr migParams
= NULL
;
12712 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
12714 if (!(flags
& VIR_MIGRATE_TUNNELLED
)) {
12715 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
12716 _("PrepareTunnel called but no TUNNELLED flag set"));
12720 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
12721 QEMU_MIGRATION_DESTINATION
)))
12724 if (virLockManagerPluginUsesState(driver
->lockManager
)) {
12725 virReportError(VIR_ERR_INTERNAL_ERROR
,
12726 _("Cannot use migrate v2 protocol with lock manager %s"),
12727 virLockManagerPluginGetName(driver
->lockManager
));
12731 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
12734 if (virDomainMigratePrepareTunnelEnsureACL(dconn
, def
) < 0)
12737 ret
= qemuMigrationDstPrepareTunnel(driver
, dconn
,
12738 NULL
, 0, NULL
, NULL
, /* No cookies in v2 */
12739 st
, &def
, origname
, migParams
, flags
);
12742 qemuMigrationParamsFree(migParams
);
12743 VIR_FREE(origname
);
12744 virDomainDefFree(def
);
12748 /* Prepare is the first step, and it runs on the destination host.
12750 * This starts an empty VM listening on a TCP port.
12752 static int ATTRIBUTE_NONNULL(5)
12753 qemuDomainMigratePrepare2(virConnectPtr dconn
,
12754 char **cookie ATTRIBUTE_UNUSED
,
12755 int *cookielen ATTRIBUTE_UNUSED
,
12756 const char *uri_in
,
12758 unsigned long flags
,
12760 unsigned long resource ATTRIBUTE_UNUSED
,
12761 const char *dom_xml
)
12763 virQEMUDriverPtr driver
= dconn
->privateData
;
12764 virDomainDefPtr def
= NULL
;
12765 char *origname
= NULL
;
12766 qemuMigrationParamsPtr migParams
= NULL
;
12769 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
12771 if (flags
& VIR_MIGRATE_TUNNELLED
) {
12772 /* this is a logical error; we never should have gotten here with
12773 * VIR_MIGRATE_TUNNELLED set
12775 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
12776 _("Tunnelled migration requested but invalid "
12777 "RPC method called"));
12781 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
12782 QEMU_MIGRATION_DESTINATION
)))
12785 if (virLockManagerPluginUsesState(driver
->lockManager
)) {
12786 virReportError(VIR_ERR_INTERNAL_ERROR
,
12787 _("Cannot use migrate v2 protocol with lock manager %s"),
12788 virLockManagerPluginGetName(driver
->lockManager
));
12792 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
12795 if (virDomainMigratePrepare2EnsureACL(dconn
, def
) < 0)
12798 /* Do not use cookies in v2 protocol, since the cookie
12799 * length was not sufficiently large, causing failures
12800 * migrating between old & new libvirtd
12802 ret
= qemuMigrationDstPrepareDirect(driver
, dconn
,
12803 NULL
, 0, NULL
, NULL
, /* No cookies */
12805 &def
, origname
, NULL
, 0, NULL
, 0,
12809 qemuMigrationParamsFree(migParams
);
12810 VIR_FREE(origname
);
12811 virDomainDefFree(def
);
12816 /* Perform is the second step, and it runs on the source host. */
12818 qemuDomainMigratePerform(virDomainPtr dom
,
12819 const char *cookie
,
12822 unsigned long flags
,
12824 unsigned long resource
)
12826 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
12827 virDomainObjPtr vm
;
12829 const char *dconnuri
= NULL
;
12830 qemuMigrationParamsPtr migParams
= NULL
;
12832 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
12834 if (virLockManagerPluginUsesState(driver
->lockManager
)) {
12835 virReportError(VIR_ERR_INTERNAL_ERROR
,
12836 _("Cannot use migrate v2 protocol with lock manager %s"),
12837 virLockManagerPluginGetName(driver
->lockManager
));
12841 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
12842 QEMU_MIGRATION_SOURCE
)))
12845 if (!(vm
= qemuDomObjFromDomain(dom
)))
12848 if (virDomainMigratePerformEnsureACL(dom
->conn
, vm
->def
) < 0) {
12849 virDomainObjEndAPI(&vm
);
12853 if (flags
& VIR_MIGRATE_PEER2PEER
)
12854 VIR_STEAL_PTR(dconnuri
, uri
);
12856 /* Do not output cookies in v2 protocol, since the cookie
12857 * length was not sufficiently large, causing failures
12858 * migrating between old & new libvirtd.
12860 * Consume any cookie we were able to decode though
12862 ret
= qemuMigrationSrcPerform(driver
, dom
->conn
, vm
, NULL
,
12863 NULL
, dconnuri
, uri
, NULL
, NULL
, 0, NULL
, 0,
12864 migParams
, cookie
, cookielen
,
12865 NULL
, NULL
, /* No output cookies in v2 */
12866 flags
, dname
, resource
, false);
12869 qemuMigrationParamsFree(migParams
);
12874 /* Finish is the third and final step, and it runs on the destination host. */
12875 static virDomainPtr
12876 qemuDomainMigrateFinish2(virConnectPtr dconn
,
12878 const char *cookie ATTRIBUTE_UNUSED
,
12879 int cookielen ATTRIBUTE_UNUSED
,
12880 const char *uri ATTRIBUTE_UNUSED
,
12881 unsigned long flags
,
12884 virQEMUDriverPtr driver
= dconn
->privateData
;
12885 virDomainObjPtr vm
;
12886 virDomainPtr dom
= NULL
;
12888 virCheckFlags(QEMU_MIGRATION_FLAGS
, NULL
);
12890 vm
= virDomainObjListFindByName(driver
->domains
, dname
);
12892 virReportError(VIR_ERR_NO_DOMAIN
,
12893 _("no domain with matching name '%s'"), dname
);
12894 qemuMigrationDstErrorReport(driver
, dname
);
12898 if (virDomainMigrateFinish2EnsureACL(dconn
, vm
->def
) < 0) {
12899 virDomainObjEndAPI(&vm
);
12903 /* Do not use cookies in v2 protocol, since the cookie
12904 * length was not sufficiently large, causing failures
12905 * migrating between old & new libvirtd
12907 dom
= qemuMigrationDstFinish(driver
, dconn
, vm
,
12908 NULL
, 0, NULL
, NULL
, /* No cookies */
12909 flags
, retcode
, false);
12916 /*******************************************************************
12917 * Migration Protocol Version 3
12918 *******************************************************************/
12921 qemuDomainMigrateBegin3(virDomainPtr domain
,
12925 unsigned long flags
,
12927 unsigned long resource ATTRIBUTE_UNUSED
)
12929 virDomainObjPtr vm
;
12931 virCheckFlags(QEMU_MIGRATION_FLAGS
, NULL
);
12933 if (!(vm
= qemuDomObjFromDomain(domain
)))
12936 if (virDomainMigrateBegin3EnsureACL(domain
->conn
, vm
->def
) < 0) {
12937 virDomainObjEndAPI(&vm
);
12941 return qemuMigrationSrcBegin(domain
->conn
, vm
, xmlin
, dname
,
12942 cookieout
, cookieoutlen
, 0, NULL
, flags
);
12946 qemuDomainMigrateBegin3Params(virDomainPtr domain
,
12947 virTypedParameterPtr params
,
12951 unsigned int flags
)
12953 const char *xmlin
= NULL
;
12954 const char *dname
= NULL
;
12955 const char **migrate_disks
= NULL
;
12956 int nmigrate_disks
;
12958 virDomainObjPtr vm
;
12960 virCheckFlags(QEMU_MIGRATION_FLAGS
, NULL
);
12961 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
12964 if (virTypedParamsGetString(params
, nparams
,
12965 VIR_MIGRATE_PARAM_DEST_XML
,
12967 virTypedParamsGetString(params
, nparams
,
12968 VIR_MIGRATE_PARAM_DEST_NAME
,
12972 nmigrate_disks
= virTypedParamsGetStringList(params
, nparams
,
12973 VIR_MIGRATE_PARAM_MIGRATE_DISKS
,
12976 if (nmigrate_disks
< 0)
12979 if (!(vm
= qemuDomObjFromDomain(domain
)))
12982 if (virDomainMigrateBegin3ParamsEnsureACL(domain
->conn
, vm
->def
) < 0) {
12983 virDomainObjEndAPI(&vm
);
12987 ret
= qemuMigrationSrcBegin(domain
->conn
, vm
, xmlin
, dname
,
12988 cookieout
, cookieoutlen
,
12989 nmigrate_disks
, migrate_disks
, flags
);
12992 VIR_FREE(migrate_disks
);
12998 qemuDomainMigratePrepare3(virConnectPtr dconn
,
12999 const char *cookiein
,
13003 const char *uri_in
,
13005 unsigned long flags
,
13007 unsigned long resource ATTRIBUTE_UNUSED
,
13008 const char *dom_xml
)
13010 virQEMUDriverPtr driver
= dconn
->privateData
;
13011 virDomainDefPtr def
= NULL
;
13012 char *origname
= NULL
;
13013 qemuMigrationParamsPtr migParams
= NULL
;
13016 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13018 if (flags
& VIR_MIGRATE_TUNNELLED
) {
13019 /* this is a logical error; we never should have gotten here with
13020 * VIR_MIGRATE_TUNNELLED set
13022 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
13023 _("Tunnelled migration requested but invalid "
13024 "RPC method called"));
13028 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
13029 QEMU_MIGRATION_DESTINATION
)))
13032 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
13035 if (virDomainMigratePrepare3EnsureACL(dconn
, def
) < 0)
13038 ret
= qemuMigrationDstPrepareDirect(driver
, dconn
,
13039 cookiein
, cookieinlen
,
13040 cookieout
, cookieoutlen
,
13042 &def
, origname
, NULL
, 0, NULL
, 0,
13046 qemuMigrationParamsFree(migParams
);
13047 VIR_FREE(origname
);
13048 virDomainDefFree(def
);
13053 qemuDomainMigratePrepare3Params(virConnectPtr dconn
,
13054 virTypedParameterPtr params
,
13056 const char *cookiein
,
13061 unsigned int flags
)
13063 virQEMUDriverPtr driver
= dconn
->privateData
;
13064 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
13065 virDomainDefPtr def
= NULL
;
13066 const char *dom_xml
= NULL
;
13067 const char *dname
= NULL
;
13068 const char *uri_in
= NULL
;
13069 const char *listenAddress
= cfg
->migrationAddress
;
13071 int nmigrate_disks
;
13072 const char **migrate_disks
= NULL
;
13073 char *origname
= NULL
;
13074 qemuMigrationParamsPtr migParams
= NULL
;
13077 virCheckFlagsGoto(QEMU_MIGRATION_FLAGS
, cleanup
);
13078 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
13081 if (virTypedParamsGetString(params
, nparams
,
13082 VIR_MIGRATE_PARAM_DEST_XML
,
13084 virTypedParamsGetString(params
, nparams
,
13085 VIR_MIGRATE_PARAM_DEST_NAME
,
13087 virTypedParamsGetString(params
, nparams
,
13088 VIR_MIGRATE_PARAM_URI
,
13090 virTypedParamsGetString(params
, nparams
,
13091 VIR_MIGRATE_PARAM_LISTEN_ADDRESS
,
13092 &listenAddress
) < 0 ||
13093 virTypedParamsGetInt(params
, nparams
,
13094 VIR_MIGRATE_PARAM_DISKS_PORT
,
13098 nmigrate_disks
= virTypedParamsGetStringList(params
, nparams
,
13099 VIR_MIGRATE_PARAM_MIGRATE_DISKS
,
13102 if (nmigrate_disks
< 0)
13105 if (!(migParams
= qemuMigrationParamsFromFlags(params
, nparams
, flags
,
13106 QEMU_MIGRATION_DESTINATION
)))
13109 if (flags
& VIR_MIGRATE_TUNNELLED
) {
13110 /* this is a logical error; we never should have gotten here with
13111 * VIR_MIGRATE_TUNNELLED set
13113 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
13114 _("Tunnelled migration requested but invalid "
13115 "RPC method called"));
13119 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
13122 if (virDomainMigratePrepare3ParamsEnsureACL(dconn
, def
) < 0)
13125 ret
= qemuMigrationDstPrepareDirect(driver
, dconn
,
13126 cookiein
, cookieinlen
,
13127 cookieout
, cookieoutlen
,
13129 &def
, origname
, listenAddress
,
13130 nmigrate_disks
, migrate_disks
, nbdPort
,
13134 qemuMigrationParamsFree(migParams
);
13135 VIR_FREE(migrate_disks
);
13136 VIR_FREE(origname
);
13137 virDomainDefFree(def
);
13138 virObjectUnref(cfg
);
13144 qemuDomainMigratePrepareTunnel3(virConnectPtr dconn
,
13146 const char *cookiein
,
13150 unsigned long flags
,
13152 unsigned long resource ATTRIBUTE_UNUSED
,
13153 const char *dom_xml
)
13155 virQEMUDriverPtr driver
= dconn
->privateData
;
13156 virDomainDefPtr def
= NULL
;
13157 char *origname
= NULL
;
13158 qemuMigrationParamsPtr migParams
= NULL
;
13161 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13163 if (!(flags
& VIR_MIGRATE_TUNNELLED
)) {
13164 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
13165 _("PrepareTunnel called but no TUNNELLED flag set"));
13169 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
13170 QEMU_MIGRATION_DESTINATION
)))
13173 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
13176 if (virDomainMigratePrepareTunnel3EnsureACL(dconn
, def
) < 0)
13179 ret
= qemuMigrationDstPrepareTunnel(driver
, dconn
,
13180 cookiein
, cookieinlen
,
13181 cookieout
, cookieoutlen
,
13182 st
, &def
, origname
, migParams
, flags
);
13185 qemuMigrationParamsFree(migParams
);
13186 VIR_FREE(origname
);
13187 virDomainDefFree(def
);
13192 qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn
,
13194 virTypedParameterPtr params
,
13196 const char *cookiein
,
13200 unsigned int flags
)
13202 virQEMUDriverPtr driver
= dconn
->privateData
;
13203 virDomainDefPtr def
= NULL
;
13204 const char *dom_xml
= NULL
;
13205 const char *dname
= NULL
;
13206 char *origname
= NULL
;
13207 qemuMigrationParamsPtr migParams
= NULL
;
13210 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13211 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
13214 if (virTypedParamsGetString(params
, nparams
,
13215 VIR_MIGRATE_PARAM_DEST_XML
,
13217 virTypedParamsGetString(params
, nparams
,
13218 VIR_MIGRATE_PARAM_DEST_NAME
,
13222 if (!(flags
& VIR_MIGRATE_TUNNELLED
)) {
13223 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
13224 _("PrepareTunnel called but no TUNNELLED flag set"));
13228 if (!(migParams
= qemuMigrationParamsFromFlags(params
, nparams
, flags
,
13229 QEMU_MIGRATION_DESTINATION
)))
13232 if (!(def
= qemuMigrationAnyPrepareDef(driver
, dom_xml
, dname
, &origname
)))
13235 if (virDomainMigratePrepareTunnel3ParamsEnsureACL(dconn
, def
) < 0)
13238 ret
= qemuMigrationDstPrepareTunnel(driver
, dconn
,
13239 cookiein
, cookieinlen
,
13240 cookieout
, cookieoutlen
,
13241 st
, &def
, origname
, migParams
, flags
);
13244 qemuMigrationParamsFree(migParams
);
13245 VIR_FREE(origname
);
13246 virDomainDefFree(def
);
13252 qemuDomainMigratePerform3(virDomainPtr dom
,
13254 const char *cookiein
,
13258 const char *dconnuri
,
13260 unsigned long flags
,
13262 unsigned long resource
)
13264 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
13265 virDomainObjPtr vm
;
13266 qemuMigrationParamsPtr migParams
= NULL
;
13269 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13271 if (!(migParams
= qemuMigrationParamsFromFlags(NULL
, 0, flags
,
13272 QEMU_MIGRATION_SOURCE
)))
13275 if (!(vm
= qemuDomObjFromDomain(dom
)))
13278 if (virDomainMigratePerform3EnsureACL(dom
->conn
, vm
->def
) < 0) {
13279 virDomainObjEndAPI(&vm
);
13283 ret
= qemuMigrationSrcPerform(driver
, dom
->conn
, vm
, xmlin
, NULL
,
13284 dconnuri
, uri
, NULL
, NULL
, 0, NULL
, 0,
13286 cookiein
, cookieinlen
,
13287 cookieout
, cookieoutlen
,
13288 flags
, dname
, resource
, true);
13291 qemuMigrationParamsFree(migParams
);
13296 qemuDomainMigratePerform3Params(virDomainPtr dom
,
13297 const char *dconnuri
,
13298 virTypedParameterPtr params
,
13300 const char *cookiein
,
13304 unsigned int flags
)
13306 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
13307 virDomainObjPtr vm
;
13308 const char *dom_xml
= NULL
;
13309 const char *persist_xml
= NULL
;
13310 const char *dname
= NULL
;
13311 const char *uri
= NULL
;
13312 const char *graphicsuri
= NULL
;
13313 const char *listenAddress
= NULL
;
13314 int nmigrate_disks
;
13315 const char **migrate_disks
= NULL
;
13316 unsigned long long bandwidth
= 0;
13318 qemuMigrationParamsPtr migParams
= NULL
;
13321 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13322 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
13325 if (virTypedParamsGetString(params
, nparams
,
13326 VIR_MIGRATE_PARAM_DEST_XML
,
13328 virTypedParamsGetString(params
, nparams
,
13329 VIR_MIGRATE_PARAM_DEST_NAME
,
13331 virTypedParamsGetString(params
, nparams
,
13332 VIR_MIGRATE_PARAM_URI
,
13334 virTypedParamsGetULLong(params
, nparams
,
13335 VIR_MIGRATE_PARAM_BANDWIDTH
,
13337 virTypedParamsGetString(params
, nparams
,
13338 VIR_MIGRATE_PARAM_GRAPHICS_URI
,
13339 &graphicsuri
) < 0 ||
13340 virTypedParamsGetString(params
, nparams
,
13341 VIR_MIGRATE_PARAM_LISTEN_ADDRESS
,
13342 &listenAddress
) < 0 ||
13343 virTypedParamsGetInt(params
, nparams
,
13344 VIR_MIGRATE_PARAM_DISKS_PORT
,
13346 virTypedParamsGetString(params
, nparams
,
13347 VIR_MIGRATE_PARAM_PERSIST_XML
,
13351 nmigrate_disks
= virTypedParamsGetStringList(params
, nparams
,
13352 VIR_MIGRATE_PARAM_MIGRATE_DISKS
,
13355 if (nmigrate_disks
< 0)
13358 if (!(migParams
= qemuMigrationParamsFromFlags(params
, nparams
, flags
,
13359 QEMU_MIGRATION_SOURCE
)))
13362 if (!(vm
= qemuDomObjFromDomain(dom
)))
13365 if (virDomainMigratePerform3ParamsEnsureACL(dom
->conn
, vm
->def
) < 0) {
13366 virDomainObjEndAPI(&vm
);
13370 ret
= qemuMigrationSrcPerform(driver
, dom
->conn
, vm
, dom_xml
, persist_xml
,
13371 dconnuri
, uri
, graphicsuri
, listenAddress
,
13372 nmigrate_disks
, migrate_disks
, nbdPort
,
13374 cookiein
, cookieinlen
, cookieout
, cookieoutlen
,
13375 flags
, dname
, bandwidth
, true);
13377 qemuMigrationParamsFree(migParams
);
13378 VIR_FREE(migrate_disks
);
13383 static virDomainPtr
13384 qemuDomainMigrateFinish3(virConnectPtr dconn
,
13386 const char *cookiein
,
13390 const char *dconnuri ATTRIBUTE_UNUSED
,
13391 const char *uri ATTRIBUTE_UNUSED
,
13392 unsigned long flags
,
13395 virQEMUDriverPtr driver
= dconn
->privateData
;
13396 virDomainObjPtr vm
;
13398 virCheckFlags(QEMU_MIGRATION_FLAGS
, NULL
);
13401 virReportError(VIR_ERR_NO_DOMAIN
, "%s", _("missing domain name"));
13405 vm
= virDomainObjListFindByName(driver
->domains
, dname
);
13407 virReportError(VIR_ERR_NO_DOMAIN
,
13408 _("no domain with matching name '%s'"), dname
);
13409 qemuMigrationDstErrorReport(driver
, dname
);
13413 if (virDomainMigrateFinish3EnsureACL(dconn
, vm
->def
) < 0) {
13414 virDomainObjEndAPI(&vm
);
13418 return qemuMigrationDstFinish(driver
, dconn
, vm
,
13419 cookiein
, cookieinlen
,
13420 cookieout
, cookieoutlen
,
13421 flags
, cancelled
, true);
13424 static virDomainPtr
13425 qemuDomainMigrateFinish3Params(virConnectPtr dconn
,
13426 virTypedParameterPtr params
,
13428 const char *cookiein
,
13432 unsigned int flags
,
13435 virQEMUDriverPtr driver
= dconn
->privateData
;
13436 virDomainObjPtr vm
;
13437 const char *dname
= NULL
;
13439 virCheckFlags(QEMU_MIGRATION_FLAGS
, NULL
);
13440 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
13443 if (virTypedParamsGetString(params
, nparams
,
13444 VIR_MIGRATE_PARAM_DEST_NAME
,
13449 virReportError(VIR_ERR_NO_DOMAIN
, "%s", _("missing domain name"));
13453 vm
= virDomainObjListFindByName(driver
->domains
, dname
);
13455 virReportError(VIR_ERR_NO_DOMAIN
,
13456 _("no domain with matching name '%s'"), dname
);
13457 qemuMigrationDstErrorReport(driver
, dname
);
13461 if (virDomainMigrateFinish3ParamsEnsureACL(dconn
, vm
->def
) < 0) {
13462 virDomainObjEndAPI(&vm
);
13466 return qemuMigrationDstFinish(driver
, dconn
, vm
,
13467 cookiein
, cookieinlen
,
13468 cookieout
, cookieoutlen
,
13469 flags
, cancelled
, true);
13474 qemuDomainMigrateConfirm3(virDomainPtr domain
,
13475 const char *cookiein
,
13477 unsigned long flags
,
13480 virDomainObjPtr vm
;
13482 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13484 if (!(vm
= qemuDomObjFromDomain(domain
)))
13487 if (virDomainMigrateConfirm3EnsureACL(domain
->conn
, vm
->def
) < 0) {
13488 virDomainObjEndAPI(&vm
);
13492 return qemuMigrationSrcConfirm(domain
->conn
->privateData
, vm
, cookiein
, cookieinlen
,
13497 qemuDomainMigrateConfirm3Params(virDomainPtr domain
,
13498 virTypedParameterPtr params
,
13500 const char *cookiein
,
13502 unsigned int flags
,
13505 virDomainObjPtr vm
;
13507 virCheckFlags(QEMU_MIGRATION_FLAGS
, -1);
13509 if (virTypedParamsValidate(params
, nparams
, QEMU_MIGRATION_PARAMETERS
) < 0)
13512 if (!(vm
= qemuDomObjFromDomain(domain
)))
13515 if (virDomainMigrateConfirm3ParamsEnsureACL(domain
->conn
, vm
->def
) < 0) {
13516 virDomainObjEndAPI(&vm
);
13520 return qemuMigrationSrcConfirm(domain
->conn
->privateData
, vm
, cookiein
, cookieinlen
,
13526 qemuNodeDeviceGetPCIInfo(virNodeDeviceDefPtr def
,
13530 unsigned *function
)
13532 virNodeDevCapsDefPtr cap
;
13537 if (cap
->data
.type
== VIR_NODE_DEV_CAP_PCI_DEV
) {
13538 *domain
= cap
->data
.pci_dev
.domain
;
13539 *bus
= cap
->data
.pci_dev
.bus
;
13540 *slot
= cap
->data
.pci_dev
.slot
;
13541 *function
= cap
->data
.pci_dev
.function
;
13549 virReportError(VIR_ERR_INVALID_ARG
,
13550 _("device %s is not a PCI device"), def
->name
);
13560 qemuNodeDeviceDetachFlags(virNodeDevicePtr dev
,
13561 const char *driverName
,
13562 unsigned int flags
)
13564 virQEMUDriverPtr driver
= dev
->conn
->privateData
;
13565 virPCIDevicePtr pci
= NULL
;
13566 unsigned domain
= 0, bus
= 0, slot
= 0, function
= 0;
13568 virNodeDeviceDefPtr def
= NULL
;
13570 bool legacy
= qemuHostdevHostSupportsPassthroughLegacy();
13571 bool vfio
= qemuHostdevHostSupportsPassthroughVFIO();
13572 virHostdevManagerPtr hostdev_mgr
= driver
->hostdevMgr
;
13574 virCheckFlags(0, -1);
13576 xml
= virNodeDeviceGetXMLDesc(dev
, 0);
13580 def
= virNodeDeviceDefParseString(xml
, EXISTING_DEVICE
, NULL
);
13584 if (virNodeDeviceDetachFlagsEnsureACL(dev
->conn
, def
) < 0)
13587 if (qemuNodeDeviceGetPCIInfo(def
, &domain
, &bus
, &slot
, &function
) < 0)
13590 pci
= virPCIDeviceNew(domain
, bus
, slot
, function
);
13596 driverName
= "vfio";
13597 } else if (legacy
) {
13598 driverName
= "kvm";
13600 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
13601 _("neither VFIO nor KVM device assignment is "
13602 "currently supported on this system"));
13607 if (STREQ(driverName
, "vfio")) {
13609 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
13610 _("VFIO device assignment is currently not "
13611 "supported on this system"));
13614 virPCIDeviceSetStubDriver(pci
, VIR_PCI_STUB_DRIVER_VFIO
);
13615 } else if (STREQ(driverName
, "kvm")) {
13617 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
13618 _("KVM device assignment is currently not "
13619 "supported on this system"));
13622 virPCIDeviceSetStubDriver(pci
, VIR_PCI_STUB_DRIVER_KVM
);
13624 virReportError(VIR_ERR_INVALID_ARG
,
13625 _("unknown driver name '%s'"), driverName
);
13629 ret
= virHostdevPCINodeDeviceDetach(hostdev_mgr
, pci
);
13631 virPCIDeviceFree(pci
);
13632 virNodeDeviceDefFree(def
);
13638 qemuNodeDeviceDettach(virNodeDevicePtr dev
)
13640 return qemuNodeDeviceDetachFlags(dev
, NULL
, 0);
13644 qemuNodeDeviceReAttach(virNodeDevicePtr dev
)
13646 virQEMUDriverPtr driver
= dev
->conn
->privateData
;
13647 virPCIDevicePtr pci
= NULL
;
13648 unsigned domain
= 0, bus
= 0, slot
= 0, function
= 0;
13650 virNodeDeviceDefPtr def
= NULL
;
13652 virHostdevManagerPtr hostdev_mgr
= driver
->hostdevMgr
;
13654 xml
= virNodeDeviceGetXMLDesc(dev
, 0);
13658 def
= virNodeDeviceDefParseString(xml
, EXISTING_DEVICE
, NULL
);
13662 if (virNodeDeviceReAttachEnsureACL(dev
->conn
, def
) < 0)
13665 if (qemuNodeDeviceGetPCIInfo(def
, &domain
, &bus
, &slot
, &function
) < 0)
13668 pci
= virPCIDeviceNew(domain
, bus
, slot
, function
);
13672 ret
= virHostdevPCINodeDeviceReAttach(hostdev_mgr
, pci
);
13674 virPCIDeviceFree(pci
);
13676 virNodeDeviceDefFree(def
);
13682 qemuNodeDeviceReset(virNodeDevicePtr dev
)
13684 virQEMUDriverPtr driver
= dev
->conn
->privateData
;
13685 virPCIDevicePtr pci
;
13686 unsigned domain
= 0, bus
= 0, slot
= 0, function
= 0;
13688 virNodeDeviceDefPtr def
= NULL
;
13690 virHostdevManagerPtr hostdev_mgr
= driver
->hostdevMgr
;
13692 xml
= virNodeDeviceGetXMLDesc(dev
, 0);
13696 def
= virNodeDeviceDefParseString(xml
, EXISTING_DEVICE
, NULL
);
13700 if (virNodeDeviceResetEnsureACL(dev
->conn
, def
) < 0)
13703 if (qemuNodeDeviceGetPCIInfo(def
, &domain
, &bus
, &slot
, &function
) < 0)
13706 pci
= virPCIDeviceNew(domain
, bus
, slot
, function
);
13710 ret
= virHostdevPCINodeDeviceReset(hostdev_mgr
, pci
);
13712 virPCIDeviceFree(pci
);
13714 virNodeDeviceDefFree(def
);
13720 qemuConnectCompareCPU(virConnectPtr conn
,
13721 const char *xmlDesc
,
13722 unsigned int flags
)
13724 virQEMUDriverPtr driver
= conn
->privateData
;
13725 int ret
= VIR_CPU_COMPARE_ERROR
;
13726 virCapsPtr caps
= NULL
;
13727 bool failIncompatible
;
13729 virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE
,
13730 VIR_CPU_COMPARE_ERROR
);
13732 if (virConnectCompareCPUEnsureACL(conn
) < 0)
13735 failIncompatible
= !!(flags
& VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE
);
13737 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
13740 ret
= virCPUCompareXML(caps
->host
.arch
, caps
->host
.cpu
,
13741 xmlDesc
, failIncompatible
);
13744 virObjectUnref(caps
);
13750 qemuConnectCompareHypervisorCPU(virConnectPtr conn
,
13751 const char *emulator
,
13752 const char *archStr
,
13753 const char *machine
,
13754 const char *virttypeStr
,
13755 const char *xmlCPU
,
13756 unsigned int flags
)
13758 int ret
= VIR_CPU_COMPARE_ERROR
;
13759 virQEMUDriverPtr driver
= conn
->privateData
;
13760 virQEMUCapsPtr qemuCaps
= NULL
;
13761 bool failIncompatible
;
13762 virCPUDefPtr hvCPU
;
13764 virDomainVirtType virttype
;
13766 virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE
,
13767 VIR_CPU_COMPARE_ERROR
);
13769 if (virConnectCompareHypervisorCPUEnsureACL(conn
) < 0)
13772 failIncompatible
= !!(flags
& VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE
);
13774 qemuCaps
= virQEMUCapsCacheLookupDefault(driver
->qemuCapsCache
,
13779 &arch
, &virttype
, NULL
);
13783 hvCPU
= virQEMUCapsGetHostModel(qemuCaps
, virttype
,
13784 VIR_QEMU_CAPS_HOST_CPU_REPORTED
);
13786 if (!hvCPU
|| hvCPU
->fallback
!= VIR_CPU_FALLBACK_FORBID
) {
13787 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
13788 _("QEMU '%s' does not support reporting CPU model for "
13790 virQEMUCapsGetBinary(qemuCaps
),
13791 virDomainVirtTypeToString(virttype
));
13795 if (ARCH_IS_X86(arch
)) {
13796 ret
= virCPUCompareXML(arch
, hvCPU
, xmlCPU
, failIncompatible
);
13798 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
13799 _("comparing with the hypervisor CPU is not supported "
13800 "for arch %s"), virArchToString(arch
));
13804 virObjectUnref(qemuCaps
);
13810 qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED
,
13811 const char **xmlCPUs
,
13812 unsigned int ncpus
,
13813 unsigned int flags
)
13815 virCPUDefPtr
*cpus
= NULL
;
13816 virCPUDefPtr baseline
= NULL
;
13817 virCPUDefPtr cpu
= NULL
;
13818 char *cpustr
= NULL
;
13820 virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES
|
13821 VIR_CONNECT_BASELINE_CPU_MIGRATABLE
, NULL
);
13823 if (virConnectBaselineCPUEnsureACL(conn
) < 0)
13826 if (!(cpus
= virCPUDefListParse(xmlCPUs
, ncpus
, VIR_CPU_TYPE_HOST
)))
13829 if (!(baseline
= virCPUBaseline(VIR_ARCH_NONE
, cpus
, ncpus
, NULL
, NULL
,
13830 !!(flags
& VIR_CONNECT_BASELINE_CPU_MIGRATABLE
))))
13833 if (!(cpu
= virCPUDefCopyWithoutModel(baseline
)))
13836 if (virCPUDefCopyModelFilter(cpu
, baseline
, false,
13837 virQEMUCapsCPUFilterFeatures
,
13838 &cpus
[0]->arch
) < 0)
13841 if ((flags
& VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES
) &&
13842 virCPUExpandFeatures(cpus
[0]->arch
, cpu
) < 0)
13845 cpustr
= virCPUDefFormat(cpu
, NULL
);
13848 virCPUDefListFree(cpus
);
13849 virCPUDefFree(baseline
);
13850 virCPUDefFree(cpu
);
13857 qemuConnectBaselineHypervisorCPU(virConnectPtr conn
,
13858 const char *emulator
,
13859 const char *archStr
,
13860 const char *machine
,
13861 const char *virttypeStr
,
13862 const char **xmlCPUs
,
13863 unsigned int ncpus
,
13864 unsigned int flags
)
13866 virQEMUDriverPtr driver
= conn
->privateData
;
13867 virCPUDefPtr
*cpus
= NULL
;
13868 virQEMUCapsPtr qemuCaps
= NULL
;
13870 virDomainVirtType virttype
;
13871 virDomainCapsCPUModelsPtr cpuModels
;
13873 virCPUDefPtr cpu
= NULL
;
13874 char *cpustr
= NULL
;
13875 char **features
= NULL
;
13877 virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES
|
13878 VIR_CONNECT_BASELINE_CPU_MIGRATABLE
, NULL
);
13880 if (virConnectBaselineHypervisorCPUEnsureACL(conn
) < 0)
13883 migratable
= !!(flags
& VIR_CONNECT_BASELINE_CPU_MIGRATABLE
);
13885 if (!(cpus
= virCPUDefListParse(xmlCPUs
, ncpus
, VIR_CPU_TYPE_AUTO
)))
13888 qemuCaps
= virQEMUCapsCacheLookupDefault(driver
->qemuCapsCache
,
13893 &arch
, &virttype
, NULL
);
13897 if (!(cpuModels
= virQEMUCapsGetCPUDefinitions(qemuCaps
, virttype
)) ||
13898 cpuModels
->nmodels
== 0) {
13899 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
13900 _("QEMU '%s' does not support any CPU models for "
13902 virQEMUCapsGetBinary(qemuCaps
),
13903 virDomainVirtTypeToString(virttype
));
13907 if (ARCH_IS_X86(arch
)) {
13908 int rc
= virQEMUCapsGetCPUFeatures(qemuCaps
, virttype
,
13909 migratable
, &features
);
13912 if (features
&& rc
== 0) {
13913 /* We got only migratable features from QEMU if we asked for them,
13914 * no further filtering in virCPUBaseline is desired. */
13915 migratable
= false;
13918 if (!(cpu
= virCPUBaseline(arch
, cpus
, ncpus
, cpuModels
,
13919 (const char **)features
, migratable
)))
13922 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
13923 _("computing baseline hypervisor CPU is not supported "
13924 "for arch %s"), virArchToString(arch
));
13928 cpu
->fallback
= VIR_CPU_FALLBACK_FORBID
;
13930 if ((flags
& VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES
) &&
13931 virCPUExpandFeatures(arch
, cpu
) < 0)
13934 cpustr
= virCPUDefFormat(cpu
, NULL
);
13937 virCPUDefListFree(cpus
);
13938 virCPUDefFree(cpu
);
13939 virObjectUnref(qemuCaps
);
13940 virStringListFree(features
);
13947 qemuDomainGetJobInfoMigrationStats(virQEMUDriverPtr driver
,
13948 virDomainObjPtr vm
,
13949 qemuDomainJobInfoPtr jobInfo
)
13951 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
13952 bool events
= virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_MIGRATION_EVENT
);
13954 if (jobInfo
->status
== QEMU_DOMAIN_JOB_STATUS_ACTIVE
||
13955 jobInfo
->status
== QEMU_DOMAIN_JOB_STATUS_MIGRATING
||
13956 jobInfo
->status
== QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED
||
13957 jobInfo
->status
== QEMU_DOMAIN_JOB_STATUS_POSTCOPY
) {
13959 jobInfo
->status
!= QEMU_DOMAIN_JOB_STATUS_ACTIVE
&&
13960 qemuMigrationAnyFetchStats(driver
, vm
, QEMU_ASYNC_JOB_NONE
,
13961 jobInfo
, NULL
) < 0)
13964 if (jobInfo
->status
== QEMU_DOMAIN_JOB_STATUS_ACTIVE
&&
13965 jobInfo
->statsType
== QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION
&&
13966 qemuMigrationSrcFetchMirrorStats(driver
, vm
, QEMU_ASYNC_JOB_NONE
,
13970 if (qemuDomainJobInfoUpdateTime(jobInfo
) < 0)
13979 qemuDomainGetJobInfoDumpStats(virQEMUDriverPtr driver
,
13980 virDomainObjPtr vm
,
13981 qemuDomainJobInfoPtr jobInfo
)
13983 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
13984 qemuMonitorDumpStats stats
= { 0 };
13987 if (qemuDomainObjEnterMonitorAsync(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
13990 rc
= qemuMonitorQueryDump(priv
->mon
, &stats
);
13992 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || rc
< 0)
13995 jobInfo
->stats
.dump
= stats
;
13997 if (qemuDomainJobInfoUpdateTime(jobInfo
) < 0)
14000 switch (jobInfo
->stats
.dump
.status
) {
14001 case QEMU_MONITOR_DUMP_STATUS_NONE
:
14002 case QEMU_MONITOR_DUMP_STATUS_FAILED
:
14003 case QEMU_MONITOR_DUMP_STATUS_LAST
:
14004 virReportError(VIR_ERR_OPERATION_FAILED
,
14005 _("dump query failed, status=%d"),
14006 jobInfo
->stats
.dump
.status
);
14010 case QEMU_MONITOR_DUMP_STATUS_ACTIVE
:
14011 jobInfo
->status
= QEMU_DOMAIN_JOB_STATUS_ACTIVE
;
14012 VIR_DEBUG("dump active, bytes written='%llu' remaining='%llu'",
14013 jobInfo
->stats
.dump
.completed
,
14014 jobInfo
->stats
.dump
.total
-
14015 jobInfo
->stats
.dump
.completed
);
14018 case QEMU_MONITOR_DUMP_STATUS_COMPLETED
:
14019 jobInfo
->status
= QEMU_DOMAIN_JOB_STATUS_COMPLETED
;
14020 VIR_DEBUG("dump completed, bytes written='%llu'",
14021 jobInfo
->stats
.dump
.completed
);
14030 qemuDomainGetJobStatsInternal(virQEMUDriverPtr driver
,
14031 virDomainObjPtr vm
,
14033 qemuDomainJobInfoPtr jobInfo
)
14035 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
14039 if (priv
->job
.completed
&& !priv
->job
.current
)
14040 *jobInfo
= *priv
->job
.completed
;
14042 jobInfo
->status
= QEMU_DOMAIN_JOB_STATUS_NONE
;
14047 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_IN
) {
14048 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
14049 _("migration statistics are available only on "
14050 "the source host"));
14054 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
14057 if (virDomainObjCheckActive(vm
) < 0)
14060 if (!priv
->job
.current
) {
14061 jobInfo
->status
= QEMU_DOMAIN_JOB_STATUS_NONE
;
14065 *jobInfo
= *priv
->job
.current
;
14067 switch (jobInfo
->statsType
) {
14068 case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION
:
14069 case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP
:
14070 if (qemuDomainGetJobInfoMigrationStats(driver
, vm
, jobInfo
) < 0)
14074 case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP
:
14075 if (qemuDomainGetJobInfoDumpStats(driver
, vm
, jobInfo
) < 0)
14079 case QEMU_DOMAIN_JOB_STATS_TYPE_NONE
:
14086 qemuDomainObjEndJob(driver
, vm
);
14092 qemuDomainGetJobInfo(virDomainPtr dom
,
14093 virDomainJobInfoPtr info
)
14095 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14096 qemuDomainJobInfo jobInfo
;
14097 virDomainObjPtr vm
;
14100 if (!(vm
= qemuDomObjFromDomain(dom
)))
14103 if (virDomainGetJobInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
14106 if (qemuDomainGetJobStatsInternal(driver
, vm
, false, &jobInfo
) < 0)
14109 if (jobInfo
.status
== QEMU_DOMAIN_JOB_STATUS_NONE
) {
14110 memset(info
, 0, sizeof(*info
));
14111 info
->type
= VIR_DOMAIN_JOB_NONE
;
14116 ret
= qemuDomainJobInfoToInfo(&jobInfo
, info
);
14119 virDomainObjEndAPI(&vm
);
14125 qemuDomainGetJobStats(virDomainPtr dom
,
14127 virTypedParameterPtr
*params
,
14129 unsigned int flags
)
14131 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14132 virDomainObjPtr vm
;
14133 qemuDomainObjPrivatePtr priv
;
14134 qemuDomainJobInfo jobInfo
;
14135 bool completed
= !!(flags
& VIR_DOMAIN_JOB_STATS_COMPLETED
);
14138 virCheckFlags(VIR_DOMAIN_JOB_STATS_COMPLETED
, -1);
14140 if (!(vm
= qemuDomObjFromDomain(dom
)))
14143 if (virDomainGetJobStatsEnsureACL(dom
->conn
, vm
->def
) < 0)
14146 priv
= vm
->privateData
;
14147 if (qemuDomainGetJobStatsInternal(driver
, vm
, completed
, &jobInfo
) < 0)
14150 if (jobInfo
.status
== QEMU_DOMAIN_JOB_STATUS_NONE
) {
14151 *type
= VIR_DOMAIN_JOB_NONE
;
14158 ret
= qemuDomainJobInfoToParams(&jobInfo
, type
, params
, nparams
);
14160 if (completed
&& ret
== 0)
14161 VIR_FREE(priv
->job
.completed
);
14164 virDomainObjEndAPI(&vm
);
14169 static int qemuDomainAbortJob(virDomainPtr dom
)
14171 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14172 virDomainObjPtr vm
;
14174 qemuDomainObjPrivatePtr priv
;
14177 if (!(vm
= qemuDomObjFromDomain(dom
)))
14180 if (virDomainAbortJobEnsureACL(dom
->conn
, vm
->def
) < 0)
14183 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_ABORT
) < 0)
14186 if (virDomainObjCheckActive(vm
) < 0)
14189 priv
= vm
->privateData
;
14191 if (!priv
->job
.asyncJob
) {
14192 virReportError(VIR_ERR_OPERATION_INVALID
,
14193 "%s", _("no job is active on the domain"));
14197 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_IN
) {
14198 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14199 _("cannot abort incoming migration;"
14200 " use virDomainDestroy instead"));
14204 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_DUMP
&&
14205 priv
->job
.apiFlags
& VIR_DUMP_MEMORY_ONLY
) {
14206 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14207 _("cannot abort memory-only dump"));
14211 if (priv
->job
.asyncJob
== QEMU_ASYNC_JOB_MIGRATION_OUT
&&
14212 (priv
->job
.current
->status
== QEMU_DOMAIN_JOB_STATUS_POSTCOPY
||
14213 (virDomainObjGetState(vm
, &reason
) == VIR_DOMAIN_PAUSED
&&
14214 reason
== VIR_DOMAIN_PAUSED_POSTCOPY
))) {
14215 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14216 _("cannot abort migration in post-copy mode"));
14220 VIR_DEBUG("Cancelling job at client request");
14221 qemuDomainObjAbortAsyncJob(vm
);
14222 qemuDomainObjEnterMonitor(driver
, vm
);
14223 ret
= qemuMonitorMigrateCancel(priv
->mon
);
14224 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14228 qemuDomainObjEndJob(driver
, vm
);
14231 virDomainObjEndAPI(&vm
);
14237 qemuDomainMigrateSetMaxDowntime(virDomainPtr dom
,
14238 unsigned long long downtime
,
14239 unsigned int flags
)
14241 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14242 virDomainObjPtr vm
;
14243 qemuDomainObjPrivatePtr priv
;
14246 virCheckFlags(0, -1);
14248 if (!(vm
= qemuDomObjFromDomain(dom
)))
14251 if (virDomainMigrateSetMaxDowntimeEnsureACL(dom
->conn
, vm
->def
) < 0)
14254 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MIGRATION_OP
) < 0)
14257 if (virDomainObjCheckActive(vm
) < 0)
14260 priv
= vm
->privateData
;
14262 VIR_DEBUG("Setting migration downtime to %llums", downtime
);
14263 qemuDomainObjEnterMonitor(driver
, vm
);
14264 ret
= qemuMonitorSetMigrationDowntime(priv
->mon
, downtime
);
14265 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14269 qemuDomainObjEndJob(driver
, vm
);
14272 virDomainObjEndAPI(&vm
);
14278 qemuDomainMigrateGetMaxDowntime(virDomainPtr dom
,
14279 unsigned long long *downtime
,
14280 unsigned int flags
)
14282 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14283 virDomainObjPtr vm
;
14284 qemuMigrationParamsPtr migParams
= NULL
;
14288 virCheckFlags(0, -1);
14290 if (!(vm
= qemuDomObjFromDomain(dom
)))
14293 if (virDomainMigrateGetMaxDowntimeEnsureACL(dom
->conn
, vm
->def
) < 0)
14296 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
14299 if (virDomainObjCheckActive(vm
) < 0)
14302 if (qemuMigrationParamsFetch(driver
, vm
, QEMU_ASYNC_JOB_NONE
,
14306 if ((rc
= qemuMigrationParamsGetULL(migParams
,
14307 QEMU_MIGRATION_PARAM_DOWNTIME_LIMIT
,
14313 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14314 _("Querying migration downtime is not supported by "
14322 qemuDomainObjEndJob(driver
, vm
);
14325 qemuMigrationParamsFree(migParams
);
14326 virDomainObjEndAPI(&vm
);
14332 qemuDomainMigrateGetCompressionCache(virDomainPtr dom
,
14333 unsigned long long *cacheSize
,
14334 unsigned int flags
)
14336 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14337 virDomainObjPtr vm
;
14338 qemuDomainObjPrivatePtr priv
;
14341 virCheckFlags(0, -1);
14343 if (!(vm
= qemuDomObjFromDomain(dom
)))
14346 if (virDomainMigrateGetCompressionCacheEnsureACL(dom
->conn
, vm
->def
) < 0)
14349 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
14352 if (virDomainObjCheckActive(vm
) < 0)
14355 priv
= vm
->privateData
;
14357 if (!qemuMigrationCapsGet(vm
, QEMU_MIGRATION_CAP_XBZRLE
)) {
14358 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
14359 _("Compressed migration is not supported by "
14364 qemuDomainObjEnterMonitor(driver
, vm
);
14366 ret
= qemuMonitorGetMigrationCacheSize(priv
->mon
, cacheSize
);
14368 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14372 qemuDomainObjEndJob(driver
, vm
);
14375 virDomainObjEndAPI(&vm
);
14380 qemuDomainMigrateSetCompressionCache(virDomainPtr dom
,
14381 unsigned long long cacheSize
,
14382 unsigned int flags
)
14384 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14385 virDomainObjPtr vm
;
14386 qemuDomainObjPrivatePtr priv
;
14389 virCheckFlags(0, -1);
14391 if (!(vm
= qemuDomObjFromDomain(dom
)))
14394 if (virDomainMigrateSetCompressionCacheEnsureACL(dom
->conn
, vm
->def
) < 0)
14397 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MIGRATION_OP
) < 0)
14400 if (virDomainObjCheckActive(vm
) < 0)
14403 priv
= vm
->privateData
;
14405 if (!qemuMigrationCapsGet(vm
, QEMU_MIGRATION_CAP_XBZRLE
)) {
14406 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
14407 _("Compressed migration is not supported by "
14412 qemuDomainObjEnterMonitor(driver
, vm
);
14414 VIR_DEBUG("Setting compression cache to %llu B", cacheSize
);
14415 ret
= qemuMonitorSetMigrationCacheSize(priv
->mon
, cacheSize
);
14417 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14421 qemuDomainObjEndJob(driver
, vm
);
14424 virDomainObjEndAPI(&vm
);
14429 qemuDomainMigrateSetMaxSpeed(virDomainPtr dom
,
14430 unsigned long bandwidth
,
14431 unsigned int flags
)
14433 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14434 virDomainObjPtr vm
;
14435 qemuDomainObjPrivatePtr priv
;
14436 bool postcopy
= !!(flags
& VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY
);
14437 VIR_AUTOPTR(qemuMigrationParams
) migParams
= NULL
;
14438 unsigned long long max
;
14441 virCheckFlags(VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY
, -1);
14443 if (!(vm
= qemuDomObjFromDomain(dom
)))
14446 priv
= vm
->privateData
;
14448 if (virDomainMigrateSetMaxSpeedEnsureACL(dom
->conn
, vm
->def
) < 0)
14452 max
= ULLONG_MAX
/ 1024 / 1024;
14454 max
= QEMU_DOMAIN_MIG_BANDWIDTH_MAX
;
14456 if (bandwidth
> max
) {
14457 virReportError(VIR_ERR_OVERFLOW
,
14458 _("bandwidth must be less than %llu"), max
+ 1);
14462 if (!postcopy
&& !virDomainObjIsActive(vm
)) {
14463 priv
->migMaxBandwidth
= bandwidth
;
14468 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MIGRATION_OP
) < 0)
14471 if (virDomainObjCheckActive(vm
) < 0)
14474 VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth
);
14477 if (!(migParams
= qemuMigrationParamsNew()))
14480 if (qemuMigrationParamsSetULL(migParams
,
14481 QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH
,
14482 bandwidth
* 1024 * 1024) < 0)
14485 if (qemuMigrationParamsApply(driver
, vm
, QEMU_ASYNC_JOB_NONE
,
14491 qemuDomainObjEnterMonitor(driver
, vm
);
14492 rc
= qemuMonitorSetMigrationSpeed(priv
->mon
, bandwidth
);
14493 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || rc
< 0)
14496 priv
->migMaxBandwidth
= bandwidth
;
14502 qemuDomainObjEndJob(driver
, vm
);
14505 virDomainObjEndAPI(&vm
);
14511 qemuDomainMigrationGetPostcopyBandwidth(virQEMUDriverPtr driver
,
14512 virDomainObjPtr vm
,
14513 unsigned long *bandwidth
)
14515 VIR_AUTOPTR(qemuMigrationParams
) migParams
= NULL
;
14516 unsigned long long bw
;
14520 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
14523 if (virDomainObjCheckActive(vm
) < 0)
14526 if (qemuMigrationParamsFetch(driver
, vm
, QEMU_ASYNC_JOB_NONE
,
14530 if ((rc
= qemuMigrationParamsGetULL(migParams
,
14531 QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH
,
14536 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14537 _("querying maximum post-copy migration speed is "
14538 "not supported by QEMU binary"));
14542 /* QEMU reports B/s while we use MiB/s */
14545 if (bw
> ULONG_MAX
) {
14546 virReportError(VIR_ERR_OVERFLOW
,
14547 _("bandwidth %llu is greater than %lu which is the "
14548 "maximum value supported by this API"),
14557 qemuDomainObjEndJob(driver
, vm
);
14563 qemuDomainMigrateGetMaxSpeed(virDomainPtr dom
,
14564 unsigned long *bandwidth
,
14565 unsigned int flags
)
14567 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14568 virDomainObjPtr vm
;
14569 qemuDomainObjPrivatePtr priv
;
14570 bool postcopy
= !!(flags
& VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY
);
14573 virCheckFlags(VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY
, -1);
14575 if (!(vm
= qemuDomObjFromDomain(dom
)))
14578 priv
= vm
->privateData
;
14580 if (virDomainMigrateGetMaxSpeedEnsureACL(dom
->conn
, vm
->def
) < 0)
14584 if (qemuDomainMigrationGetPostcopyBandwidth(driver
, vm
, bandwidth
) < 0)
14587 *bandwidth
= priv
->migMaxBandwidth
;
14593 virDomainObjEndAPI(&vm
);
14599 qemuDomainMigrateStartPostCopy(virDomainPtr dom
,
14600 unsigned int flags
)
14602 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
14603 virDomainObjPtr vm
;
14604 qemuDomainObjPrivatePtr priv
;
14607 virCheckFlags(0, -1);
14609 if (!(vm
= qemuDomObjFromDomain(dom
)))
14612 if (virDomainMigrateStartPostCopyEnsureACL(dom
->conn
, vm
->def
) < 0)
14615 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MIGRATION_OP
) < 0)
14618 if (virDomainObjCheckActive(vm
) < 0)
14621 priv
= vm
->privateData
;
14623 if (priv
->job
.asyncJob
!= QEMU_ASYNC_JOB_MIGRATION_OUT
) {
14624 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14625 _("post-copy can only be started while "
14626 "outgoing migration is in progress"));
14630 if (!(priv
->job
.apiFlags
& VIR_MIGRATE_POSTCOPY
)) {
14631 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
14632 _("switching to post-copy requires migration to be "
14633 "started with VIR_MIGRATE_POSTCOPY flag"));
14637 VIR_DEBUG("Starting post-copy");
14638 qemuDomainObjEnterMonitor(driver
, vm
);
14639 ret
= qemuMonitorMigrateStartPostCopy(priv
->mon
);
14640 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14644 qemuDomainObjEndJob(driver
, vm
);
14647 virDomainObjEndAPI(&vm
);
14652 /* Return -1 if request is not sent to agent due to misconfig, -2 if request
14653 * is sent but failed, and number of frozen filesystems on success. If -2 is
14654 * returned, FSThaw should be called revert the quiesced status. */
14656 qemuDomainSnapshotFSFreeze(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
14657 virDomainObjPtr vm
,
14658 const char **mountpoints
,
14659 unsigned int nmountpoints
)
14661 qemuAgentPtr agent
;
14664 if (!qemuDomainAgentAvailable(vm
, true))
14667 agent
= qemuDomainObjEnterAgent(vm
);
14668 frozen
= qemuAgentFSFreeze(agent
, mountpoints
, nmountpoints
);
14669 qemuDomainObjExitAgent(vm
, agent
);
14670 return frozen
< 0 ? -2 : frozen
;
14674 /* Return -1 on error, otherwise number of thawed filesystems. */
14676 qemuDomainSnapshotFSThaw(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
14677 virDomainObjPtr vm
,
14680 qemuAgentPtr agent
;
14682 virErrorPtr err
= NULL
;
14684 if (!qemuDomainAgentAvailable(vm
, report
))
14687 agent
= qemuDomainObjEnterAgent(vm
);
14689 err
= virSaveLastError();
14690 thawed
= qemuAgentFSThaw(agent
);
14693 qemuDomainObjExitAgent(vm
, agent
);
14701 /* The domain is expected to be locked and inactive. */
14703 qemuDomainSnapshotCreateInactiveInternal(virQEMUDriverPtr driver
,
14704 virDomainObjPtr vm
,
14705 virDomainSnapshotObjPtr snap
)
14707 return qemuDomainSnapshotForEachQcow2(driver
, vm
, snap
, "-c", false);
14711 /* The domain is expected to be locked and inactive. */
14713 qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver
,
14714 virDomainObjPtr vm
,
14715 virDomainSnapshotObjPtr snap
,
14719 virDomainSnapshotDiskDefPtr snapdisk
;
14720 virDomainDiskDefPtr defdisk
;
14721 virCommandPtr cmd
= NULL
;
14722 const char *qemuImgPath
;
14723 virBitmapPtr created
= NULL
;
14724 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
14726 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
14728 if (!(qemuImgPath
= qemuFindQemuImgBinary(driver
)))
14731 if (!(created
= virBitmapNew(snap
->def
->ndisks
)))
14734 /* If reuse is true, then qemuDomainSnapshotPrepare already
14735 * ensured that the new files exist, and it was up to the user to
14736 * create them correctly. */
14737 for (i
= 0; i
< snap
->def
->ndisks
&& !reuse
; i
++) {
14738 snapdisk
= &(snap
->def
->disks
[i
]);
14739 defdisk
= snap
->def
->dom
->disks
[snapdisk
->idx
];
14740 if (snapdisk
->snapshot
!= VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
)
14743 if (!snapdisk
->src
->format
)
14744 snapdisk
->src
->format
= VIR_STORAGE_FILE_QCOW2
;
14746 /* creates cmd line args: qemu-img create -f qcow2 -o */
14747 if (!(cmd
= virCommandNewArgList(qemuImgPath
,
14750 virStorageFileFormatTypeToString(snapdisk
->src
->format
),
14755 /* adds cmd line arg: backing_fmt=format,backing_file=/path/to/backing/file */
14756 virBufferAsprintf(&buf
, "backing_fmt=%s,backing_file=",
14757 virStorageFileFormatTypeToString(defdisk
->src
->format
));
14758 virQEMUBuildBufferEscapeComma(&buf
, defdisk
->src
->path
);
14759 virCommandAddArgBuffer(cmd
, &buf
);
14761 /* adds cmd line args: /path/to/target/file */
14762 virQEMUBuildBufferEscapeComma(&buf
, snapdisk
->src
->path
);
14763 virCommandAddArgBuffer(cmd
, &buf
);
14765 /* If the target does not exist, we're going to create it possibly */
14766 if (!virFileExists(snapdisk
->src
->path
))
14767 ignore_value(virBitmapSetBit(created
, i
));
14769 if (virCommandRun(cmd
, NULL
) < 0)
14772 virCommandFree(cmd
);
14776 /* update disk definitions */
14777 for (i
= 0; i
< snap
->def
->ndisks
; i
++) {
14778 snapdisk
= &(snap
->def
->disks
[i
]);
14779 defdisk
= vm
->def
->disks
[snapdisk
->idx
];
14781 if (snapdisk
->snapshot
== VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
) {
14782 VIR_FREE(defdisk
->src
->path
);
14783 if (VIR_STRDUP(defdisk
->src
->path
, snapdisk
->src
->path
) < 0) {
14784 /* we cannot rollback here in a sane way */
14787 defdisk
->src
->format
= snapdisk
->src
->format
;
14789 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, vm
->def
) < 0)
14797 virBufferFreeAndReset(&buf
);
14798 virCommandFree(cmd
);
14800 /* unlink images if creation has failed */
14801 if (ret
< 0 && created
) {
14803 while ((bit
= virBitmapNextSetBit(created
, bit
)) >= 0) {
14804 snapdisk
= &(snap
->def
->disks
[bit
]);
14805 if (unlink(snapdisk
->src
->path
) < 0)
14806 VIR_WARN("Failed to remove snapshot image '%s'",
14807 snapdisk
->src
->path
);
14810 virBitmapFree(created
);
14811 virObjectUnref(cfg
);
14817 /* The domain is expected to be locked and active. */
14819 qemuDomainSnapshotCreateActiveInternal(virQEMUDriverPtr driver
,
14820 virDomainObjPtr vm
,
14821 virDomainSnapshotObjPtr snap
,
14822 unsigned int flags
)
14824 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
14825 virObjectEventPtr event
= NULL
;
14826 bool resume
= false;
14829 if (!qemuMigrationSrcIsAllowed(driver
, vm
, false, 0))
14832 if (virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
) {
14833 /* savevm monitor command pauses the domain emitting an event which
14834 * confuses libvirt since it's not notified when qemu resumes the
14835 * domain. Thus we stop and start CPUs ourselves.
14837 if (qemuProcessStopCPUs(driver
, vm
, VIR_DOMAIN_PAUSED_SAVE
,
14838 QEMU_ASYNC_JOB_SNAPSHOT
) < 0)
14842 if (!virDomainObjIsActive(vm
)) {
14843 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
14844 _("guest unexpectedly quit"));
14849 if (qemuDomainObjEnterMonitorAsync(driver
, vm
,
14850 QEMU_ASYNC_JOB_SNAPSHOT
) < 0) {
14855 ret
= qemuMonitorCreateSnapshot(priv
->mon
, snap
->def
->name
);
14856 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
14861 if (!(snap
->def
->cookie
= (virObjectPtr
) qemuDomainSaveCookieNew(vm
)))
14864 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_HALT
) {
14865 event
= virDomainEventLifecycleNewFromObj(vm
, VIR_DOMAIN_EVENT_STOPPED
,
14866 VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT
);
14867 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT
,
14868 QEMU_ASYNC_JOB_SNAPSHOT
, 0);
14869 virDomainAuditStop(vm
, "from-snapshot");
14874 if (resume
&& virDomainObjIsActive(vm
) &&
14875 qemuProcessStartCPUs(driver
, vm
,
14876 VIR_DOMAIN_RUNNING_UNPAUSED
,
14877 QEMU_ASYNC_JOB_SNAPSHOT
) < 0) {
14878 event
= virDomainEventLifecycleNewFromObj(vm
,
14879 VIR_DOMAIN_EVENT_SUSPENDED
,
14880 VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR
);
14881 if (virGetLastErrorCode() == VIR_ERR_OK
) {
14882 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
14883 _("resuming after snapshot failed"));
14887 virObjectEventStateQueue(driver
->domainEventState
, event
);
14894 qemuDomainSnapshotPrepareDiskShared(virDomainSnapshotDiskDefPtr snapdisk
,
14895 virDomainDiskDefPtr domdisk
)
14897 if (!domdisk
->src
->shared
|| domdisk
->src
->readonly
)
14900 if (!qemuBlockStorageSourceSupportsConcurrentAccess(snapdisk
->src
)) {
14901 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
14902 _("shared access for disk '%s' requires use of "
14903 "supported storage format"), domdisk
->dst
);
14912 qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdisk
,
14913 virDomainDiskDefPtr domdisk
)
14915 int domDiskType
= virStorageSourceGetActualType(domdisk
->src
);
14916 int snapDiskType
= virStorageSourceGetActualType(snapdisk
->src
);
14918 switch ((virStorageType
)domDiskType
) {
14919 case VIR_STORAGE_TYPE_BLOCK
:
14920 case VIR_STORAGE_TYPE_FILE
:
14923 case VIR_STORAGE_TYPE_NETWORK
:
14924 switch ((virStorageNetProtocol
) domdisk
->src
->protocol
) {
14925 case VIR_STORAGE_NET_PROTOCOL_NONE
:
14926 case VIR_STORAGE_NET_PROTOCOL_NBD
:
14927 case VIR_STORAGE_NET_PROTOCOL_RBD
:
14928 case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG
:
14929 case VIR_STORAGE_NET_PROTOCOL_GLUSTER
:
14930 case VIR_STORAGE_NET_PROTOCOL_ISCSI
:
14931 case VIR_STORAGE_NET_PROTOCOL_HTTP
:
14932 case VIR_STORAGE_NET_PROTOCOL_HTTPS
:
14933 case VIR_STORAGE_NET_PROTOCOL_FTP
:
14934 case VIR_STORAGE_NET_PROTOCOL_FTPS
:
14935 case VIR_STORAGE_NET_PROTOCOL_TFTP
:
14936 case VIR_STORAGE_NET_PROTOCOL_SSH
:
14937 case VIR_STORAGE_NET_PROTOCOL_VXHS
:
14938 case VIR_STORAGE_NET_PROTOCOL_LAST
:
14939 virReportError(VIR_ERR_INTERNAL_ERROR
,
14940 _("external inactive snapshots are not supported on "
14941 "'network' disks using '%s' protocol"),
14942 virStorageNetProtocolTypeToString(domdisk
->src
->protocol
));
14947 case VIR_STORAGE_TYPE_DIR
:
14948 case VIR_STORAGE_TYPE_VOLUME
:
14949 case VIR_STORAGE_TYPE_NONE
:
14950 case VIR_STORAGE_TYPE_LAST
:
14951 virReportError(VIR_ERR_INTERNAL_ERROR
,
14952 _("external inactive snapshots are not supported on "
14953 "'%s' disks"), virStorageTypeToString(domDiskType
));
14957 switch ((virStorageType
)snapDiskType
) {
14958 case VIR_STORAGE_TYPE_BLOCK
:
14959 case VIR_STORAGE_TYPE_FILE
:
14962 case VIR_STORAGE_TYPE_NETWORK
:
14963 case VIR_STORAGE_TYPE_DIR
:
14964 case VIR_STORAGE_TYPE_VOLUME
:
14965 case VIR_STORAGE_TYPE_NONE
:
14966 case VIR_STORAGE_TYPE_LAST
:
14967 virReportError(VIR_ERR_INTERNAL_ERROR
,
14968 _("external inactive snapshots are not supported on "
14969 "'%s' disks"), virStorageTypeToString(snapDiskType
));
14973 if (qemuDomainSnapshotPrepareDiskShared(snapdisk
, domdisk
) < 0)
14981 qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk
,
14982 virDomainDiskDefPtr domdisk
)
14984 int actualType
= virStorageSourceGetActualType(snapdisk
->src
);
14986 if (domdisk
->device
== VIR_DOMAIN_DISK_DEVICE_LUN
) {
14987 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
14988 _("external active snapshots are not supported on scsi "
14989 "passthrough devices"));
14993 switch ((virStorageType
)actualType
) {
14994 case VIR_STORAGE_TYPE_BLOCK
:
14995 case VIR_STORAGE_TYPE_FILE
:
14998 case VIR_STORAGE_TYPE_NETWORK
:
14999 switch ((virStorageNetProtocol
) snapdisk
->src
->protocol
) {
15000 case VIR_STORAGE_NET_PROTOCOL_GLUSTER
:
15003 case VIR_STORAGE_NET_PROTOCOL_NONE
:
15004 case VIR_STORAGE_NET_PROTOCOL_NBD
:
15005 case VIR_STORAGE_NET_PROTOCOL_RBD
:
15006 case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG
:
15007 case VIR_STORAGE_NET_PROTOCOL_ISCSI
:
15008 case VIR_STORAGE_NET_PROTOCOL_HTTP
:
15009 case VIR_STORAGE_NET_PROTOCOL_HTTPS
:
15010 case VIR_STORAGE_NET_PROTOCOL_FTP
:
15011 case VIR_STORAGE_NET_PROTOCOL_FTPS
:
15012 case VIR_STORAGE_NET_PROTOCOL_TFTP
:
15013 case VIR_STORAGE_NET_PROTOCOL_SSH
:
15014 case VIR_STORAGE_NET_PROTOCOL_VXHS
:
15015 case VIR_STORAGE_NET_PROTOCOL_LAST
:
15016 virReportError(VIR_ERR_INTERNAL_ERROR
,
15017 _("external active snapshots are not supported on "
15018 "'network' disks using '%s' protocol"),
15019 virStorageNetProtocolTypeToString(snapdisk
->src
->protocol
));
15025 case VIR_STORAGE_TYPE_DIR
:
15026 case VIR_STORAGE_TYPE_VOLUME
:
15027 case VIR_STORAGE_TYPE_NONE
:
15028 case VIR_STORAGE_TYPE_LAST
:
15029 virReportError(VIR_ERR_INTERNAL_ERROR
,
15030 _("external active snapshots are not supported on "
15031 "'%s' disks"), virStorageTypeToString(actualType
));
15035 if (qemuDomainSnapshotPrepareDiskShared(snapdisk
, domdisk
) < 0)
15043 qemuDomainSnapshotPrepareDiskExternal(virDomainDiskDefPtr disk
,
15044 virDomainSnapshotDiskDefPtr snapdisk
,
15051 if (disk
->src
->readonly
) {
15052 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
15053 _("external snapshot for readonly disk %s "
15054 "is not supported"), disk
->dst
);
15058 if (qemuTranslateSnapshotDiskSourcePool(snapdisk
) < 0)
15062 if (virDomainDiskTranslateSourcePool(disk
) < 0)
15065 if (qemuDomainSnapshotPrepareDiskExternalInactive(snapdisk
, disk
) < 0)
15068 if (qemuDomainSnapshotPrepareDiskExternalActive(snapdisk
, disk
) < 0)
15072 if (virStorageFileInit(snapdisk
->src
) < 0)
15075 if (virStorageFileStat(snapdisk
->src
, &st
) < 0) {
15076 if (errno
!= ENOENT
) {
15077 virReportSystemError(errno
,
15078 _("unable to stat for disk %s: %s"),
15079 snapdisk
->name
, snapdisk
->src
->path
);
15081 } else if (reuse
) {
15082 virReportSystemError(errno
,
15083 _("missing existing file for disk %s: %s"),
15084 snapdisk
->name
, snapdisk
->src
->path
);
15087 } else if (!S_ISBLK(st
.st_mode
) && st
.st_size
&& !reuse
) {
15088 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
15089 _("external snapshot file for disk %s already "
15090 "exists and is not a block device: %s"),
15091 snapdisk
->name
, snapdisk
->src
->path
);
15098 virStorageFileDeinit(snapdisk
->src
);
15104 qemuDomainSnapshotPrepareDiskInternal(virDomainDiskDefPtr disk
,
15109 /* active disks are handled by qemu itself so no need to worry about those */
15113 if (virDomainDiskTranslateSourcePool(disk
) < 0)
15116 actualType
= virStorageSourceGetActualType(disk
->src
);
15118 switch ((virStorageType
)actualType
) {
15119 case VIR_STORAGE_TYPE_BLOCK
:
15120 case VIR_STORAGE_TYPE_FILE
:
15123 case VIR_STORAGE_TYPE_NETWORK
:
15124 switch ((virStorageNetProtocol
) disk
->src
->protocol
) {
15125 case VIR_STORAGE_NET_PROTOCOL_NONE
:
15126 case VIR_STORAGE_NET_PROTOCOL_NBD
:
15127 case VIR_STORAGE_NET_PROTOCOL_RBD
:
15128 case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG
:
15129 case VIR_STORAGE_NET_PROTOCOL_GLUSTER
:
15130 case VIR_STORAGE_NET_PROTOCOL_ISCSI
:
15131 case VIR_STORAGE_NET_PROTOCOL_HTTP
:
15132 case VIR_STORAGE_NET_PROTOCOL_HTTPS
:
15133 case VIR_STORAGE_NET_PROTOCOL_FTP
:
15134 case VIR_STORAGE_NET_PROTOCOL_FTPS
:
15135 case VIR_STORAGE_NET_PROTOCOL_TFTP
:
15136 case VIR_STORAGE_NET_PROTOCOL_SSH
:
15137 case VIR_STORAGE_NET_PROTOCOL_VXHS
:
15138 case VIR_STORAGE_NET_PROTOCOL_LAST
:
15139 virReportError(VIR_ERR_INTERNAL_ERROR
,
15140 _("internal inactive snapshots are not supported on "
15141 "'network' disks using '%s' protocol"),
15142 virStorageNetProtocolTypeToString(disk
->src
->protocol
));
15147 case VIR_STORAGE_TYPE_DIR
:
15148 case VIR_STORAGE_TYPE_VOLUME
:
15149 case VIR_STORAGE_TYPE_NONE
:
15150 case VIR_STORAGE_TYPE_LAST
:
15151 virReportError(VIR_ERR_INTERNAL_ERROR
,
15152 _("internal inactive snapshots are not supported on "
15153 "'%s' disks"), virStorageTypeToString(actualType
));
15162 qemuDomainSnapshotPrepare(virDomainObjPtr vm
,
15163 virDomainSnapshotDefPtr def
,
15164 unsigned int *flags
)
15168 bool active
= virDomainObjIsActive(vm
);
15169 bool reuse
= (*flags
& VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT
) != 0;
15170 bool found_internal
= false;
15171 bool forbid_internal
= false;
15174 for (i
= 0; i
< def
->ndisks
; i
++) {
15175 virDomainSnapshotDiskDefPtr disk
= &def
->disks
[i
];
15176 virDomainDiskDefPtr dom_disk
= vm
->def
->disks
[i
];
15178 if (disk
->snapshot
!= VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
&&
15179 qemuDomainDiskBlockJobIsActive(dom_disk
))
15182 switch ((virDomainSnapshotLocation
) disk
->snapshot
) {
15183 case VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL
:
15184 found_internal
= true;
15186 if (def
->state
== VIR_SNAP_STATE_DISK_SNAPSHOT
&& active
) {
15187 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
15188 _("active qemu domains require external disk "
15189 "snapshots; disk %s requested internal"),
15194 if (qemuDomainSnapshotPrepareDiskInternal(dom_disk
,
15198 if (vm
->def
->disks
[i
]->src
->format
> 0 &&
15199 vm
->def
->disks
[i
]->src
->format
!= VIR_STORAGE_FILE_QCOW2
) {
15200 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
15201 _("internal snapshot for disk %s unsupported "
15202 "for storage type %s"),
15204 virStorageFileFormatTypeToString(
15205 vm
->def
->disks
[i
]->src
->format
));
15210 case VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
:
15211 if (!disk
->src
->format
) {
15212 disk
->src
->format
= VIR_STORAGE_FILE_QCOW2
;
15213 } else if (disk
->src
->format
!= VIR_STORAGE_FILE_QCOW2
&&
15214 disk
->src
->format
!= VIR_STORAGE_FILE_QED
) {
15215 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
15216 _("external snapshot format for disk %s "
15217 "is unsupported: %s"),
15219 virStorageFileFormatTypeToString(disk
->src
->format
));
15223 if (qemuDomainSnapshotPrepareDiskExternal(dom_disk
, disk
,
15224 active
, reuse
) < 0)
15230 case VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
:
15231 /* Remember seeing a disk that has snapshot disabled */
15232 if (!virStorageSourceIsEmpty(dom_disk
->src
) &&
15233 !dom_disk
->src
->readonly
)
15234 forbid_internal
= true;
15237 case VIR_DOMAIN_SNAPSHOT_LOCATION_DEFAULT
:
15238 case VIR_DOMAIN_SNAPSHOT_LOCATION_LAST
:
15239 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
15240 _("unexpected code path"));
15245 if (!found_internal
&& !external
&&
15246 def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
) {
15247 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
15248 _("nothing selected for snapshot"));
15252 /* internal snapshot requires a disk image to store the memory image to, and
15253 * also disks can't be excluded from an internal snapshot*/
15254 if ((def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL
&& !found_internal
) ||
15255 (found_internal
&& forbid_internal
)) {
15256 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
15257 _("internal and full system snapshots require all "
15258 "disks to be selected for snapshot"));
15262 /* disk snapshot requires at least one disk */
15263 if (def
->state
== VIR_SNAP_STATE_DISK_SNAPSHOT
&& !external
) {
15264 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
15265 _("disk-only snapshots require at least "
15266 "one disk to be selected for snapshot"));
15270 /* For now, we don't allow mixing internal and external disks.
15271 * XXX technically, we could mix internal and external disks for
15272 * offline snapshots */
15273 if ((found_internal
&& external
) ||
15274 (def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL
&& external
) ||
15275 (def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
&& found_internal
)) {
15276 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
15277 _("mixing internal and external targets for a snapshot "
15278 "is not yet supported"));
15282 /* internal snapshots + pflash based loader have the following problems:
15283 * - if the variable store is raw, the snapshot fails
15284 * - allowing a qcow2 image as the varstore would make it eligible to receive
15285 * the vmstate dump, which would make it huge
15286 * - offline snapshot would not snapshot the varstore at all
15288 * Avoid the issues by forbidding internal snapshot with pflash completely.
15290 if (found_internal
&&
15291 vm
->def
->os
.loader
&&
15292 vm
->def
->os
.loader
->type
== VIR_DOMAIN_LOADER_TYPE_PFLASH
) {
15293 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
15294 _("internal snapshots of a VM with pflash based "
15295 "firmware are not supported"));
15299 /* Alter flags to let later users know what we learned. */
15300 if (external
&& !active
)
15301 *flags
|= VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
;
15310 struct _qemuDomainSnapshotDiskData
{
15311 virStorageSourcePtr src
;
15312 bool initialized
; /* @src was initialized in the storage driver */
15313 bool created
; /* @src was created by the snapshot code */
15314 bool prepared
; /* @src was prepared using qemuDomainDiskChainElementPrepare */
15315 virDomainDiskDefPtr disk
;
15316 char *relPath
; /* relative path component to fill into original disk */
15318 virStorageSourcePtr persistsrc
;
15319 virDomainDiskDefPtr persistdisk
;
15322 typedef struct _qemuDomainSnapshotDiskData qemuDomainSnapshotDiskData
;
15323 typedef qemuDomainSnapshotDiskData
*qemuDomainSnapshotDiskDataPtr
;
15327 qemuDomainSnapshotDiskDataFree(qemuDomainSnapshotDiskDataPtr data
,
15329 virQEMUDriverPtr driver
,
15330 virDomainObjPtr vm
)
15337 for (i
= 0; i
< ndata
; i
++) {
15338 /* on success of the snapshot the 'src' and 'persistsrc' properties will
15339 * be set to NULL by qemuDomainSnapshotUpdateDiskSources */
15341 if (data
[i
].initialized
)
15342 virStorageFileDeinit(data
[i
].src
);
15344 if (data
[i
].prepared
)
15345 qemuDomainDiskChainElementRevoke(driver
, vm
, data
[i
].src
);
15347 virObjectUnref(data
[i
].src
);
15349 virObjectUnref(data
[i
].persistsrc
);
15350 VIR_FREE(data
[i
].relPath
);
15358 * qemuDomainSnapshotDiskDataCollect:
15360 * Collects and prepares a list of structures that hold information about disks
15361 * that are selected for the snapshot.
15363 static qemuDomainSnapshotDiskDataPtr
15364 qemuDomainSnapshotDiskDataCollect(virQEMUDriverPtr driver
,
15365 virDomainObjPtr vm
,
15366 virDomainSnapshotObjPtr snap
,
15370 qemuDomainSnapshotDiskDataPtr ret
;
15371 qemuDomainSnapshotDiskDataPtr dd
;
15372 char *backingStoreStr
;
15374 if (VIR_ALLOC_N(ret
, snap
->def
->ndisks
) < 0)
15377 for (i
= 0; i
< snap
->def
->ndisks
; i
++) {
15378 if (snap
->def
->disks
[i
].snapshot
== VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
)
15383 dd
->disk
= vm
->def
->disks
[i
];
15385 if (!(dd
->src
= virStorageSourceCopy(snap
->def
->disks
[i
].src
, false)))
15388 if (virStorageSourceInitChainElement(dd
->src
, dd
->disk
->src
, false) < 0)
15391 if (qemuDomainStorageFileInit(driver
, vm
, dd
->src
, NULL
) < 0)
15394 dd
->initialized
= true;
15396 /* relative backing store paths need to be updated so that relative
15397 * block commit still works */
15399 if (virStorageFileGetBackingStoreStr(dd
->src
, &backingStoreStr
) < 0)
15401 if (backingStoreStr
!= NULL
) {
15402 if (virStorageIsRelative(backingStoreStr
))
15403 VIR_STEAL_PTR(dd
->relPath
, backingStoreStr
);
15405 VIR_FREE(backingStoreStr
);
15409 /* Note that it's unsafe to assume that the disks in the persistent
15410 * definition match up with the disks in the live definition just by
15411 * checking that the target name is the same. We've done that
15412 * historically this way though. */
15414 (dd
->persistdisk
= virDomainDiskByName(vm
->newDef
, dd
->disk
->dst
,
15417 if (!(dd
->persistsrc
= virStorageSourceCopy(dd
->src
, false)))
15420 if (virStorageSourceInitChainElement(dd
->persistsrc
,
15421 dd
->persistdisk
->src
, false) < 0)
15429 qemuDomainSnapshotDiskDataFree(ret
, snap
->def
->ndisks
, driver
, vm
);
15435 qemuDomainSnapshotUpdateDiskSourcesRenumber(virStorageSourcePtr src
)
15437 virStorageSourcePtr next
;
15438 unsigned int idx
= 1;
15440 for (next
= src
->backingStore
; virStorageSourceIsBacking(next
); next
= next
->backingStore
)
15446 * qemuDomainSnapshotUpdateDiskSources:
15447 * @dd: snapshot disk data object
15448 * @persist: set to true if persistent config of the VM was changed
15450 * Updates disk definition after a successful snapshot.
15453 qemuDomainSnapshotUpdateDiskSources(qemuDomainSnapshotDiskDataPtr dd
,
15459 /* storage driver access won'd be needed */
15460 if (dd
->initialized
)
15461 virStorageFileDeinit(dd
->src
);
15463 /* the old disk image is now readonly */
15464 dd
->disk
->src
->readonly
= true;
15466 VIR_STEAL_PTR(dd
->disk
->src
->relPath
, dd
->relPath
);
15467 VIR_STEAL_PTR(dd
->src
->backingStore
, dd
->disk
->src
);
15468 VIR_STEAL_PTR(dd
->disk
->src
, dd
->src
);
15470 /* fix numbering of disks */
15471 qemuDomainSnapshotUpdateDiskSourcesRenumber(dd
->disk
->src
);
15473 if (dd
->persistdisk
) {
15474 VIR_STEAL_PTR(dd
->persistsrc
->backingStore
, dd
->persistdisk
->src
);
15475 VIR_STEAL_PTR(dd
->persistdisk
->src
, dd
->persistsrc
);
15482 qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver
,
15483 virDomainObjPtr vm
,
15484 qemuDomainSnapshotDiskDataPtr dd
,
15485 virJSONValuePtr actions
,
15490 if (qemuBlockSnapshotAddLegacy(actions
, dd
->disk
, dd
->src
, reuse
) < 0)
15493 /* pre-create the image file so that we can label it before handing it to qemu */
15494 if (!reuse
&& dd
->src
->type
!= VIR_STORAGE_TYPE_BLOCK
) {
15495 if (virStorageFileCreate(dd
->src
) < 0) {
15496 virReportSystemError(errno
, _("failed to create image file '%s'"),
15497 NULLSTR(dd
->src
->path
));
15500 dd
->created
= true;
15503 /* set correct security, cgroup and locking options on the new image */
15504 if (qemuDomainDiskChainElementPrepare(driver
, vm
, dd
->src
, false, true) < 0) {
15505 qemuDomainDiskChainElementRevoke(driver
, vm
, dd
->src
);
15509 dd
->prepared
= true;
15518 /* The domain is expected to be locked and active. */
15520 qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver
,
15521 virDomainObjPtr vm
,
15522 virDomainSnapshotObjPtr snap
,
15523 unsigned int flags
,
15524 qemuDomainAsyncJob asyncJob
)
15526 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
15527 virJSONValuePtr actions
= NULL
;
15528 bool do_transaction
= false;
15531 bool persist
= false;
15532 bool reuse
= (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT
) != 0;
15533 virQEMUDriverConfigPtr cfg
= NULL
;
15534 qemuDomainSnapshotDiskDataPtr diskdata
= NULL
;
15535 virErrorPtr orig_err
= NULL
;
15537 if (virDomainObjCheckActive(vm
) < 0)
15540 if (!(actions
= virJSONValueNewArray()))
15543 /* prepare a list of objects to use in the vm definition so that we don't
15544 * have to roll back later */
15545 if (!(diskdata
= qemuDomainSnapshotDiskDataCollect(driver
, vm
, snap
, reuse
)))
15548 cfg
= virQEMUDriverGetConfig(driver
);
15550 /* Based on earlier qemuDomainSnapshotPrepare, all disks in this list are
15551 * now either VIR_DOMAIN_SNAPSHOT_LOCATION_NONE, or
15552 * VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL with a valid file name and
15554 for (i
= 0; i
< snap
->def
->ndisks
; i
++) {
15555 if (!diskdata
[i
].src
)
15558 ret
= qemuDomainSnapshotCreateSingleDiskActive(driver
, vm
,
15565 do_transaction
= true;
15568 if (do_transaction
) {
15569 if (qemuDomainObjEnterMonitorAsync(driver
, vm
, asyncJob
) < 0)
15572 ret
= qemuMonitorTransaction(priv
->mon
, &actions
);
15574 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
15577 for (i
= 0; i
< snap
->def
->ndisks
; i
++) {
15578 qemuDomainSnapshotDiskDataPtr dd
= &diskdata
[i
];
15583 virDomainAuditDisk(vm
, dd
->disk
->src
, dd
->src
, "snapshot", ret
>= 0);
15586 qemuDomainSnapshotUpdateDiskSources(dd
, &persist
);
15595 orig_err
= virSaveLastError();
15596 for (i
= 0; i
< snap
->def
->ndisks
; i
++) {
15597 if (!diskdata
[i
].src
)
15600 if (diskdata
[i
].prepared
)
15601 qemuDomainDiskChainElementRevoke(driver
, vm
, diskdata
[i
].src
);
15603 if (diskdata
[i
].created
&&
15604 virStorageFileUnlink(diskdata
[i
].src
) < 0)
15605 VIR_WARN("Unable to remove just-created %s", diskdata
[i
].src
->path
);
15608 /* on successful snapshot we need to remove locks from the now-old
15609 * disks and if the VM is paused release locks on the images since qemu
15610 * stopped using them*/
15611 bool paused
= virDomainObjGetState(vm
, NULL
) != VIR_DOMAIN_RUNNING
;
15613 for (i
= 0; i
< snap
->def
->ndisks
; i
++) {
15614 if (!diskdata
[i
].disk
)
15618 virDomainLockImageDetach(driver
->lockManager
, vm
,
15619 diskdata
[i
].disk
->src
);
15621 virDomainLockImageDetach(driver
->lockManager
, vm
,
15622 diskdata
[i
].disk
->src
->backingStore
);
15626 if (ret
== 0 || !do_transaction
) {
15627 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0 ||
15628 (persist
&& virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
15634 qemuDomainSnapshotDiskDataFree(diskdata
, snap
->def
->ndisks
, driver
, vm
);
15635 virJSONValueFree(actions
);
15636 virObjectUnref(cfg
);
15639 virSetError(orig_err
);
15640 virFreeError(orig_err
);
15648 qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr driver
,
15649 virDomainObjPtr vm
,
15650 virDomainSnapshotObjPtr snap
,
15651 unsigned int flags
)
15653 virObjectEventPtr event
;
15654 bool resume
= false;
15656 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
15658 bool memory
= snap
->def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
;
15659 bool memory_unlink
= false;
15660 int thaw
= 0; /* 1 if freeze succeeded, -1 if freeze failed */
15661 bool pmsuspended
= false;
15662 virQEMUDriverConfigPtr cfg
= NULL
;
15664 char *compressedpath
= NULL
;
15665 virQEMUSaveDataPtr data
= NULL
;
15667 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DISK_SNAPSHOT
) ||
15668 !virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_TRANSACTION
)) {
15669 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
15670 _("live disk snapshot not supported with this "
15675 /* If quiesce was requested, then issue a freeze command, and a
15676 * counterpart thaw command when it is actually sent to agent.
15677 * The command will fail if the guest is paused or the guest agent
15678 * is not running, or is already quiesced. */
15679 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE
) {
15682 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
15685 if (virDomainObjCheckActive(vm
) < 0) {
15686 qemuDomainObjEndAgentJob(vm
);
15690 freeze
= qemuDomainSnapshotFSFreeze(driver
, vm
, NULL
, 0);
15691 qemuDomainObjEndAgentJob(vm
);
15694 /* the helper reported the error */
15696 thaw
= -1; /* the command is sent but agent failed */
15702 /* We need to track what state the guest is in, since taking the
15703 * snapshot may alter that state and we must restore it later. */
15704 if (virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_PMSUSPENDED
) {
15705 pmsuspended
= true;
15706 } else if (virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
) {
15707 /* For full system external snapshots (those with memory), the guest
15708 * must pause (either by libvirt up front, or by qemu after
15709 * _LIVE converges). */
15713 if (memory
&& !(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_LIVE
)) {
15714 if (qemuProcessStopCPUs(driver
, vm
, VIR_DOMAIN_PAUSED_SNAPSHOT
,
15715 QEMU_ASYNC_JOB_SNAPSHOT
) < 0)
15718 if (!virDomainObjIsActive(vm
)) {
15719 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
15720 _("guest unexpectedly quit"));
15728 /* do the memory snapshot if necessary */
15730 /* check if migration is possible */
15731 if (!qemuMigrationSrcIsAllowed(driver
, vm
, false, 0))
15734 /* allow the migration job to be cancelled or the domain to be paused */
15735 qemuDomainObjSetAsyncJobMask(vm
, (QEMU_JOB_DEFAULT_MASK
|
15736 JOB_MASK(QEMU_JOB_SUSPEND
) |
15737 JOB_MASK(QEMU_JOB_MIGRATION_OP
)));
15739 cfg
= virQEMUDriverGetConfig(driver
);
15740 if ((compressed
= qemuGetCompressionProgram(cfg
->snapshotImageFormat
,
15742 "snapshot", false)) < 0)
15745 if (!(xml
= qemuDomainDefFormatLive(driver
, vm
->def
, priv
->origCPU
,
15747 !(snap
->def
->cookie
= (virObjectPtr
) qemuDomainSaveCookieNew(vm
)))
15750 if (!(data
= virQEMUSaveDataNew(xml
,
15751 (qemuDomainSaveCookiePtr
) snap
->def
->cookie
,
15752 resume
, compressed
, driver
->xmlopt
)))
15756 if ((ret
= qemuDomainSaveMemory(driver
, vm
, snap
->def
->file
, data
,
15758 QEMU_ASYNC_JOB_SNAPSHOT
)) < 0)
15761 /* the memory image was created, remove it on errors */
15762 memory_unlink
= true;
15764 /* forbid any further manipulation */
15765 qemuDomainObjSetAsyncJobMask(vm
, QEMU_JOB_DEFAULT_MASK
);
15768 /* the domain is now paused if a memory snapshot was requested */
15770 if ((ret
= qemuDomainSnapshotCreateDiskActive(driver
, vm
, snap
, flags
,
15771 QEMU_ASYNC_JOB_SNAPSHOT
)) < 0)
15774 /* the snapshot is complete now */
15775 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_HALT
) {
15776 event
= virDomainEventLifecycleNewFromObj(vm
, VIR_DOMAIN_EVENT_STOPPED
,
15777 VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT
);
15778 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT
,
15779 QEMU_ASYNC_JOB_SNAPSHOT
, 0);
15780 virDomainAuditStop(vm
, "from-snapshot");
15783 virObjectEventStateQueue(driver
->domainEventState
, event
);
15784 } else if (memory
&& pmsuspended
) {
15785 /* qemu 1.3 is unable to save a domain in pm-suspended (S3)
15786 * state; so we must emit an event stating that it was
15787 * converted to paused. */
15788 virDomainObjSetState(vm
, VIR_DOMAIN_PAUSED
,
15789 VIR_DOMAIN_PAUSED_FROM_SNAPSHOT
);
15790 event
= virDomainEventLifecycleNewFromObj(vm
, VIR_DOMAIN_EVENT_SUSPENDED
,
15791 VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT
);
15792 virObjectEventStateQueue(driver
->domainEventState
, event
);
15798 if (resume
&& virDomainObjIsActive(vm
) &&
15799 qemuProcessStartCPUs(driver
, vm
,
15800 VIR_DOMAIN_RUNNING_UNPAUSED
,
15801 QEMU_ASYNC_JOB_SNAPSHOT
) < 0) {
15802 event
= virDomainEventLifecycleNewFromObj(vm
,
15803 VIR_DOMAIN_EVENT_SUSPENDED
,
15804 VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR
);
15805 virObjectEventStateQueue(driver
->domainEventState
, event
);
15806 if (virGetLastErrorCode() == VIR_ERR_OK
) {
15807 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
15808 _("resuming after snapshot failed"));
15815 qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) >= 0 &&
15816 virDomainObjIsActive(vm
)) {
15817 if (qemuDomainSnapshotFSThaw(driver
, vm
, ret
== 0 && thaw
> 0) < 0) {
15818 /* helper reported the error, if it was needed */
15823 qemuDomainObjEndAgentJob(vm
);
15826 virQEMUSaveDataFree(data
);
15828 VIR_FREE(compressedpath
);
15829 virObjectUnref(cfg
);
15830 if (memory_unlink
&& ret
< 0)
15831 unlink(snap
->def
->file
);
15837 /* Validate that a snapshot object does not violate any qemu-specific
15840 qemuDomainSnapshotValidate(virDomainSnapshotDefPtr def
,
15841 virDomainSnapshotState state
,
15842 unsigned int flags
)
15844 /* reject snapshot names containing slashes or starting with dot as
15845 * snapshot definitions are saved in files named by the snapshot name */
15846 if (!(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA
)) {
15847 if (strchr(def
->name
, '/')) {
15848 virReportError(VIR_ERR_XML_DETAIL
,
15849 _("invalid snapshot name '%s': "
15850 "name can't contain '/'"),
15855 if (def
->name
[0] == '.') {
15856 virReportError(VIR_ERR_XML_DETAIL
,
15857 _("invalid snapshot name '%s': "
15858 "name can't start with '.'"),
15864 /* allow snapshots only in certain states */
15867 case VIR_SNAP_STATE_RUNNING
:
15868 case VIR_SNAP_STATE_PAUSED
:
15869 case VIR_SNAP_STATE_SHUTDOWN
:
15870 case VIR_SNAP_STATE_SHUTOFF
:
15871 case VIR_SNAP_STATE_CRASHED
:
15874 case VIR_SNAP_STATE_DISK_SNAPSHOT
:
15875 if (!(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
)) {
15876 virReportError(VIR_ERR_INTERNAL_ERROR
, _("Invalid domain state %s"),
15877 virDomainSnapshotStateTypeToString(state
));
15882 case VIR_SNAP_STATE_PMSUSPENDED
:
15883 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
15884 _("qemu doesn't support taking snapshots of "
15885 "PMSUSPENDED guests"));
15888 /* invalid states */
15889 case VIR_SNAP_STATE_NOSTATE
:
15890 case VIR_SNAP_STATE_BLOCKED
: /* invalid state, unused in qemu */
15891 case VIR_SNAP_STATE_LAST
:
15892 virReportError(VIR_ERR_INTERNAL_ERROR
, _("Invalid domain state %s"),
15893 virDomainSnapshotStateTypeToString(state
));
15900 /* Struct and hash-iterator callback used when bulk redefining snapshots */
15901 struct qemuDomainSnapshotBulk
{
15902 virDomainObjPtr vm
;
15903 virQEMUDriverPtr driver
;
15904 const char *snapshotDir
;
15905 unsigned int flags
;
15909 qemuDomainSnapshotBulkRedefine(void *payload
,
15910 const void *name ATTRIBUTE_UNUSED
,
15913 virDomainSnapshotObjPtr snap
= payload
;
15914 struct qemuDomainSnapshotBulk
*data
= opaque
;
15916 if (qemuDomainSnapshotValidate(snap
->def
, snap
->def
->state
,
15919 if (qemuDomainSnapshotWriteMetadata(data
->vm
, snap
, data
->driver
->caps
,
15920 data
->driver
->xmlopt
,
15921 data
->snapshotDir
) < 0)
15927 static virDomainSnapshotPtr
15928 qemuDomainSnapshotCreateXML(virDomainPtr domain
,
15929 const char *xmlDesc
,
15930 unsigned int flags
)
15932 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
15933 virDomainObjPtr vm
= NULL
;
15935 virDomainSnapshotObjPtr snap
= NULL
;
15936 virDomainSnapshotPtr snapshot
= NULL
;
15937 virDomainSnapshotDefPtr def
= NULL
;
15938 bool update_current
= true;
15939 bool redefine
= flags
& VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
;
15940 unsigned int parse_flags
= VIR_DOMAIN_SNAPSHOT_PARSE_DISKS
;
15941 virDomainSnapshotObjPtr other
= NULL
;
15942 int align_location
= VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL
;
15943 bool align_match
= true;
15944 virQEMUDriverConfigPtr cfg
= NULL
;
15945 virCapsPtr caps
= NULL
;
15946 qemuDomainObjPrivatePtr priv
;
15948 virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
|
15949 VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
|
15950 VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA
|
15951 VIR_DOMAIN_SNAPSHOT_CREATE_HALT
|
15952 VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
|
15953 VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT
|
15954 VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE
|
15955 VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC
|
15956 VIR_DOMAIN_SNAPSHOT_CREATE_LIVE
|
15957 VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE_LIST
, NULL
);
15959 VIR_REQUIRE_FLAG_RET(VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE
,
15960 VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
,
15962 VIR_EXCLUSIVE_FLAGS_RET(VIR_DOMAIN_SNAPSHOT_CREATE_LIVE
,
15963 VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
,
15966 if ((redefine
&& !(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
)) ||
15967 (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA
))
15968 update_current
= false;
15970 parse_flags
|= VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE
;
15972 if (!(vm
= qemuDomObjFromDomain(domain
)))
15975 cfg
= virQEMUDriverGetConfig(driver
);
15977 if (virDomainSnapshotCreateXMLEnsureACL(domain
->conn
, vm
->def
, flags
) < 0)
15980 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
15983 if (qemuProcessAutoDestroyActive(driver
, vm
)) {
15984 virReportError(VIR_ERR_OPERATION_INVALID
,
15985 "%s", _("domain is marked for auto destroy"));
15989 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE_LIST
) {
15990 struct qemuDomainSnapshotBulk bulk
= {
15993 .snapshotDir
= cfg
->snapshotDir
,
15997 if (virDomainSnapshotObjListParse(xmlDesc
, vm
->def
->uuid
,
15998 vm
->snapshots
, &vm
->current_snapshot
,
15999 caps
, driver
->xmlopt
,
16002 /* Validate and save the snapshots to disk. Since we don't get
16003 * here unless there were no snapshots beforehand, just delete
16004 * everything if anything failed, ignoring further errors. */
16005 if (virDomainSnapshotForEach(vm
->snapshots
,
16006 qemuDomainSnapshotBulkRedefine
,
16008 virErrorPtr orig_err
= virSaveLastError();
16010 qemuDomainSnapshotDiscardAllMetadata(driver
, vm
);
16011 virSetError(orig_err
);
16012 virFreeError(orig_err
);
16015 /* Return is arbitrary, so use the first root */
16016 snap
= virDomainSnapshotFindByName(vm
->snapshots
, NULL
);
16017 snapshot
= virGetDomainSnapshot(domain
, snap
->first_child
->def
->name
);
16021 if (!vm
->persistent
&& (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_HALT
)) {
16022 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
16023 _("cannot halt after transient domain snapshot"));
16026 if ((flags
& VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
) ||
16027 !virDomainObjIsActive(vm
))
16028 parse_flags
|= VIR_DOMAIN_SNAPSHOT_PARSE_OFFLINE
;
16030 if (!(def
= virDomainSnapshotDefParseString(xmlDesc
, caps
, driver
->xmlopt
,
16034 if (qemuDomainSnapshotValidate(def
, redefine
? def
->state
: vm
->state
.state
,
16038 /* reject the VIR_DOMAIN_SNAPSHOT_CREATE_LIVE flag where not supported */
16039 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_LIVE
&&
16040 (!virDomainObjIsActive(vm
) ||
16041 def
->memory
!= VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
)) {
16042 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
16043 _("live snapshot creation is supported only "
16044 "during full system snapshots"));
16048 /* We are going to modify the domain below. Internal snapshots would use
16049 * a regular job, so we need to set the job mask to disallow query as
16050 * 'savevm' blocks the monitor. External snapshot will then modify the
16051 * job mask appropriately. */
16052 if (qemuDomainObjBeginAsyncJob(driver
, vm
, QEMU_ASYNC_JOB_SNAPSHOT
,
16053 VIR_DOMAIN_JOB_OPERATION_SNAPSHOT
, flags
) < 0)
16056 qemuDomainObjSetAsyncJobMask(vm
, QEMU_JOB_NONE
);
16058 priv
= vm
->privateData
;
16061 if (virDomainSnapshotRedefinePrep(domain
, vm
, &def
, &snap
,
16063 &update_current
, flags
) < 0)
16066 /* Easiest way to clone inactive portion of vm->def is via
16067 * conversion in and back out of xml. */
16068 if (!(xml
= qemuDomainDefFormatLive(driver
, vm
->def
, priv
->origCPU
,
16070 !(def
->dom
= virDomainDefParseString(xml
, caps
, driver
->xmlopt
, NULL
,
16071 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
16072 VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
)))
16075 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
) {
16076 align_location
= VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
;
16077 align_match
= false;
16078 if (virDomainObjIsActive(vm
))
16079 def
->state
= VIR_SNAP_STATE_DISK_SNAPSHOT
;
16081 def
->state
= VIR_SNAP_STATE_SHUTOFF
;
16082 def
->memory
= VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
;
16083 } else if (def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
) {
16084 def
->state
= virDomainObjGetState(vm
, NULL
);
16085 align_location
= VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
;
16086 align_match
= false;
16088 def
->state
= virDomainObjGetState(vm
, NULL
);
16090 if (virDomainObjIsActive(vm
) &&
16091 def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
) {
16092 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
16093 _("internal snapshot of a running VM "
16094 "must include the memory state"));
16098 def
->memory
= (def
->state
== VIR_SNAP_STATE_SHUTOFF
?
16099 VIR_DOMAIN_SNAPSHOT_LOCATION_NONE
:
16100 VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL
);
16102 if (virDomainSnapshotAlignDisks(def
, align_location
,
16103 align_match
) < 0 ||
16104 qemuDomainSnapshotPrepare(vm
, def
, &flags
) < 0)
16109 if (!(snap
= virDomainSnapshotAssignDef(vm
->snapshots
, def
)))
16115 if (update_current
)
16116 snap
->def
->current
= true;
16117 if (vm
->current_snapshot
) {
16119 VIR_STRDUP(snap
->def
->parent
, vm
->current_snapshot
->def
->name
) < 0)
16121 if (update_current
) {
16122 vm
->current_snapshot
->def
->current
= false;
16123 if (qemuDomainSnapshotWriteMetadata(vm
, vm
->current_snapshot
,
16124 driver
->caps
, driver
->xmlopt
,
16125 cfg
->snapshotDir
) < 0)
16127 vm
->current_snapshot
= NULL
;
16131 /* actually do the snapshot */
16133 /* XXX Should we validate that the redefined snapshot even
16134 * makes sense, such as checking that qemu-img recognizes the
16135 * snapshot name in at least one of the domain's disks? */
16136 } else if (virDomainObjIsActive(vm
)) {
16137 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
||
16138 snap
->def
->memory
== VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL
) {
16139 /* external full system or disk snapshot */
16140 if (qemuDomainSnapshotCreateActiveExternal(driver
,
16141 vm
, snap
, flags
) < 0)
16144 /* internal full system */
16145 if (qemuDomainSnapshotCreateActiveInternal(driver
,
16146 vm
, snap
, flags
) < 0)
16150 /* inactive; qemuDomainSnapshotPrepare guaranteed that we
16151 * aren't mixing internal and external, and altered flags to
16152 * contain DISK_ONLY if there is an external disk. */
16153 if (flags
& VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY
) {
16154 bool reuse
= !!(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT
);
16156 if (qemuDomainSnapshotCreateInactiveExternal(driver
, vm
, snap
,
16160 if (qemuDomainSnapshotCreateInactiveInternal(driver
, vm
, snap
) < 0)
16165 /* If we fail after this point, there's not a whole lot we can
16166 * do; we've successfully taken the snapshot, and we are now running
16167 * on it, so we have to go forward the best we can
16169 snapshot
= virGetDomainSnapshot(domain
, snap
->def
->name
);
16172 if (snapshot
&& !(flags
& VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA
)) {
16173 if (qemuDomainSnapshotWriteMetadata(vm
, snap
, driver
->caps
,
16175 cfg
->snapshotDir
) < 0) {
16176 /* if writing of metadata fails, error out rather than trying
16177 * to silently carry on without completing the snapshot */
16178 virObjectUnref(snapshot
);
16180 virReportError(VIR_ERR_INTERNAL_ERROR
,
16181 _("unable to save metadata for snapshot %s"),
16183 virDomainSnapshotObjListRemove(vm
->snapshots
, snap
);
16185 if (update_current
)
16186 vm
->current_snapshot
= snap
;
16187 other
= virDomainSnapshotFindByName(vm
->snapshots
,
16188 snap
->def
->parent
);
16189 snap
->parent
= other
;
16190 other
->nchildren
++;
16191 snap
->sibling
= other
->first_child
;
16192 other
->first_child
= snap
;
16195 virDomainSnapshotObjListRemove(vm
->snapshots
, snap
);
16198 qemuDomainObjEndAsyncJob(driver
, vm
);
16201 virDomainObjEndAPI(&vm
);
16202 virDomainSnapshotDefFree(def
);
16204 virObjectUnref(caps
);
16205 virObjectUnref(cfg
);
16211 qemuDomainSnapshotListNames(virDomainPtr domain
,
16214 unsigned int flags
)
16216 virDomainObjPtr vm
= NULL
;
16219 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
|
16220 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16222 if (!(vm
= qemuDomObjFromDomain(domain
)))
16225 if (virDomainSnapshotListNamesEnsureACL(domain
->conn
, vm
->def
) < 0)
16228 n
= virDomainSnapshotObjListGetNames(vm
->snapshots
, NULL
, names
, nameslen
,
16232 virDomainObjEndAPI(&vm
);
16238 qemuDomainSnapshotNum(virDomainPtr domain
,
16239 unsigned int flags
)
16241 virDomainObjPtr vm
= NULL
;
16244 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
|
16245 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16247 if (!(vm
= qemuDomObjFromDomain(domain
)))
16250 if (virDomainSnapshotNumEnsureACL(domain
->conn
, vm
->def
) < 0)
16253 n
= virDomainSnapshotObjListNum(vm
->snapshots
, NULL
, flags
);
16256 virDomainObjEndAPI(&vm
);
16262 qemuDomainListAllSnapshots(virDomainPtr domain
,
16263 virDomainSnapshotPtr
**snaps
,
16264 unsigned int flags
)
16266 virDomainObjPtr vm
= NULL
;
16269 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
|
16270 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16272 if (!(vm
= qemuDomObjFromDomain(domain
)))
16275 if (virDomainListAllSnapshotsEnsureACL(domain
->conn
, vm
->def
) < 0)
16278 n
= virDomainListSnapshots(vm
->snapshots
, NULL
, domain
, snaps
, flags
);
16281 virDomainObjEndAPI(&vm
);
16287 qemuDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot
,
16290 unsigned int flags
)
16292 virDomainObjPtr vm
= NULL
;
16293 virDomainSnapshotObjPtr snap
= NULL
;
16296 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS
|
16297 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16299 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16302 if (virDomainSnapshotListChildrenNamesEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16305 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16308 n
= virDomainSnapshotObjListGetNames(vm
->snapshots
, snap
, names
, nameslen
,
16312 virDomainObjEndAPI(&vm
);
16318 qemuDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot
,
16319 unsigned int flags
)
16321 virDomainObjPtr vm
= NULL
;
16322 virDomainSnapshotObjPtr snap
= NULL
;
16325 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS
|
16326 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16328 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16331 if (virDomainSnapshotNumChildrenEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16334 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16337 n
= virDomainSnapshotObjListNum(vm
->snapshots
, snap
, flags
);
16340 virDomainObjEndAPI(&vm
);
16346 qemuDomainSnapshotListAllChildren(virDomainSnapshotPtr snapshot
,
16347 virDomainSnapshotPtr
**snaps
,
16348 unsigned int flags
)
16350 virDomainObjPtr vm
= NULL
;
16351 virDomainSnapshotObjPtr snap
= NULL
;
16354 virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS
|
16355 VIR_DOMAIN_SNAPSHOT_FILTERS_ALL
, -1);
16357 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16360 if (virDomainSnapshotListAllChildrenEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16363 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16366 n
= virDomainListSnapshots(vm
->snapshots
, snap
, snapshot
->domain
, snaps
,
16370 virDomainObjEndAPI(&vm
);
16375 static virDomainSnapshotPtr
16376 qemuDomainSnapshotLookupByName(virDomainPtr domain
,
16378 unsigned int flags
)
16380 virDomainObjPtr vm
;
16381 virDomainSnapshotObjPtr snap
= NULL
;
16382 virDomainSnapshotPtr snapshot
= NULL
;
16384 virCheckFlags(0, NULL
);
16386 if (!(vm
= qemuDomObjFromDomain(domain
)))
16389 if (virDomainSnapshotLookupByNameEnsureACL(domain
->conn
, vm
->def
) < 0)
16392 if (!(snap
= qemuSnapObjFromName(vm
, name
)))
16395 snapshot
= virGetDomainSnapshot(domain
, snap
->def
->name
);
16398 virDomainObjEndAPI(&vm
);
16404 qemuDomainHasCurrentSnapshot(virDomainPtr domain
,
16405 unsigned int flags
)
16407 virDomainObjPtr vm
;
16410 virCheckFlags(0, -1);
16412 if (!(vm
= qemuDomObjFromDomain(domain
)))
16415 if (virDomainHasCurrentSnapshotEnsureACL(domain
->conn
, vm
->def
) < 0)
16418 ret
= (vm
->current_snapshot
!= NULL
);
16421 virDomainObjEndAPI(&vm
);
16426 static virDomainSnapshotPtr
16427 qemuDomainSnapshotGetParent(virDomainSnapshotPtr snapshot
,
16428 unsigned int flags
)
16430 virDomainObjPtr vm
;
16431 virDomainSnapshotObjPtr snap
= NULL
;
16432 virDomainSnapshotPtr parent
= NULL
;
16434 virCheckFlags(0, NULL
);
16436 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16439 if (virDomainSnapshotGetParentEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16442 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16445 if (!snap
->def
->parent
) {
16446 virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT
,
16447 _("snapshot '%s' does not have a parent"),
16452 parent
= virGetDomainSnapshot(snapshot
->domain
, snap
->def
->parent
);
16455 virDomainObjEndAPI(&vm
);
16460 static virDomainSnapshotPtr
16461 qemuDomainSnapshotCurrent(virDomainPtr domain
,
16462 unsigned int flags
)
16464 virDomainObjPtr vm
;
16465 virDomainSnapshotPtr snapshot
= NULL
;
16467 virCheckFlags(0, NULL
);
16469 if (!(vm
= qemuDomObjFromDomain(domain
)))
16472 if (virDomainSnapshotCurrentEnsureACL(domain
->conn
, vm
->def
) < 0)
16475 if (!vm
->current_snapshot
) {
16476 virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT
, "%s",
16477 _("the domain does not have a current snapshot"));
16481 snapshot
= virGetDomainSnapshot(domain
, vm
->current_snapshot
->def
->name
);
16484 virDomainObjEndAPI(&vm
);
16490 qemuDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot
,
16491 unsigned int flags
)
16493 virQEMUDriverPtr driver
= snapshot
->domain
->conn
->privateData
;
16494 virDomainObjPtr vm
= NULL
;
16496 virDomainSnapshotObjPtr snap
= NULL
;
16497 char uuidstr
[VIR_UUID_STRING_BUFLEN
];
16499 virCheckFlags(VIR_DOMAIN_SNAPSHOT_XML_SECURE
, NULL
);
16501 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16504 if (virDomainSnapshotGetXMLDescEnsureACL(snapshot
->domain
->conn
, vm
->def
, flags
) < 0)
16507 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16510 virUUIDFormat(snapshot
->domain
->uuid
, uuidstr
);
16512 xml
= virDomainSnapshotDefFormat(uuidstr
, snap
->def
,
16513 driver
->caps
, driver
->xmlopt
,
16514 virDomainSnapshotFormatConvertXMLFlags(flags
));
16517 virDomainObjEndAPI(&vm
);
16523 qemuDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot
,
16524 unsigned int flags
)
16526 virDomainObjPtr vm
= NULL
;
16528 virDomainSnapshotObjPtr snap
= NULL
;
16530 virCheckFlags(0, -1);
16532 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16535 if (virDomainSnapshotIsCurrentEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16538 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16541 ret
= (vm
->current_snapshot
&&
16542 STREQ(snapshot
->name
, vm
->current_snapshot
->def
->name
));
16545 virDomainObjEndAPI(&vm
);
16551 qemuDomainSnapshotHasMetadata(virDomainSnapshotPtr snapshot
,
16552 unsigned int flags
)
16554 virDomainObjPtr vm
= NULL
;
16556 virDomainSnapshotObjPtr snap
= NULL
;
16558 virCheckFlags(0, -1);
16560 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16563 if (virDomainSnapshotHasMetadataEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16566 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16569 /* XXX Someday, we should recognize internal snapshots in qcow2
16570 * images that are not tied to a libvirt snapshot; if we ever do
16571 * that, then we would have a reason to return 0 here. */
16575 virDomainObjEndAPI(&vm
);
16580 /* The domain is expected to be locked and inactive. */
16582 qemuDomainSnapshotRevertInactive(virQEMUDriverPtr driver
,
16583 virDomainObjPtr vm
,
16584 virDomainSnapshotObjPtr snap
)
16586 /* Try all disks, but report failure if we skipped any. */
16587 int ret
= qemuDomainSnapshotForEachQcow2(driver
, vm
, snap
, "-a", true);
16588 return ret
> 0 ? -1 : ret
;
16593 qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot
,
16594 unsigned int flags
)
16596 virQEMUDriverPtr driver
= snapshot
->domain
->conn
->privateData
;
16597 virDomainObjPtr vm
= NULL
;
16599 virDomainSnapshotObjPtr snap
= NULL
;
16600 virObjectEventPtr event
= NULL
;
16601 virObjectEventPtr event2
= NULL
;
16603 qemuDomainObjPrivatePtr priv
;
16605 virDomainDefPtr config
= NULL
;
16606 virQEMUDriverConfigPtr cfg
= NULL
;
16607 virCapsPtr caps
= NULL
;
16608 bool was_stopped
= false;
16609 qemuDomainSaveCookiePtr cookie
;
16610 virCPUDefPtr origCPU
= NULL
;
16611 unsigned int start_flags
= VIR_QEMU_PROCESS_START_GEN_VMID
;
16612 qemuDomainAsyncJob jobType
= QEMU_ASYNC_JOB_START
;
16614 virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING
|
16615 VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
|
16616 VIR_DOMAIN_SNAPSHOT_REVERT_FORCE
, -1);
16618 /* We have the following transitions, which create the following events:
16619 * 1. inactive -> inactive: none
16620 * 2. inactive -> running: EVENT_STARTED
16621 * 3. inactive -> paused: EVENT_STARTED, EVENT_PAUSED
16622 * 4. running -> inactive: EVENT_STOPPED
16623 * 5. running -> running: none
16624 * 6. running -> paused: EVENT_PAUSED
16625 * 7. paused -> inactive: EVENT_STOPPED
16626 * 8. paused -> running: EVENT_RESUMED
16627 * 9. paused -> paused: none
16628 * Also, several transitions occur even if we fail partway through,
16629 * and use of FORCE can cause multiple transitions.
16632 virNWFilterReadLockFilterUpdates();
16634 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
16637 cfg
= virQEMUDriverGetConfig(driver
);
16639 if (virDomainRevertToSnapshotEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
16642 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
16645 if (qemuDomainHasBlockjob(vm
, false)) {
16646 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
16647 _("domain has active block job"));
16651 if (qemuProcessBeginJob(driver
, vm
,
16652 VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT
,
16656 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
16659 if (!vm
->persistent
&&
16660 snap
->def
->state
!= VIR_SNAP_STATE_RUNNING
&&
16661 snap
->def
->state
!= VIR_SNAP_STATE_PAUSED
&&
16662 (flags
& (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING
|
16663 VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
)) == 0) {
16664 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
16665 _("transient domain needs to request run or pause "
16666 "to revert to inactive snapshot"));
16670 if (virDomainSnapshotIsExternal(snap
)) {
16671 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
16672 _("revert to external snapshot not supported yet"));
16676 if (!(flags
& VIR_DOMAIN_SNAPSHOT_REVERT_FORCE
)) {
16677 if (!snap
->def
->dom
) {
16678 virReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY
,
16679 _("snapshot '%s' lacks domain '%s' rollback info"),
16680 snap
->def
->name
, vm
->def
->name
);
16683 if (virDomainObjIsActive(vm
) &&
16684 !(snap
->def
->state
== VIR_SNAP_STATE_RUNNING
||
16685 snap
->def
->state
== VIR_SNAP_STATE_PAUSED
) &&
16686 (flags
& (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING
|
16687 VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
))) {
16688 virReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY
, "%s",
16689 _("must respawn qemu to start inactive snapshot"));
16695 if (vm
->current_snapshot
) {
16696 vm
->current_snapshot
->def
->current
= false;
16697 if (qemuDomainSnapshotWriteMetadata(vm
, vm
->current_snapshot
,
16698 driver
->caps
, driver
->xmlopt
,
16699 cfg
->snapshotDir
) < 0)
16701 vm
->current_snapshot
= NULL
;
16702 /* XXX Should we restore vm->current_snapshot after this point
16703 * in the failure cases where we know there was no change? */
16706 /* Prepare to copy the snapshot inactive xml as the config of this
16709 * XXX Should domain snapshots track live xml rather
16710 * than inactive xml? */
16711 snap
->def
->current
= true;
16712 if (snap
->def
->dom
) {
16713 config
= virDomainDefCopy(snap
->def
->dom
, caps
,
16714 driver
->xmlopt
, NULL
, true);
16719 cookie
= (qemuDomainSaveCookiePtr
) snap
->def
->cookie
;
16721 switch ((virDomainSnapshotState
) snap
->def
->state
) {
16722 case VIR_SNAP_STATE_RUNNING
:
16723 case VIR_SNAP_STATE_PAUSED
:
16725 start_flags
|= VIR_QEMU_PROCESS_START_PAUSED
;
16727 /* Transitions 2, 3, 5, 6, 8, 9 */
16728 /* When using the loadvm monitor command, qemu does not know
16729 * whether to pause or run the reverted domain, and just stays
16730 * in the same state as before the monitor command, whether
16731 * that is paused or running. We always pause before loadvm,
16732 * to have finer control. */
16733 if (virDomainObjIsActive(vm
)) {
16734 /* Transitions 5, 6, 8, 9 */
16735 /* Check for ABI compatibility. We need to do this check against
16736 * the migratable XML or it will always fail otherwise */
16740 /* Replace the CPU in config and put the original one in priv
16741 * once we're done. When we have the updated CPU def in the
16742 * cookie, we don't want to replace the CPU in migratable def
16743 * when doing ABI checks to make sure the current CPU exactly
16744 * matches the one used at the time the snapshot was taken.
16746 if (cookie
&& cookie
->cpu
&& config
->cpu
) {
16747 origCPU
= config
->cpu
;
16748 if (!(config
->cpu
= virCPUDefCopy(cookie
->cpu
)))
16751 compatible
= qemuDomainDefCheckABIStability(driver
, vm
->def
,
16754 compatible
= qemuDomainCheckABIStability(driver
, vm
, config
);
16757 /* If using VM GenID, there is no way currently to change
16758 * the genid for the running guest, so set an error,
16759 * mark as incompatible, and don't allow change of genid
16760 * if the revert force flag would start the guest again. */
16761 if (compatible
&& config
->genidRequested
) {
16762 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
16763 _("domain genid update requires restart"));
16764 compatible
= false;
16765 start_flags
&= ~VIR_QEMU_PROCESS_START_GEN_VMID
;
16769 virErrorPtr err
= virGetLastError();
16771 if (!(flags
& VIR_DOMAIN_SNAPSHOT_REVERT_FORCE
)) {
16772 /* Re-spawn error using correct category. */
16773 if (err
->code
== VIR_ERR_CONFIG_UNSUPPORTED
)
16774 virReportError(VIR_ERR_SNAPSHOT_REVERT_RISKY
, "%s",
16778 virResetError(err
);
16779 qemuProcessStop(driver
, vm
,
16780 VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT
,
16781 QEMU_ASYNC_JOB_START
, 0);
16782 virDomainAuditStop(vm
, "from-snapshot");
16783 detail
= VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT
;
16784 event
= virDomainEventLifecycleNewFromObj(vm
,
16785 VIR_DOMAIN_EVENT_STOPPED
,
16787 virObjectEventStateQueue(driver
->domainEventState
, event
);
16788 /* Start after stop won't be an async start job, so
16790 jobType
= QEMU_ASYNC_JOB_NONE
;
16795 priv
= vm
->privateData
;
16796 if (virDomainObjGetState(vm
, NULL
) == VIR_DOMAIN_RUNNING
) {
16797 /* Transitions 5, 6 */
16798 if (qemuProcessStopCPUs(driver
, vm
,
16799 VIR_DOMAIN_PAUSED_FROM_SNAPSHOT
,
16800 QEMU_ASYNC_JOB_START
) < 0)
16802 /* Create an event now in case the restore fails, so
16803 * that user will be alerted that they are now paused.
16804 * If restore later succeeds, we might replace this. */
16805 detail
= VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT
;
16806 event
= virDomainEventLifecycleNewFromObj(vm
,
16807 VIR_DOMAIN_EVENT_SUSPENDED
,
16809 if (!virDomainObjIsActive(vm
)) {
16810 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
16811 _("guest unexpectedly quit"));
16816 if (qemuDomainObjEnterMonitorAsync(driver
, vm
,
16817 QEMU_ASYNC_JOB_START
) < 0)
16819 rc
= qemuMonitorLoadSnapshot(priv
->mon
, snap
->def
->name
);
16820 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
16823 /* XXX resume domain if it was running before the
16824 * failed loadvm attempt? */
16828 virDomainObjAssignDef(vm
, config
, false, NULL
);
16829 virCPUDefFree(priv
->origCPU
);
16830 VIR_STEAL_PTR(priv
->origCPU
, origCPU
);
16833 /* Transitions 2, 3 */
16835 was_stopped
= true;
16837 virDomainObjAssignDef(vm
, config
, false, NULL
);
16839 /* No cookie means libvirt which saved the domain was too old to
16840 * mess up the CPU definitions.
16843 qemuDomainFixupCPUs(vm
, &cookie
->cpu
) < 0)
16846 rc
= qemuProcessStart(snapshot
->domain
->conn
, driver
, vm
,
16847 cookie
? cookie
->cpu
: NULL
,
16848 jobType
, NULL
, -1, NULL
, snap
,
16849 VIR_NETDEV_VPORT_PROFILE_OP_CREATE
,
16851 virDomainAuditStart(vm
, "from-snapshot", rc
>= 0);
16852 detail
= VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT
;
16853 event
= virDomainEventLifecycleNewFromObj(vm
,
16854 VIR_DOMAIN_EVENT_STARTED
,
16860 /* Touch up domain state. */
16861 if (!(flags
& VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING
) &&
16862 (snap
->def
->state
== VIR_SNAP_STATE_PAUSED
||
16863 (flags
& VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
))) {
16864 /* Transitions 3, 6, 9 */
16865 virDomainObjSetState(vm
, VIR_DOMAIN_PAUSED
,
16866 VIR_DOMAIN_PAUSED_FROM_SNAPSHOT
);
16868 /* Transition 3, use event as-is and add event2 */
16869 detail
= VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT
;
16870 event2
= virDomainEventLifecycleNewFromObj(vm
,
16871 VIR_DOMAIN_EVENT_SUSPENDED
,
16873 } /* else transition 6 and 9 use event as-is */
16875 /* Transitions 2, 5, 8 */
16876 if (!virDomainObjIsActive(vm
)) {
16877 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
16878 _("guest unexpectedly quit"));
16881 rc
= qemuProcessStartCPUs(driver
, vm
,
16882 VIR_DOMAIN_RUNNING_FROM_SNAPSHOT
,
16886 virObjectUnref(event
);
16890 detail
= VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT
;
16891 event
= virDomainEventLifecycleNewFromObj(vm
,
16892 VIR_DOMAIN_EVENT_STARTED
,
16898 case VIR_SNAP_STATE_SHUTDOWN
:
16899 case VIR_SNAP_STATE_SHUTOFF
:
16900 case VIR_SNAP_STATE_CRASHED
:
16901 /* Transitions 1, 4, 7 */
16902 /* Newer qemu -loadvm refuses to revert to the state of a snapshot
16903 * created by qemu-img snapshot -c. If the domain is running, we
16904 * must take it offline; then do the revert using qemu-img.
16907 if (virDomainObjIsActive(vm
)) {
16908 /* Transitions 4, 7 */
16909 qemuProcessStop(driver
, vm
, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT
,
16910 QEMU_ASYNC_JOB_START
, 0);
16911 virDomainAuditStop(vm
, "from-snapshot");
16912 detail
= VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT
;
16913 event
= virDomainEventLifecycleNewFromObj(vm
,
16914 VIR_DOMAIN_EVENT_STOPPED
,
16918 if (qemuDomainSnapshotRevertInactive(driver
, vm
, snap
) < 0) {
16919 qemuDomainRemoveInactive(driver
, vm
);
16920 qemuProcessEndJob(driver
, vm
);
16924 virDomainObjAssignDef(vm
, config
, false, NULL
);
16926 if (flags
& (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING
|
16927 VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
)) {
16928 /* Flush first event, now do transition 2 or 3 */
16929 bool paused
= (flags
& VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED
) != 0;
16931 start_flags
|= paused
? VIR_QEMU_PROCESS_START_PAUSED
: 0;
16933 virObjectEventStateQueue(driver
->domainEventState
, event
);
16934 rc
= qemuProcessStart(snapshot
->domain
->conn
, driver
, vm
, NULL
,
16935 QEMU_ASYNC_JOB_START
, NULL
, -1, NULL
, NULL
,
16936 VIR_NETDEV_VPORT_PROFILE_OP_CREATE
,
16938 virDomainAuditStart(vm
, "from-snapshot", rc
>= 0);
16940 qemuDomainRemoveInactive(driver
, vm
);
16941 qemuProcessEndJob(driver
, vm
);
16944 detail
= VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT
;
16945 event
= virDomainEventLifecycleNewFromObj(vm
,
16946 VIR_DOMAIN_EVENT_STARTED
,
16949 detail
= VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT
;
16950 event2
= virDomainEventLifecycleNewFromObj(vm
,
16951 VIR_DOMAIN_EVENT_SUSPENDED
,
16957 case VIR_SNAP_STATE_PMSUSPENDED
:
16958 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
16959 _("qemu doesn't support reversion of snapshot taken in "
16960 "PMSUSPENDED state"));
16963 case VIR_SNAP_STATE_DISK_SNAPSHOT
:
16964 /* Rejected earlier as an external snapshot */
16965 case VIR_SNAP_STATE_NOSTATE
:
16966 case VIR_SNAP_STATE_BLOCKED
:
16967 case VIR_SNAP_STATE_LAST
:
16968 virReportError(VIR_ERR_INTERNAL_ERROR
,
16969 _("Invalid target domain state '%s'. Refusing "
16970 "snapshot reversion"),
16971 virDomainSnapshotStateTypeToString(snap
->def
->state
));
16978 qemuProcessEndJob(driver
, vm
);
16982 if (qemuDomainSnapshotWriteMetadata(vm
, snap
, driver
->caps
,
16984 cfg
->snapshotDir
) < 0)
16987 vm
->current_snapshot
= snap
;
16989 snap
->def
->current
= false;
16991 if (ret
== 0 && config
&& vm
->persistent
&&
16992 !(ret
= virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
16993 vm
->newDef
? vm
->newDef
: vm
->def
))) {
16994 detail
= VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT
;
16995 virObjectEventStateQueue(driver
->domainEventState
,
16996 virDomainEventLifecycleNewFromObj(vm
,
16997 VIR_DOMAIN_EVENT_DEFINED
,
17000 virObjectEventStateQueue(driver
->domainEventState
, event
);
17001 virObjectEventStateQueue(driver
->domainEventState
, event2
);
17002 virDomainObjEndAPI(&vm
);
17003 virObjectUnref(caps
);
17004 virObjectUnref(cfg
);
17005 virNWFilterUnlockFilterUpdates();
17006 virCPUDefFree(origCPU
);
17012 typedef struct _virQEMUSnapReparent virQEMUSnapReparent
;
17013 typedef virQEMUSnapReparent
*virQEMUSnapReparentPtr
;
17014 struct _virQEMUSnapReparent
{
17015 virQEMUDriverConfigPtr cfg
;
17016 virDomainSnapshotObjPtr parent
;
17017 virDomainObjPtr vm
;
17019 virDomainXMLOptionPtr xmlopt
;
17021 virDomainSnapshotObjPtr last
;
17026 qemuDomainSnapshotReparentChildren(void *payload
,
17027 const void *name ATTRIBUTE_UNUSED
,
17030 virDomainSnapshotObjPtr snap
= payload
;
17031 virQEMUSnapReparentPtr rep
= data
;
17036 VIR_FREE(snap
->def
->parent
);
17037 snap
->parent
= rep
->parent
;
17039 if (rep
->parent
->def
&&
17040 VIR_STRDUP(snap
->def
->parent
, rep
->parent
->def
->name
) < 0) {
17045 if (!snap
->sibling
)
17048 rep
->err
= qemuDomainSnapshotWriteMetadata(rep
->vm
, snap
,
17049 rep
->caps
, rep
->xmlopt
,
17050 rep
->cfg
->snapshotDir
);
17056 qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot
,
17057 unsigned int flags
)
17059 virQEMUDriverPtr driver
= snapshot
->domain
->conn
->privateData
;
17060 virDomainObjPtr vm
= NULL
;
17062 virDomainSnapshotObjPtr snap
= NULL
;
17063 virQEMUDependentRemove rem
;
17064 virQEMUSnapReparent rep
;
17065 bool metadata_only
= !!(flags
& VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY
);
17067 virQEMUDriverConfigPtr cfg
= NULL
;
17069 virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN
|
17070 VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY
|
17071 VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
, -1);
17073 if (!(vm
= qemuDomObjFromSnapshot(snapshot
)))
17076 cfg
= virQEMUDriverGetConfig(driver
);
17078 if (virDomainSnapshotDeleteEnsureACL(snapshot
->domain
->conn
, vm
->def
) < 0)
17081 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
17084 if (!(snap
= qemuSnapObjFromSnapshot(vm
, snapshot
)))
17087 if (!metadata_only
) {
17088 if (!(flags
& VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
) &&
17089 virDomainSnapshotIsExternal(snap
))
17091 if (flags
& (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN
|
17092 VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
))
17093 virDomainSnapshotForEachDescendant(snap
,
17094 qemuDomainSnapshotCountExternal
,
17097 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
17098 _("deletion of %d external disk snapshots not "
17099 "supported yet"), external
);
17104 if (flags
& (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN
|
17105 VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
)) {
17106 rem
.driver
= driver
;
17108 rem
.metadata_only
= metadata_only
;
17110 rem
.current
= false;
17111 virDomainSnapshotForEachDescendant(snap
,
17112 qemuDomainSnapshotDiscardAll
,
17117 if (flags
& VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
) {
17118 snap
->def
->current
= true;
17119 if (qemuDomainSnapshotWriteMetadata(vm
, snap
, driver
->caps
,
17121 cfg
->snapshotDir
) < 0) {
17122 virReportError(VIR_ERR_INTERNAL_ERROR
,
17123 _("failed to set snapshot '%s' as current"),
17125 snap
->def
->current
= false;
17129 vm
->current_snapshot
= snap
;
17131 } else if (snap
->nchildren
) {
17133 rep
.parent
= snap
->parent
;
17137 rep
.caps
= driver
->caps
;
17138 rep
.xmlopt
= driver
->xmlopt
;
17139 virDomainSnapshotForEachChild(snap
,
17140 qemuDomainSnapshotReparentChildren
,
17144 /* Can't modify siblings during ForEachChild, so do it now. */
17145 snap
->parent
->nchildren
+= snap
->nchildren
;
17146 rep
.last
->sibling
= snap
->parent
->first_child
;
17147 snap
->parent
->first_child
= snap
->first_child
;
17150 if (flags
& VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
) {
17151 snap
->nchildren
= 0;
17152 snap
->first_child
= NULL
;
17155 ret
= qemuDomainSnapshotDiscard(driver
, vm
, snap
, true, metadata_only
);
17159 qemuDomainObjEndJob(driver
, vm
);
17162 virDomainObjEndAPI(&vm
);
17163 virObjectUnref(cfg
);
17168 /* Called prior to job lock */
17169 static virDomainCheckpointDefPtr
17170 qemuDomainCheckpointDefParseString(virQEMUDriverPtr driver
, virCapsPtr caps
,
17171 const char *xmlDesc
, unsigned int flags
)
17173 virDomainCheckpointDefPtr def
= NULL
;
17174 virDomainCheckpointDefPtr ret
= NULL
;
17175 unsigned int parse_flags
= VIR_DOMAIN_CHECKPOINT_PARSE_DISKS
;
17177 if (flags
& VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE
)
17178 parse_flags
|= VIR_DOMAIN_CHECKPOINT_PARSE_REDEFINE
;
17179 if (!(def
= virDomainCheckpointDefParseString(xmlDesc
, caps
, driver
->xmlopt
,
17183 /* reject checkpoint names containing slashes or starting with dot as
17184 * checkpoint definitions are saved in files named by the checkpoint name */
17185 if (!(flags
& VIR_DOMAIN_CHECKPOINT_CREATE_NO_METADATA
)) {
17186 if (strchr(def
->name
, '/')) {
17187 virReportError(VIR_ERR_XML_DETAIL
,
17188 _("invalid checkpoint name '%s': "
17189 "name can't contain '/'"),
17194 if (def
->name
[0] == '.') {
17195 virReportError(VIR_ERR_XML_DETAIL
,
17196 _("invalid checkpoint name '%s': "
17197 "name can't start with '.'"),
17203 VIR_STEAL_PTR(ret
, def
);
17206 virDomainCheckpointDefFree(def
);
17211 /* Called inside job lock */
17213 qemuDomainCheckpointPrepare(virQEMUDriverPtr driver
, virCapsPtr caps
,
17214 virDomainObjPtr vm
,
17215 virDomainCheckpointDefPtr def
)
17220 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
17222 /* Easiest way to clone inactive portion of vm->def is via
17223 * conversion in and back out of xml. */
17224 if (!(xml
= qemuDomainDefFormatLive(driver
, vm
->def
, priv
->origCPU
,
17226 !(def
->dom
= virDomainDefParseString(xml
, caps
, driver
->xmlopt
, NULL
,
17227 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
17228 VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE
)))
17231 if (virDomainCheckpointAlignDisks(def
) < 0 ||
17232 qemuBlockNodeNamesDetect(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
17235 for (i
= 0; i
< def
->ndisks
; i
++) {
17236 virDomainCheckpointDiskDefPtr disk
= &def
->disks
[i
];
17238 if (disk
->type
!= VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP
)
17241 /* We want to name temporary bitmap after disk name during
17242 * incremental backup, which is not possible if that is a
17243 * persistent bitmap name. We can also make life easier by
17244 * enforcing bitmap names match checkpoint name, although this
17245 * is not technically necessary. */
17246 if (STREQ(disk
->name
, disk
->bitmap
)) {
17247 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
17248 _("checkpoint for disk %s must have distinct bitmap name"),
17252 if (STRNEQ(disk
->bitmap
, def
->name
)) {
17253 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
17254 _("disk %s bitmap should match checkpoint name %s"),
17255 disk
->name
, def
->name
);
17259 if (vm
->def
->disks
[i
]->src
->format
> 0 &&
17260 vm
->def
->disks
[i
]->src
->format
!= VIR_STORAGE_FILE_QCOW2
) {
17261 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
17262 _("checkpoint for disk %s unsupported "
17263 "for storage type %s"),
17265 virStorageFileFormatTypeToString(
17266 vm
->def
->disks
[i
]->src
->format
));
17279 qemuDomainCheckpointAddActions(virDomainObjPtr vm
,
17280 virJSONValuePtr actions
,
17281 virDomainCheckpointObjPtr old_current
,
17282 virDomainCheckpointDefPtr def
)
17287 for (i
= 0; i
< def
->ndisks
; i
++) {
17288 virDomainCheckpointDiskDef
*disk
= &def
->disks
[i
];
17291 if (disk
->type
!= VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP
)
17293 node
= qemuBlockNodeLookup(vm
, disk
->name
);
17294 if (qemuMonitorJSONTransactionAdd(actions
,
17295 "block-dirty-bitmap-add",
17297 "s:name", disk
->bitmap
,
17298 "b:persistent", true,
17302 for (j
= 0; j
< old_current
->def
->ndisks
; j
++) {
17303 virDomainCheckpointDiskDef
*disk2
;
17305 disk2
= &old_current
->def
->disks
[j
];
17306 if (STRNEQ(disk
->name
, disk2
->name
))
17308 if (disk2
->type
== VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP
&&
17309 qemuMonitorJSONTransactionAdd(actions
,
17310 "block-dirty-bitmap-disable",
17312 "s:name", disk2
->bitmap
,
17325 /* Struct and hash-iterator callback used when bulk redefining checkpoints */
17326 struct qemuDomainCheckpointBulk
{
17327 virDomainObjPtr vm
;
17328 virQEMUDriverPtr driver
;
17329 const char *checkpointDir
;
17330 unsigned int flags
;
17334 qemuDomainCheckpointBulkRedefine(void *payload
,
17335 const void *name ATTRIBUTE_UNUSED
,
17338 virDomainCheckpointObjPtr chk
= payload
;
17339 struct qemuDomainCheckpointBulk
*data
= opaque
;
17341 return qemuDomainCheckpointWriteMetadata(data
->vm
, chk
, data
->driver
->caps
,
17342 data
->driver
->xmlopt
,
17343 data
->checkpointDir
);
17347 static virDomainCheckpointPtr
17348 qemuDomainCheckpointCreateXML(virDomainPtr domain
,
17349 const char *xmlDesc
,
17350 unsigned int flags
)
17352 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
17353 virDomainObjPtr vm
= NULL
;
17355 virDomainCheckpointObjPtr chk
= NULL
;
17356 virDomainCheckpointPtr checkpoint
= NULL
;
17357 virDomainCheckpointDefPtr def
= NULL
;
17358 bool update_current
= true;
17359 bool redefine
= flags
& VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE
;
17360 unsigned int parse_flags
= VIR_DOMAIN_CHECKPOINT_PARSE_DISKS
;
17361 virDomainCheckpointObjPtr other
= NULL
;
17362 virQEMUDriverConfigPtr cfg
= NULL
;
17363 virCapsPtr caps
= NULL
;
17364 qemuDomainObjPrivatePtr priv
;
17365 virJSONValuePtr actions
= NULL
;
17368 virCheckFlags(VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE
|
17369 VIR_DOMAIN_CHECKPOINT_CREATE_CURRENT
|
17370 VIR_DOMAIN_CHECKPOINT_CREATE_NO_METADATA
|
17371 VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE_LIST
, NULL
);
17372 /* TODO: VIR_DOMAIN_CHECKPOINT_CREATE_QUIESCE */
17375 parse_flags
|= VIR_DOMAIN_CHECKPOINT_PARSE_REDEFINE
;
17376 if ((redefine
&& !(flags
& VIR_DOMAIN_CHECKPOINT_CREATE_CURRENT
)) ||
17377 (flags
& VIR_DOMAIN_CHECKPOINT_CREATE_NO_METADATA
))
17378 update_current
= false;
17380 if (!(vm
= qemuDomObjFromDomain(domain
)))
17383 priv
= vm
->privateData
;
17384 cfg
= virQEMUDriverGetConfig(driver
);
17386 if (virDomainCheckpointCreateXMLEnsureACL(domain
->conn
, vm
->def
) < 0)
17389 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BITMAP_MERGE
)) {
17390 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
17391 _("qemu binary lacks persistent bitmaps support"));
17395 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
17398 if (qemuProcessAutoDestroyActive(driver
, vm
)) {
17399 virReportError(VIR_ERR_OPERATION_INVALID
,
17400 "%s", _("domain is marked for auto destroy"));
17404 if (!virDomainObjIsActive(vm
)) {
17405 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
17406 _("cannot create checkpoint for inactive domain"));
17410 if (flags
& VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE_LIST
) {
17411 struct qemuDomainCheckpointBulk bulk
= {
17414 .checkpointDir
= cfg
->checkpointDir
,
17418 if (virDomainCheckpointObjListParse(xmlDesc
, vm
->def
->uuid
,
17420 &vm
->current_checkpoint
,
17421 caps
, driver
->xmlopt
,
17424 /* Validate and save the checkpoints to disk. Since we don't get
17425 * here unless there were no checkpoints beforehand, just delete
17426 * everything if anything failed, ignoring further errors. */
17427 if (virDomainCheckpointForEach(vm
->checkpoints
,
17428 qemuDomainCheckpointBulkRedefine
,
17430 virErrorPtr orig_err
= virSaveLastError();
17432 qemuDomainCheckpointDiscardAllMetadata(driver
, vm
);
17433 virSetError(orig_err
);
17434 virFreeError(orig_err
);
17437 /* Return is arbitrary, so use the first root */
17438 chk
= virDomainCheckpointFindByName(vm
->checkpoints
, NULL
);
17439 checkpoint
= virGetDomainCheckpoint(domain
,
17440 chk
->first_child
->def
->name
);
17444 if (!(def
= qemuDomainCheckpointDefParseString(driver
, caps
, xmlDesc
,
17448 /* We are going to modify the domain below. */
17449 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
17453 if (virDomainCheckpointRedefinePrep(domain
, vm
, &def
, &chk
,
17455 &update_current
) < 0)
17457 } else if (qemuDomainCheckpointPrepare(driver
, caps
, vm
, def
) < 0) {
17462 if (!(chk
= virDomainCheckpointAssignDef(vm
->checkpoints
, def
)))
17468 if (update_current
)
17469 chk
->def
->current
= true;
17470 if (vm
->current_checkpoint
) {
17471 other
= vm
->current_checkpoint
;
17473 VIR_STRDUP(chk
->def
->parent
, vm
->current_checkpoint
->def
->name
) < 0)
17475 if (update_current
) {
17476 vm
->current_checkpoint
->def
->current
= false;
17477 if (qemuDomainCheckpointWriteMetadata(vm
, vm
->current_checkpoint
,
17478 driver
->caps
, driver
->xmlopt
,
17479 cfg
->checkpointDir
) < 0)
17481 vm
->current_checkpoint
= NULL
;
17485 /* actually do the checkpoint */
17487 /* XXX Should we validate that the redefined checkpoint even
17488 * makes sense, such as checking that qemu-img recognizes the
17489 * checkpoint bitmap name in at least one of the domain's disks? */
17491 if (!(actions
= virJSONValueNewArray()))
17493 if (qemuDomainCheckpointAddActions(vm
, actions
, other
, chk
->def
) < 0)
17495 qemuDomainObjEnterMonitor(driver
, vm
);
17496 ret
= qemuMonitorTransaction(priv
->mon
, &actions
);
17497 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || ret
< 0)
17501 /* If we fail after this point, there's not a whole lot we can do;
17502 * we've successfully created the checkpoint, so we have to go
17503 * forward the best we can.
17505 checkpoint
= virGetDomainCheckpoint(domain
, chk
->def
->name
);
17508 if (checkpoint
&& !(flags
& VIR_DOMAIN_CHECKPOINT_CREATE_NO_METADATA
)) {
17509 if (qemuDomainCheckpointWriteMetadata(vm
, chk
, driver
->caps
,
17511 cfg
->checkpointDir
) < 0) {
17512 /* if writing of metadata fails, error out rather than trying
17513 * to silently carry on without completing the checkpoint */
17514 virObjectUnref(checkpoint
);
17516 virReportError(VIR_ERR_INTERNAL_ERROR
,
17517 _("unable to save metadata for checkpoint %s"),
17519 virDomainCheckpointObjListRemove(vm
->checkpoints
, chk
);
17521 if (update_current
)
17522 vm
->current_checkpoint
= chk
;
17523 other
= virDomainCheckpointFindByName(vm
->checkpoints
,
17525 chk
->parent
= other
;
17526 other
->nchildren
++;
17527 chk
->sibling
= other
->first_child
;
17528 other
->first_child
= chk
;
17531 virDomainCheckpointObjListRemove(vm
->checkpoints
, chk
);
17534 qemuDomainObjEndJob(driver
, vm
);
17537 virJSONValueFree(actions
);
17538 virDomainObjEndAPI(&vm
);
17539 virDomainCheckpointDefFree(def
);
17541 virObjectUnref(caps
);
17542 virObjectUnref(cfg
);
17548 qemuDomainListCheckpoints(virDomainPtr domain
,
17549 virDomainCheckpointPtr
**chks
,
17550 unsigned int flags
)
17552 virDomainObjPtr vm
= NULL
;
17555 virCheckFlags(VIR_DOMAIN_CHECKPOINT_LIST_ROOTS
|
17556 VIR_DOMAIN_CHECKPOINT_FILTERS_ALL
, -1);
17558 if (!(vm
= qemuDomObjFromDomain(domain
)))
17561 if (virDomainListCheckpointsEnsureACL(domain
->conn
, vm
->def
) < 0)
17564 n
= virDomainListAllCheckpoints(vm
->checkpoints
, NULL
, domain
, chks
, flags
);
17567 virDomainObjEndAPI(&vm
);
17573 qemuDomainCheckpointListChildren(virDomainCheckpointPtr checkpoint
,
17574 virDomainCheckpointPtr
**chks
,
17575 unsigned int flags
)
17577 virDomainObjPtr vm
= NULL
;
17578 virDomainCheckpointObjPtr chk
= NULL
;
17581 virCheckFlags(VIR_DOMAIN_CHECKPOINT_LIST_DESCENDANTS
|
17582 VIR_DOMAIN_CHECKPOINT_FILTERS_ALL
, -1);
17584 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17587 if (virDomainCheckpointListChildrenEnsureACL(checkpoint
->domain
->conn
, vm
->def
) < 0)
17590 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17593 n
= virDomainListAllCheckpoints(vm
->checkpoints
, chk
, checkpoint
->domain
, chks
, flags
);
17596 virDomainObjEndAPI(&vm
);
17601 static virDomainCheckpointPtr
17602 qemuDomainCheckpointLookupByName(virDomainPtr domain
,
17604 unsigned int flags
)
17606 virDomainObjPtr vm
;
17607 virDomainCheckpointObjPtr chk
= NULL
;
17608 virDomainCheckpointPtr checkpoint
= NULL
;
17610 virCheckFlags(0, NULL
);
17612 if (!(vm
= qemuDomObjFromDomain(domain
)))
17615 if (virDomainCheckpointLookupByNameEnsureACL(domain
->conn
, vm
->def
) < 0)
17618 if (!(chk
= qemuCheckObjFromName(vm
, name
)))
17621 checkpoint
= virGetDomainCheckpoint(domain
, chk
->def
->name
);
17624 virDomainObjEndAPI(&vm
);
17630 qemuDomainHasCurrentCheckpoint(virDomainPtr domain
,
17631 unsigned int flags
)
17633 virDomainObjPtr vm
;
17636 virCheckFlags(0, -1);
17638 if (!(vm
= qemuDomObjFromDomain(domain
)))
17641 if (virDomainHasCurrentCheckpointEnsureACL(domain
->conn
, vm
->def
) < 0)
17644 ret
= (vm
->current_checkpoint
!= NULL
);
17647 virDomainObjEndAPI(&vm
);
17652 static virDomainCheckpointPtr
17653 qemuDomainCheckpointGetParent(virDomainCheckpointPtr checkpoint
,
17654 unsigned int flags
)
17656 virDomainObjPtr vm
;
17657 virDomainCheckpointObjPtr chk
= NULL
;
17658 virDomainCheckpointPtr parent
= NULL
;
17660 virCheckFlags(0, NULL
);
17662 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17665 if (virDomainCheckpointGetParentEnsureACL(checkpoint
->domain
->conn
, vm
->def
) < 0)
17668 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17671 if (!chk
->def
->parent
) {
17672 virReportError(VIR_ERR_NO_DOMAIN_CHECKPOINT
,
17673 _("checkpoint '%s' does not have a parent"),
17678 parent
= virGetDomainCheckpoint(checkpoint
->domain
, chk
->def
->parent
);
17681 virDomainObjEndAPI(&vm
);
17686 static virDomainCheckpointPtr
17687 qemuDomainCheckpointCurrent(virDomainPtr domain
,
17688 unsigned int flags
)
17690 virDomainObjPtr vm
;
17691 virDomainCheckpointPtr checkpoint
= NULL
;
17693 virCheckFlags(0, NULL
);
17695 if (!(vm
= qemuDomObjFromDomain(domain
)))
17698 if (virDomainCheckpointCurrentEnsureACL(domain
->conn
, vm
->def
) < 0)
17701 if (!vm
->current_checkpoint
) {
17702 virReportError(VIR_ERR_NO_DOMAIN_CHECKPOINT
, "%s",
17703 _("the domain does not have a current checkpoint"));
17707 checkpoint
= virGetDomainCheckpoint(domain
, vm
->current_checkpoint
->def
->name
);
17710 virDomainObjEndAPI(&vm
);
17716 qemuDomainCheckpointGetXMLDesc(virDomainCheckpointPtr checkpoint
,
17717 unsigned int flags
)
17719 virQEMUDriverPtr driver
= checkpoint
->domain
->conn
->privateData
;
17720 virDomainObjPtr vm
= NULL
;
17722 virDomainCheckpointObjPtr chk
= NULL
;
17723 qemuDomainObjPrivatePtr priv
;
17727 virCheckFlags(VIR_DOMAIN_CHECKPOINT_XML_SECURE
|
17728 VIR_DOMAIN_CHECKPOINT_XML_NO_DOMAIN
|
17729 VIR_DOMAIN_CHECKPOINT_XML_SIZE
, NULL
);
17731 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17734 if (virDomainCheckpointGetXMLDescEnsureACL(checkpoint
->domain
->conn
, vm
->def
, flags
) < 0)
17737 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17740 if (flags
& VIR_DOMAIN_CHECKPOINT_XML_SIZE
) {
17741 /* TODO: for non-current checkpoint, this requires a QMP sequence per
17742 disk, since the stat of one bitmap in isolation is too low,
17743 and merely adding bitmap sizes may be too high:
17744 block-dirty-bitmap-create tmp
17745 for each bitmap from checkpoint to current:
17746 add bitmap to src_list
17747 block-dirty-bitmap-merge dst=tmp src_list
17748 query-block and read tmp size
17749 block-dirty-bitmap-remove tmp
17750 So for now, go with simpler query-blocks only for current.
17752 if (!vm
->current_checkpoint
||
17753 STRNEQ(checkpoint
->name
, vm
->current_checkpoint
->def
->name
)) {
17754 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
17755 _("cannot compute size for non-current checkpoint '%s'"),
17760 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
17763 if (virDomainObjCheckActive(vm
) < 0)
17766 if (qemuBlockNodeNamesDetect(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
17769 /* TODO: Shouldn't need to recompute node names. */
17770 for (i
= 0; i
< chk
->def
->ndisks
; i
++) {
17771 virDomainCheckpointDiskDef
*disk
= &chk
->def
->disks
[i
];
17773 if (disk
->type
!= VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP
)
17775 VIR_FREE(chk
->def
->dom
->disks
[disk
->idx
]->src
->nodeformat
);
17776 if (VIR_STRDUP(chk
->def
->dom
->disks
[disk
->idx
]->src
->nodeformat
,
17777 qemuBlockNodeLookup(vm
, disk
->name
)) < 0)
17781 priv
= vm
->privateData
;
17782 qemuDomainObjEnterMonitor(driver
, vm
);
17783 rc
= qemuMonitorUpdateCheckpointSize(priv
->mon
, chk
->def
);
17784 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
17790 xml
= virDomainCheckpointDefFormat(chk
->def
, driver
->caps
, driver
->xmlopt
,
17794 if (flags
& VIR_DOMAIN_CHECKPOINT_XML_SIZE
)
17795 qemuDomainObjEndJob(driver
, vm
);
17798 virDomainObjEndAPI(&vm
);
17804 qemuDomainCheckpointIsCurrent(virDomainCheckpointPtr checkpoint
,
17805 unsigned int flags
)
17807 virDomainObjPtr vm
= NULL
;
17809 virDomainCheckpointObjPtr chk
= NULL
;
17811 virCheckFlags(0, -1);
17813 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17816 if (virDomainCheckpointIsCurrentEnsureACL(checkpoint
->domain
->conn
, vm
->def
) < 0)
17819 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17822 ret
= (vm
->current_checkpoint
&&
17823 STREQ(checkpoint
->name
, vm
->current_checkpoint
->def
->name
));
17826 virDomainObjEndAPI(&vm
);
17832 qemuDomainCheckpointHasMetadata(virDomainCheckpointPtr checkpoint
,
17833 unsigned int flags
)
17835 virDomainObjPtr vm
= NULL
;
17837 virDomainCheckpointObjPtr chk
= NULL
;
17839 virCheckFlags(0, -1);
17841 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17844 if (virDomainCheckpointHasMetadataEnsureACL(checkpoint
->domain
->conn
, vm
->def
) < 0)
17847 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17850 /* XXX Someday, we should recognize internal bitmaps in qcow2
17851 * images that are not tied to a libvirt checkpoint; if we ever do
17852 * that, then we would have a reason to return 0 here. */
17856 virDomainObjEndAPI(&vm
);
17861 typedef struct _virQEMUCheckReparent virQEMUCheckReparent
;
17862 typedef virQEMUCheckReparent
*virQEMUCheckReparentPtr
;
17863 struct _virQEMUCheckReparent
{
17864 virQEMUDriverConfigPtr cfg
;
17865 virDomainCheckpointObjPtr parent
;
17866 virDomainObjPtr vm
;
17868 virDomainXMLOptionPtr xmlopt
;
17870 virDomainCheckpointObjPtr last
;
17875 qemuDomainCheckpointReparentChildren(void *payload
,
17876 const void *name ATTRIBUTE_UNUSED
,
17879 virDomainCheckpointObjPtr chk
= payload
;
17880 virQEMUCheckReparentPtr rep
= data
;
17885 VIR_FREE(chk
->def
->parent
);
17886 chk
->parent
= rep
->parent
;
17888 if (rep
->parent
->def
&&
17889 VIR_STRDUP(chk
->def
->parent
, rep
->parent
->def
->name
) < 0) {
17897 rep
->err
= qemuDomainCheckpointWriteMetadata(rep
->vm
, chk
,
17898 rep
->caps
, rep
->xmlopt
,
17899 rep
->cfg
->checkpointDir
);
17905 qemuDomainCheckpointDelete(virDomainCheckpointPtr checkpoint
,
17906 unsigned int flags
)
17908 virQEMUDriverPtr driver
= checkpoint
->domain
->conn
->privateData
;
17909 virDomainObjPtr vm
= NULL
;
17910 qemuDomainObjPrivatePtr priv
;
17912 virDomainCheckpointObjPtr chk
= NULL
;
17913 virQEMUDependentRemove rem
;
17914 virQEMUCheckReparent rep
;
17915 bool metadata_only
= !!(flags
& VIR_DOMAIN_CHECKPOINT_DELETE_METADATA_ONLY
);
17916 virQEMUDriverConfigPtr cfg
= NULL
;
17918 virCheckFlags(VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN
|
17919 VIR_DOMAIN_CHECKPOINT_DELETE_METADATA_ONLY
|
17920 VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN_ONLY
, -1);
17922 if (!(vm
= qemuDomObjFromCheckpoint(checkpoint
)))
17925 cfg
= virQEMUDriverGetConfig(driver
);
17927 if (virDomainCheckpointDeleteEnsureACL(checkpoint
->domain
->conn
, vm
->def
) < 0)
17930 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
17933 priv
= vm
->privateData
;
17934 if (!metadata_only
) {
17935 /* Until qemu-img supports offline bitmap deletion, we are stuck
17936 * with requiring a running guest */
17937 if (!virDomainObjIsActive(vm
)) {
17938 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
17939 _("cannot delete checkpoint for inactive domain"));
17942 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BITMAP_MERGE
)) {
17943 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
17944 _("qemu binary lacks persistent bitmaps support"));
17949 if (!(chk
= qemuCheckObjFromCheckpoint(vm
, checkpoint
)))
17952 if (flags
& (VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN
|
17953 VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN_ONLY
)) {
17954 rem
.driver
= driver
;
17956 rem
.metadata_only
= metadata_only
;
17958 rem
.current
= false;
17959 virDomainCheckpointForEachDescendant(chk
,
17960 qemuDomainCheckpointDiscardAll
,
17965 if (flags
& VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN_ONLY
) {
17966 chk
->def
->current
= true;
17967 if (qemuDomainCheckpointWriteMetadata(vm
, chk
, driver
->caps
,
17969 cfg
->checkpointDir
) < 0) {
17970 virReportError(VIR_ERR_INTERNAL_ERROR
,
17971 _("failed to set checkpoint '%s' as current"),
17973 chk
->def
->current
= false;
17977 vm
->current_checkpoint
= chk
;
17979 } else if (chk
->nchildren
) {
17981 rep
.parent
= chk
->parent
;
17985 rep
.caps
= driver
->caps
;
17986 rep
.xmlopt
= driver
->xmlopt
;
17987 virDomainCheckpointForEachChild(chk
,
17988 qemuDomainCheckpointReparentChildren
,
17992 /* Can't modify siblings during ForEachChild, so do it now. */
17993 chk
->parent
->nchildren
+= chk
->nchildren
;
17994 rep
.last
->sibling
= chk
->parent
->first_child
;
17995 chk
->parent
->first_child
= chk
->first_child
;
17998 if (flags
& VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN_ONLY
) {
17999 chk
->nchildren
= 0;
18000 chk
->first_child
= NULL
;
18003 ret
= qemuDomainCheckpointDiscard(driver
, vm
, chk
, true, metadata_only
);
18007 qemuDomainObjEndJob(driver
, vm
);
18010 virDomainObjEndAPI(&vm
);
18011 virObjectUnref(cfg
);
18016 qemuDomainBackupPrepare(virQEMUDriverPtr driver
, virDomainObjPtr vm
,
18017 virDomainBackupDefPtr def
,
18018 virDomainCheckpointObjPtr chk
)
18023 if (chk
&& def
->ndisks
!= chk
->def
->ndisks
) {
18024 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
18025 _("inconsistency between backup and checkpoint disks"));
18028 if (qemuBlockNodeNamesDetect(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
18030 for (i
= 0; i
< def
->ndisks
; i
++) {
18031 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18032 virStorageSourcePtr src
= vm
->def
->disks
[disk
->idx
]->src
;
18034 /* For now, insist that atomic checkpoint affect same disks as
18035 * those being backed up. */
18036 if (!disk
->store
) {
18038 chk
->def
->disks
[i
].type
!= VIR_DOMAIN_CHECKPOINT_TYPE_NONE
) {
18039 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
18040 _("disk %s requested checkpoint without backup"),
18047 chk
->def
->disks
[i
].type
!= VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP
) {
18048 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
18049 _("disk %s requested backup without checkpoint"),
18053 if (virAsprintf(&disk
->store
->nodeformat
, "tmp-%s", disk
->name
) < 0)
18055 if (!disk
->store
->format
)
18056 disk
->store
->format
= VIR_STORAGE_FILE_QCOW2
;
18057 if (def
->incremental
) {
18058 if (src
->format
!= VIR_STORAGE_FILE_QCOW2
) {
18059 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
18060 _("incremental backup of %s requires qcow2"),
18071 /* Called while monitor lock is held. Best-effort cleanup. */
18073 qemuDomainBackupDiskCleanup(virQEMUDriverPtr driver
, virDomainObjPtr vm
,
18074 virDomainBackupDiskDef
*disk
, bool push
,
18075 bool incremental
, bool completed
)
18077 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
18078 const char *node
= vm
->def
->disks
[disk
->idx
]->src
->nodeformat
;
18081 if (disk
->state
>= VIR_DOMAIN_BACKUP_DISK_STATE_EXPORT
) {
18082 /* No real need to use nbd-server-remove, since we will
18083 * shortly be calling nbd-server-stop. */
18085 if (incremental
&& disk
->state
>= VIR_DOMAIN_BACKUP_DISK_STATE_BITMAP
&&
18086 qemuMonitorDeleteBitmap(priv
->mon
, node
, disk
->name
) < 0) {
18087 VIR_WARN("Unable to remove temp bitmap for disk %s after backup",
18091 if (disk
->state
>= VIR_DOMAIN_BACKUP_DISK_STATE_READY
&&
18092 qemuMonitorBlockdevDel(priv
->mon
, disk
->store
->nodeformat
) < 0) {
18093 VIR_WARN("Unable to remove %s disk %s after backup",
18094 push
? "target" : "scratch", disk
->name
);
18097 if (disk
->state
>= VIR_DOMAIN_BACKUP_DISK_STATE_LABEL
)
18098 qemuDomainDiskChainElementRevoke(driver
, vm
, disk
->store
);
18099 if ((!push
|| !completed
) &&
18100 disk
->state
>= VIR_DOMAIN_BACKUP_DISK_STATE_CREATED
&&
18101 disk
->store
->detected
&& unlink(disk
->store
->path
) < 0) {
18102 VIR_WARN("Unable to unlink %s disk %s after backup",
18103 push
? "failed target" : "scratch", disk
->store
->path
);
18110 qemuDomainBackupBegin(virDomainPtr domain
, const char *diskXml
,
18111 const char *checkpointXml
, unsigned int flags
)
18113 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
18114 virDomainObjPtr vm
= NULL
;
18115 virDomainBackupDefPtr def
= NULL
;
18116 virQEMUDriverConfigPtr cfg
= NULL
;
18117 virCapsPtr caps
= NULL
;
18118 qemuDomainObjPrivatePtr priv
;
18120 virJSONValuePtr json
= NULL
;
18121 bool job_started
= false;
18122 bool nbd_running
= false;
18127 char *suffix
= NULL
;
18128 virCommandPtr cmd
= NULL
;
18129 const char *qemuImgPath
;
18130 virDomainCheckpointDefPtr chkdef
= NULL
;
18131 virDomainCheckpointObjPtr chk
= NULL
;
18132 virDomainCheckpointObjPtr other
= NULL
;
18133 virDomainCheckpointObjPtr parent
= NULL
;
18134 virJSONValuePtr arr
= NULL
;
18136 virCheckFlags(VIR_DOMAIN_BACKUP_BEGIN_NO_METADATA
, -1);
18137 /* TODO: VIR_DOMAIN_BACKUP_BEGIN_QUIESCE */
18139 if (!(vm
= qemuDomObjFromDomain(domain
)))
18142 priv
= vm
->privateData
;
18143 cfg
= virQEMUDriverGetConfig(driver
);
18145 if (virDomainBackupBeginEnsureACL(domain
->conn
, vm
->def
) < 0)
18148 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
18151 if (qemuProcessAutoDestroyActive(driver
, vm
)) {
18152 virReportError(VIR_ERR_OPERATION_INVALID
,
18153 "%s", _("domain is marked for auto destroy"));
18157 if (!virDomainObjIsActive(vm
)) {
18158 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
18159 _("cannot perform disk backup for inactive domain"));
18162 if (!(def
= virDomainBackupDefParseString(diskXml
, driver
->xmlopt
, 0)))
18165 if (checkpointXml
) {
18166 if (!(chkdef
= qemuDomainCheckpointDefParseString(driver
, caps
,
18167 checkpointXml
, 0)) ||
18168 VIR_STRDUP(suffix
, chkdef
->name
) < 0)
18171 gettimeofday(&tv
, NULL
);
18172 if (virAsprintf(&suffix
, "%lld", (long long)tv
.tv_sec
) < 0)
18176 push
= def
->type
== VIR_DOMAIN_BACKUP_TYPE_PUSH
;
18178 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_NBD_BITMAP
)) {
18179 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
18180 _("qemu binary lacks pull-mode backup support"));
18183 if (!def
->server
||
18184 def
->server
->transport
!= VIR_STORAGE_NET_HOST_TRANS_TCP
) {
18185 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
18186 _("<domainbackup> must specify TCP server for now"));
18190 if (def
->incremental
) {
18191 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BITMAP_MERGE
)) {
18192 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
18193 _("qemu binary lacks persistent bitmaps support"));
18196 for (other
= vm
->current_checkpoint
; other
;
18197 other
= other
->def
->parent
?
18198 virDomainCheckpointFindByName(vm
->checkpoints
,
18199 other
->def
->parent
) : NULL
)
18200 if (STREQ(other
->def
->name
, def
->incremental
))
18203 virReportError(VIR_ERR_OPERATION_INVALID
,
18204 _("could not locate checkpoint '%s' for incremental backup"),
18210 if (!(qemuImgPath
= qemuFindQemuImgBinary(driver
)))
18213 /* We are going to modify the domain below. */
18214 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
18217 if (priv
->backup
) {
18218 virReportError(VIR_ERR_OPERATION_INVALID
,
18219 "%s", _("another backup job is already running"));
18224 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BITMAP_MERGE
)) {
18225 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
18226 _("qemu binary lacks persistent bitmaps support"));
18230 if (qemuDomainCheckpointPrepare(driver
, caps
, vm
, chkdef
) < 0)
18232 if (!(chk
= virDomainCheckpointAssignDef(vm
->checkpoints
, chkdef
)))
18235 chk
->def
->current
= true;
18236 if (vm
->current_checkpoint
) {
18237 parent
= vm
->current_checkpoint
;
18238 if (VIR_STRDUP(chk
->def
->parent
, parent
->def
->name
) < 0)
18240 if (qemuDomainCheckpointWriteMetadata(vm
, parent
, driver
->caps
,
18242 cfg
->checkpointDir
) < 0)
18244 vm
->current_checkpoint
= NULL
;
18248 if (virDomainBackupAlignDisks(def
, vm
->def
, suffix
) < 0 ||
18249 qemuDomainBackupPrepare(driver
, vm
, def
, chk
) < 0)
18252 /* actually start the checkpoint. 2x2 array of push/pull, full/incr,
18253 plus additional tweak if checkpoint requested */
18254 qemuDomainObjEnterMonitor(driver
, vm
);
18255 /* - push/pull: blockdev-add per <disk>
18256 - incr: bitmap-add of tmp, bitmap-merge per <disk> */
18257 for (i
= 0; i
< def
->ndisks
; i
++) {
18258 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18259 virJSONValuePtr file
;
18260 virStorageSourcePtr src
= vm
->def
->disks
[disk
->idx
]->src
;
18261 const char *node
= src
->nodeformat
;
18265 if (qemuDomainStorageFileInit(driver
, vm
, disk
->store
, src
) < 0)
18267 if (disk
->store
->detected
) {
18268 if (virStorageFileCreate(disk
->store
) < 0) {
18269 virReportSystemError(errno
,
18270 _("failed to create image file '%s'"),
18271 NULLSTR(disk
->store
->path
));
18274 disk
->state
= VIR_DOMAIN_BACKUP_DISK_STATE_CREATED
;
18276 if (qemuDomainDiskChainElementPrepare(driver
, vm
, disk
->store
, false,
18279 disk
->state
= VIR_DOMAIN_BACKUP_DISK_STATE_LABEL
;
18280 if (disk
->store
->detected
) {
18281 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
18283 /* Force initialization of scratch/target file to new qcow2 */
18284 if (!(cmd
= virCommandNewArgList(qemuImgPath
,
18287 virStorageFileFormatTypeToString(disk
->store
->format
),
18291 virBufferAsprintf(&buf
, "backing_fmt=%s,backing_file=",
18292 virStorageFileFormatTypeToString(src
->format
));
18293 virQEMUBuildBufferEscapeComma(&buf
, src
->path
);
18294 virCommandAddArgBuffer(cmd
, &buf
);
18296 virQEMUBuildBufferEscapeComma(&buf
, disk
->store
->path
);
18297 virCommandAddArgBuffer(cmd
, &buf
);
18298 if (virCommandRun(cmd
, NULL
) < 0)
18300 virCommandFree(cmd
);
18304 /* FIXME: allow non-local files for push destinations */
18305 if (virJSONValueObjectCreate(&file
,
18306 "s:driver", "file",
18307 "s:filename", disk
->store
->path
,
18310 if (virJSONValueObjectCreate(&json
,
18311 "s:driver", virStorageFileFormatTypeToString(disk
->store
->format
),
18312 "s:node-name", disk
->store
->nodeformat
,
18314 "s:backing", node
, NULL
) < 0) {
18315 virJSONValueFree(file
);
18318 if (qemuMonitorBlockdevAdd(priv
->mon
, json
) < 0)
18321 disk
->state
= VIR_DOMAIN_BACKUP_DISK_STATE_READY
;
18323 if (def
->incremental
) {
18324 if (!(arr
= virJSONValueNewArray()))
18326 if (qemuMonitorAddBitmap(priv
->mon
, node
, disk
->name
, false) < 0) {
18327 virJSONValueFree(arr
);
18330 disk
->state
= VIR_DOMAIN_BACKUP_DISK_STATE_BITMAP
;
18331 for (other
= parent
? parent
: vm
->current_checkpoint
; other
;
18332 other
= other
->def
->parent
?
18333 virDomainCheckpointFindByName(vm
->checkpoints
,
18334 other
->def
->parent
) : NULL
) {
18335 if (virJSONValueArrayAppendString(arr
, other
->def
->name
) < 0) {
18336 virJSONValueFree(arr
);
18339 if (STREQ(other
->def
->name
, def
->incremental
))
18342 if (qemuMonitorMergeBitmaps(priv
->mon
, node
, disk
->name
, &arr
) < 0)
18347 /* - transaction, containing:
18348 - push+full: blockdev-backup sync:full
18349 - push+incr: blockdev-backup sync:incremental bitmap:tmp
18350 - pull+full: blockdev-backup sync:none
18351 - pull+incr: blockdev-backup sync:none, bitmap-disable of tmp
18352 - if checkpoint: bitmap-disable of old, bitmap-add of new
18354 if (!(json
= virJSONValueNewArray()))
18357 mode
= def
->incremental
? "incremental" : "full";
18360 for (i
= 0; i
< def
->ndisks
; i
++) {
18361 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18363 const char *push_bitmap
= NULL
;
18367 node
= qemuBlockNodeLookup(vm
, disk
->name
);
18368 if (push
&& def
->incremental
)
18369 push_bitmap
= disk
->name
;
18370 if (qemuMonitorJSONTransactionAdd(json
,
18373 "s:target", disk
->store
->nodeformat
,
18375 "S:bitmap", push_bitmap
,
18376 "s:job-id", disk
->name
,
18379 if (def
->incremental
&& !push
&&
18380 qemuMonitorJSONTransactionAdd(json
,
18381 "block-dirty-bitmap-disable",
18383 "s:name", disk
->name
,
18387 if (chk
&& qemuDomainCheckpointAddActions(vm
, json
, parent
, chk
->def
) < 0)
18389 if (qemuMonitorTransaction(priv
->mon
, &json
) < 0)
18391 job_started
= true;
18393 if (qemuDomainCheckpointWriteMetadata(vm
, chk
, driver
->caps
,
18395 cfg
->checkpointDir
) < 0) {
18396 virReportError(VIR_ERR_INTERNAL_ERROR
,
18397 _("unable to save metadata for checkpoint %s"),
18399 virDomainCheckpointObjListRemove(vm
->checkpoints
, chk
);
18402 vm
->current_checkpoint
= chk
;
18403 other
= virDomainCheckpointFindByName(vm
->checkpoints
,
18405 chk
->parent
= other
;
18406 other
->nchildren
++;
18407 chk
->sibling
= other
->first_child
;
18408 other
->first_child
= chk
;
18412 - pull: nbd-server-start with <server> from user (or autogenerate server)
18413 - pull: nbd-server-add per <disk>, including bitmap for incr
18416 if (qemuMonitorNBDServerStart(priv
->mon
, def
->server
->name
,
18417 def
->server
->port
, NULL
) < 0)
18419 nbd_running
= true;
18420 for (i
= 0; i
< def
->ndisks
; i
++) {
18421 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18425 if (qemuMonitorNBDServerAdd(priv
->mon
, disk
->store
->nodeformat
,
18427 def
->incremental
? disk
->name
:
18430 disk
->state
= VIR_DOMAIN_BACKUP_DISK_STATE_EXPORT
;
18436 /* Best effort cleanup if we fail partway through */
18438 virErrorPtr save_err
= virSaveLastError();
18441 qemuMonitorNBDServerStop(priv
->mon
) < 0)
18442 VIR_WARN("Unable to stop NBD server on vm %s after backup job",
18444 for (i
= 0; i
< def
->ndisks
; i
++) {
18445 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18450 qemuMonitorBlockJobCancel(priv
->mon
, disk
->name
) < 0)
18451 VIR_WARN("Unable to stop backup job %s on vm %s after failure",
18452 disk
->name
, vm
->def
->name
);
18453 qemuDomainBackupDiskCleanup(driver
, vm
, disk
, push
,
18454 !!def
->incremental
, false);
18456 virSetError(save_err
);
18457 virFreeError(save_err
);
18459 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
18464 VIR_STEAL_PTR(priv
->backup
, def
);
18465 ret
= priv
->backup
->id
= 1; /* Hard-coded job id for now */
18466 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
,
18468 VIR_WARN("Unable to save status on vm %s after backup job",
18472 qemuDomainObjEndJob(driver
, vm
);
18475 virJSONValueFree(arr
);
18476 virDomainCheckpointDefFree(chkdef
);
18477 virCommandFree(cmd
);
18479 virJSONValueFree(json
);
18480 virDomainObjEndAPI(&vm
);
18481 virDomainBackupDefFree(def
);
18482 virObjectUnref(caps
);
18483 virObjectUnref(cfg
);
18487 static char *qemuDomainBackupGetXMLDesc(virDomainPtr domain
, int id
,
18488 unsigned int flags
)
18490 virDomainObjPtr vm
= NULL
;
18492 qemuDomainObjPrivatePtr priv
;
18493 virBuffer buf
= VIR_BUFFER_INITIALIZER
;
18495 virCheckFlags(0, NULL
);
18497 if (!(vm
= qemuDomObjFromDomain(domain
)))
18500 if (virDomainBackupGetXMLDescEnsureACL(domain
->conn
, vm
->def
) < 0)
18503 /* TODO: Allow more than one hard-coded job id */
18504 priv
= vm
->privateData
;
18505 if (id
!= 1 || !priv
->backup
) {
18506 virReportError(VIR_ERR_NO_DOMAIN_CHECKPOINT
,
18507 _("no domain backup job with id '%d'"), id
);
18511 if (virDomainBackupDefFormat(&buf
, priv
->backup
, false) < 0)
18513 xml
= virBufferContentAndReset(&buf
);
18516 virDomainObjEndAPI(&vm
);
18520 static int qemuDomainBackupEnd(virDomainPtr domain
, int id
, unsigned int flags
)
18522 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
18523 virQEMUDriverConfigPtr cfg
= NULL
;
18524 virDomainObjPtr vm
= NULL
;
18526 virDomainBackupDefPtr backup
= NULL
;
18527 qemuDomainObjPrivatePtr priv
;
18528 bool want_abort
= flags
& VIR_DOMAIN_BACKUP_END_ABORT
;
18529 virDomainBackupDefPtr def
;
18532 bool completed
= true;
18534 virCheckFlags(VIR_DOMAIN_BACKUP_END_ABORT
, -1);
18536 if (!(vm
= qemuDomObjFromDomain(domain
)))
18539 cfg
= virQEMUDriverGetConfig(driver
);
18540 if (virDomainBackupEndEnsureACL(domain
->conn
, vm
->def
) < 0)
18543 /* TODO: Allow more than one hard-coded job id */
18544 priv
= vm
->privateData
;
18545 if (id
!= 1 || !priv
->backup
) {
18546 virReportError(VIR_ERR_NO_DOMAIN_CHECKPOINT
,
18547 _("no domain backup job with id '%d'"), id
);
18551 def
= priv
->backup
;
18552 if (def
->type
!= VIR_DOMAIN_BACKUP_TYPE_PUSH
) {
18553 want_abort
= false;
18557 /* We are going to modify the domain below. */
18558 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
18561 qemuDomainObjEnterMonitor(driver
, vm
);
18563 for (i
= 0; i
< def
->ndisks
; i
++) {
18564 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18568 if (disk
->state
!= VIR_DOMAIN_BACKUP_DISK_STATE_COMPLETE
)
18572 ret
= qemuMonitorNBDServerStop(priv
->mon
);
18574 if (!completed
&& !want_abort
) {
18575 virReportError(VIR_ERR_OPERATION_INVALID
,
18576 _("backup job id '%d' not complete yet"), id
);
18578 for (i
= 0; i
< def
->ndisks
; i
++) {
18579 virDomainBackupDiskDef
*disk
= &def
->disks
[i
];
18583 if (!push
|| disk
->state
< VIR_DOMAIN_BACKUP_DISK_STATE_COMPLETE
) {
18584 if (qemuMonitorBlockJobCancel(priv
->mon
,
18591 if (qemuDomainBackupDiskCleanup(driver
, vm
, disk
, push
,
18592 !!def
->incremental
, completed
) < 0)
18596 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || ret
< 0) {
18601 VIR_STEAL_PTR(backup
, priv
->backup
);
18602 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
,
18604 VIR_WARN("Unable to save status on vm %s after backup job",
18607 ret
= want_abort
? 0 : 1;
18610 qemuDomainObjEndJob(driver
, vm
);
18613 virDomainBackupDefFree(backup
);
18614 virDomainObjEndAPI(&vm
);
18618 static int qemuDomainQemuMonitorCommand(virDomainPtr domain
, const char *cmd
,
18619 char **result
, unsigned int flags
)
18621 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
18622 virDomainObjPtr vm
= NULL
;
18624 qemuDomainObjPrivatePtr priv
;
18627 virCheckFlags(VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP
, -1);
18629 if (!(vm
= qemuDomObjFromDomain(domain
)))
18632 if (virDomainQemuMonitorCommandEnsureACL(domain
->conn
, vm
->def
) < 0)
18635 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
18638 if (virDomainObjCheckActive(vm
) < 0)
18641 priv
= vm
->privateData
;
18643 qemuDomainObjTaint(driver
, vm
, VIR_DOMAIN_TAINT_CUSTOM_MONITOR
, NULL
);
18645 hmp
= !!(flags
& VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP
);
18647 qemuDomainObjEnterMonitor(driver
, vm
);
18648 ret
= qemuMonitorArbitraryCommand(priv
->mon
, cmd
, result
, hmp
);
18649 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
18653 qemuDomainObjEndJob(driver
, vm
);
18656 virDomainObjEndAPI(&vm
);
18661 static virDomainPtr
qemuDomainQemuAttach(virConnectPtr conn
,
18662 unsigned int pid_value
,
18663 unsigned int flags
)
18665 virQEMUDriverPtr driver
= conn
->privateData
;
18666 virDomainObjPtr vm
= NULL
;
18667 virDomainDefPtr def
= NULL
;
18668 virDomainPtr dom
= NULL
;
18669 virDomainChrSourceDefPtr monConfig
= NULL
;
18670 bool monJSON
= false;
18671 pid_t pid
= pid_value
;
18672 char *pidfile
= NULL
;
18673 virQEMUCapsPtr qemuCaps
= NULL
;
18674 virCapsPtr caps
= NULL
;
18676 virCheckFlags(0, NULL
);
18678 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
18681 if (!(def
= qemuParseCommandLinePid(driver
->qemuCapsCache
,
18682 caps
, driver
->xmlopt
, pid
,
18683 &pidfile
, &monConfig
, &monJSON
)))
18686 if (virDomainQemuAttachEnsureACL(conn
, def
) < 0)
18690 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
18691 _("No monitor connection for pid %u"), pid_value
);
18694 if (monConfig
->type
!= VIR_DOMAIN_CHR_TYPE_UNIX
) {
18695 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
18696 _("Cannot connect to monitor connection of type '%s' "
18698 virDomainChrTypeToString(monConfig
->type
),
18703 if (!(def
->name
) &&
18704 virAsprintf(&def
->name
, "attach-pid-%u", pid_value
) < 0)
18707 if (!(qemuCaps
= virQEMUCapsCacheLookup(driver
->qemuCapsCache
,
18711 if (qemuAssignDeviceAliases(def
, qemuCaps
) < 0)
18714 if (!(vm
= virDomainObjListAdd(driver
->domains
, def
,
18716 VIR_DOMAIN_OBJ_LIST_ADD_LIVE
|
18717 VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE
,
18723 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0) {
18724 qemuDomainRemoveInactive(driver
, vm
);
18728 if (qemuProcessAttach(conn
, driver
, vm
, pid
,
18729 pidfile
, monConfig
, monJSON
) < 0) {
18731 qemuDomainRemoveInactive(driver
, vm
);
18732 qemuDomainObjEndJob(driver
, vm
);
18738 if (qemuProcessAttach(conn
, driver
, vm
, pid
,
18739 pidfile
, monConfig
, monJSON
) < 0) {
18740 qemuDomainRemoveInactive(driver
, vm
);
18741 qemuDomainObjEndJob(driver
, vm
);
18745 dom
= virGetDomain(conn
, vm
->def
->name
, vm
->def
->uuid
, vm
->def
->id
);
18747 qemuDomainObjEndJob(driver
, vm
);
18750 virDomainDefFree(def
);
18751 virObjectUnref(monConfig
);
18752 virDomainObjEndAPI(&vm
);
18754 virObjectUnref(caps
);
18755 virObjectUnref(qemuCaps
);
18761 qemuDomainOpenConsole(virDomainPtr dom
,
18762 const char *dev_name
,
18764 unsigned int flags
)
18766 virDomainObjPtr vm
= NULL
;
18769 virDomainChrDefPtr chr
= NULL
;
18770 qemuDomainObjPrivatePtr priv
;
18772 virCheckFlags(VIR_DOMAIN_CONSOLE_SAFE
|
18773 VIR_DOMAIN_CONSOLE_FORCE
, -1);
18775 if (!(vm
= qemuDomObjFromDomain(dom
)))
18778 if (virDomainOpenConsoleEnsureACL(dom
->conn
, vm
->def
) < 0)
18781 if (virDomainObjCheckActive(vm
) < 0)
18784 priv
= vm
->privateData
;
18787 for (i
= 0; !chr
&& i
< vm
->def
->nconsoles
; i
++) {
18788 if (vm
->def
->consoles
[i
]->info
.alias
&&
18789 STREQ(dev_name
, vm
->def
->consoles
[i
]->info
.alias
))
18790 chr
= vm
->def
->consoles
[i
];
18792 for (i
= 0; !chr
&& i
< vm
->def
->nserials
; i
++) {
18793 if (STREQ(dev_name
, vm
->def
->serials
[i
]->info
.alias
))
18794 chr
= vm
->def
->serials
[i
];
18796 for (i
= 0; !chr
&& i
< vm
->def
->nparallels
; i
++) {
18797 if (STREQ(dev_name
, vm
->def
->parallels
[i
]->info
.alias
))
18798 chr
= vm
->def
->parallels
[i
];
18801 if (vm
->def
->nconsoles
)
18802 chr
= vm
->def
->consoles
[0];
18803 else if (vm
->def
->nserials
)
18804 chr
= vm
->def
->serials
[0];
18808 virReportError(VIR_ERR_INTERNAL_ERROR
,
18809 _("cannot find character device %s"),
18810 NULLSTR(dev_name
));
18814 if (chr
->source
->type
!= VIR_DOMAIN_CHR_TYPE_PTY
) {
18815 virReportError(VIR_ERR_INTERNAL_ERROR
,
18816 _("character device %s is not using a PTY"),
18817 dev_name
? dev_name
: NULLSTR(chr
->info
.alias
));
18821 /* handle mutually exclusive access to console devices */
18822 ret
= virChrdevOpen(priv
->devs
,
18825 (flags
& VIR_DOMAIN_CONSOLE_FORCE
) != 0);
18828 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
18829 _("Active console session exists for this domain"));
18834 virDomainObjEndAPI(&vm
);
18839 qemuDomainOpenChannel(virDomainPtr dom
,
18842 unsigned int flags
)
18844 virDomainObjPtr vm
= NULL
;
18847 virDomainChrDefPtr chr
= NULL
;
18848 qemuDomainObjPrivatePtr priv
;
18850 virCheckFlags(VIR_DOMAIN_CHANNEL_FORCE
, -1);
18852 if (!(vm
= qemuDomObjFromDomain(dom
)))
18855 if (virDomainOpenChannelEnsureACL(dom
->conn
, vm
->def
) < 0)
18858 if (virDomainObjCheckActive(vm
) < 0)
18861 priv
= vm
->privateData
;
18864 for (i
= 0; !chr
&& i
< vm
->def
->nchannels
; i
++) {
18865 if (STREQ(name
, vm
->def
->channels
[i
]->info
.alias
))
18866 chr
= vm
->def
->channels
[i
];
18868 if (vm
->def
->channels
[i
]->targetType
== \
18869 VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO
&&
18870 STREQ_NULLABLE(name
, vm
->def
->channels
[i
]->target
.name
))
18871 chr
= vm
->def
->channels
[i
];
18874 if (vm
->def
->nchannels
)
18875 chr
= vm
->def
->channels
[0];
18879 virReportError(VIR_ERR_INTERNAL_ERROR
,
18880 _("cannot find channel %s"),
18885 if (chr
->source
->type
!= VIR_DOMAIN_CHR_TYPE_UNIX
) {
18886 virReportError(VIR_ERR_INTERNAL_ERROR
,
18887 _("channel %s is not using a UNIX socket"),
18888 name
? name
: NULLSTR(chr
->info
.alias
));
18892 /* handle mutually exclusive access to channel devices */
18893 ret
= virChrdevOpen(priv
->devs
,
18896 (flags
& VIR_DOMAIN_CHANNEL_FORCE
) != 0);
18899 virReportError(VIR_ERR_OPERATION_FAILED
, "%s",
18900 _("Active channel stream exists for this domain"));
18905 virDomainObjEndAPI(&vm
);
18910 /* Called while holding the VM job lock, to implement a block job
18911 * abort with pivot; this updates the VM definition as appropriate, on
18912 * either success or failure. */
18914 qemuDomainBlockPivot(virQEMUDriverPtr driver
,
18915 virDomainObjPtr vm
,
18916 qemuBlockJobDataPtr job
,
18917 virDomainDiskDefPtr disk
)
18920 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
18922 if (!disk
->mirror
) {
18923 virReportError(VIR_ERR_OPERATION_INVALID
,
18924 _("pivot of disk '%s' requires an active copy job"),
18929 if (disk
->mirrorState
!= VIR_DOMAIN_DISK_MIRROR_STATE_READY
) {
18930 virReportError(VIR_ERR_BLOCK_COPY_ACTIVE
,
18931 _("disk '%s' not ready for pivot yet"),
18936 /* Attempt the pivot. Record the attempt now, to prevent duplicate
18937 * attempts; but the actual disk change will be made when emitting
18939 * XXX On libvirtd restarts, if we missed the qemu event, we need
18940 * to double check what state qemu is in.
18941 * XXX We should be using qemu's rerror flag to make sure the job
18942 * remains alive until we know its final state.
18943 * XXX If the abort command is synchronous but the qemu event says
18944 * that pivot failed, we need to reflect that failure into the
18945 * overall return value. */
18946 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT
;
18947 qemuDomainObjEnterMonitor(driver
, vm
);
18948 ret
= qemuMonitorDrivePivot(priv
->mon
, job
->name
);
18949 if (qemuDomainObjExitMonitor(driver
, vm
) < 0) {
18955 /* The pivot failed. The block job in QEMU remains in the synchronised
18956 * phase. Reset the state we changed and return the error to the user */
18957 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_READY
;
18965 /* bandwidth in MiB/s per public API. Caller must lock vm beforehand,
18966 * and not access it afterwards. */
18968 qemuDomainBlockPullCommon(virQEMUDriverPtr driver
,
18969 virDomainObjPtr vm
,
18972 unsigned long bandwidth
,
18973 unsigned int flags
)
18975 qemuDomainObjPrivatePtr priv
= vm
->privateData
;
18976 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
18977 char *device
= NULL
;
18978 virDomainDiskDefPtr disk
;
18979 virStorageSourcePtr baseSource
= NULL
;
18980 unsigned int baseIndex
= 0;
18981 char *basePath
= NULL
;
18982 char *backingPath
= NULL
;
18983 unsigned long long speed
= bandwidth
;
18984 qemuBlockJobDataPtr job
= NULL
;
18987 if (flags
& VIR_DOMAIN_BLOCK_REBASE_RELATIVE
&& !base
) {
18988 virReportError(VIR_ERR_INVALID_ARG
, "%s",
18989 _("flag VIR_DOMAIN_BLOCK_REBASE_RELATIVE is valid only "
18990 "with non-null base"));
18994 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
18997 if (virDomainObjCheckActive(vm
) < 0)
19000 if (qemuDomainSupportsBlockJobs(vm
) < 0)
19003 if (!(disk
= qemuDomainDiskByName(vm
->def
, path
)))
19006 if (!(device
= qemuAliasDiskDriveFromDisk(disk
)))
19009 if (qemuDomainDiskBlockJobIsActive(disk
))
19013 (virStorageFileParseChainIndex(disk
->dst
, base
, &baseIndex
) < 0 ||
19014 !(baseSource
= virStorageFileChainLookup(disk
->src
, disk
->src
,
19015 base
, baseIndex
, NULL
))))
19019 if (flags
& VIR_DOMAIN_BLOCK_REBASE_RELATIVE
) {
19020 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_CHANGE_BACKING_FILE
)) {
19021 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
19022 _("this QEMU binary doesn't support relative "
19023 "block pull/rebase"));
19027 if (virStorageFileGetRelativeBackingPath(disk
->src
->backingStore
,
19032 if (!backingPath
) {
19033 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
19034 _("can't keep relative backing relationship"));
19040 /* Convert bandwidth MiB to bytes, if needed */
19041 if (!(flags
& VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES
)) {
19042 if (speed
> LLONG_MAX
>> 20) {
19043 virReportError(VIR_ERR_OVERFLOW
,
19044 _("bandwidth must be less than %llu"),
19051 if (!(job
= qemuBlockJobDiskNew(disk
, QEMU_BLOCKJOB_TYPE_PULL
, device
)))
19054 qemuDomainObjEnterMonitor(driver
, vm
);
19056 basePath
= qemuMonitorDiskNameLookup(priv
->mon
, device
, disk
->src
,
19058 if (!baseSource
|| basePath
)
19059 ret
= qemuMonitorBlockStream(priv
->mon
, device
, basePath
, backingPath
,
19061 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
19067 qemuBlockJobStarted(job
);
19069 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
19070 VIR_WARN("Unable to save status on vm %s after state change",
19074 qemuDomainObjEndJob(driver
, vm
);
19077 qemuBlockJobStartupFinalize(job
);
19078 virObjectUnref(cfg
);
19079 VIR_FREE(basePath
);
19080 VIR_FREE(backingPath
);
19082 virDomainObjEndAPI(&vm
);
19088 qemuDomainBlockJobAbort(virDomainPtr dom
,
19090 unsigned int flags
)
19092 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19093 virDomainDiskDefPtr disk
= NULL
;
19094 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
19095 bool pivot
= !!(flags
& VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT
);
19096 bool async
= !!(flags
& VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC
);
19097 qemuBlockJobDataPtr job
= NULL
;
19098 virDomainObjPtr vm
;
19101 virCheckFlags(VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC
|
19102 VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT
, -1);
19104 if (!(vm
= qemuDomObjFromDomain(dom
)))
19107 if (virDomainBlockJobAbortEnsureACL(dom
->conn
, vm
->def
) < 0)
19110 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
19113 if (virDomainObjCheckActive(vm
) < 0)
19116 if (qemuDomainSupportsBlockJobs(vm
) < 0)
19119 if (!(disk
= qemuDomainDiskByName(vm
->def
, path
)))
19122 if (!(job
= qemuBlockJobDiskGetJob(disk
))) {
19123 virReportError(VIR_ERR_INVALID_ARG
,
19124 _("disk %s does not have an active block job"), disk
->dst
);
19128 if (disk
->mirrorState
!= VIR_DOMAIN_DISK_MIRROR_STATE_NONE
&&
19129 disk
->mirrorState
!= VIR_DOMAIN_DISK_MIRROR_STATE_READY
) {
19130 virReportError(VIR_ERR_OPERATION_INVALID
,
19131 _("another job on disk '%s' is still being ended"),
19137 qemuBlockJobSyncBegin(job
);
19140 if ((ret
= qemuDomainBlockPivot(driver
, vm
, job
, disk
)) < 0)
19144 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_ABORT
;
19146 qemuDomainObjEnterMonitor(driver
, vm
);
19147 ret
= qemuMonitorBlockJobCancel(qemuDomainGetMonitor(vm
), job
->name
);
19148 if (qemuDomainObjExitMonitor(driver
, vm
) < 0) {
19155 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_NONE
;
19160 ignore_value(virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
));
19163 * With the ABORT_ASYNC flag we don't need to do anything, the event will
19164 * come from qemu and will update the XML as appropriate, but without the
19165 * ABORT_ASYNC flag, we must block to guarantee synchronous operation. We
19166 * do the waiting while still holding the VM job, to prevent newly
19167 * scheduled block jobs from confusing us. */
19169 qemuBlockJobUpdate(vm
, job
, QEMU_ASYNC_JOB_NONE
);
19170 while (qemuBlockJobIsRunning(job
)) {
19171 if (virDomainObjWait(vm
) < 0) {
19175 qemuBlockJobUpdate(vm
, job
, QEMU_ASYNC_JOB_NONE
);
19181 qemuBlockJobSyncEnd(vm
, job
, QEMU_ASYNC_JOB_NONE
);
19182 qemuDomainObjEndJob(driver
, vm
);
19185 virObjectUnref(job
);
19186 virObjectUnref(cfg
);
19187 virDomainObjEndAPI(&vm
);
19193 qemuBlockJobInfoTranslate(qemuMonitorBlockJobInfoPtr rawInfo
,
19194 virDomainBlockJobInfoPtr info
,
19195 virDomainDiskDefPtr disk
,
19198 info
->cur
= rawInfo
->cur
;
19199 info
->end
= rawInfo
->end
;
19201 /* Fix job completeness reporting. If cur == end mgmt
19202 * applications think job is completed. Except when both cur
19203 * and end are zero, in which case qemu hasn't started the
19205 if (!info
->cur
&& !info
->end
) {
19206 if (rawInfo
->ready
> 0) {
19207 info
->cur
= info
->end
= 1;
19208 } else if (!rawInfo
->ready
) {
19213 /* If qemu reports that it's not ready yet don't make the job go to
19214 * cur == end as some apps wrote code polling this instead of waiting for
19215 * the ready event */
19216 if (rawInfo
->ready
== 0 &&
19217 info
->cur
== info
->end
&&
19221 info
->type
= rawInfo
->type
;
19222 if (info
->type
== VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT
&&
19223 disk
->mirrorJob
== VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT
)
19224 info
->type
= disk
->mirrorJob
;
19226 if (rawInfo
->bandwidth
&& !reportBytes
)
19227 rawInfo
->bandwidth
= VIR_DIV_UP(rawInfo
->bandwidth
, 1024 * 1024);
19228 info
->bandwidth
= rawInfo
->bandwidth
;
19229 if (info
->bandwidth
!= rawInfo
->bandwidth
) {
19230 virReportError(VIR_ERR_OVERFLOW
,
19231 _("bandwidth %llu cannot be represented in result"),
19232 rawInfo
->bandwidth
);
19241 qemuDomainGetBlockJobInfo(virDomainPtr dom
,
19243 virDomainBlockJobInfoPtr info
,
19244 unsigned int flags
)
19246 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19247 virDomainObjPtr vm
;
19248 virDomainDiskDefPtr disk
;
19250 qemuMonitorBlockJobInfo rawInfo
;
19252 virCheckFlags(VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES
, -1);
19254 if (!(vm
= qemuDomObjFromDomain(dom
)))
19257 if (virDomainGetBlockJobInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
19261 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
19264 if (virDomainObjCheckActive(vm
) < 0)
19267 if (qemuDomainSupportsBlockJobs(vm
) < 0)
19270 if (!(disk
= virDomainDiskByName(vm
->def
, path
, true))) {
19271 virReportError(VIR_ERR_INVALID_ARG
,
19272 _("disk %s not found in the domain"), path
);
19276 qemuDomainObjEnterMonitor(driver
, vm
);
19277 ret
= qemuMonitorGetBlockJobInfo(qemuDomainGetMonitor(vm
),
19278 disk
->info
.alias
, &rawInfo
);
19279 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
19284 if (qemuBlockJobInfoTranslate(&rawInfo
, info
, disk
,
19285 flags
& VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES
) < 0) {
19290 /* Snoop block copy operations, so future cancel operations can
19291 * avoid checking if pivot is safe. Save the change to XML, but
19292 * we can ignore failure because it is only an optimization. We
19293 * hold the vm lock, so modifying the in-memory representation is
19294 * safe, even if we are a query rather than a modify job. */
19295 if (disk
->mirror
&&
19296 rawInfo
.ready
!= 0 &&
19297 info
->cur
== info
->end
&& !disk
->mirrorState
) {
19298 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
19300 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_READY
;
19301 ignore_value(virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
));
19302 virObjectUnref(cfg
);
19305 qemuDomainObjEndJob(driver
, vm
);
19308 virDomainObjEndAPI(&vm
);
19314 qemuDomainBlockJobSetSpeed(virDomainPtr dom
,
19316 unsigned long bandwidth
,
19317 unsigned int flags
)
19319 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19320 virDomainDiskDefPtr disk
;
19322 virDomainObjPtr vm
;
19323 char *device
= NULL
;
19324 unsigned long long speed
= bandwidth
;
19326 virCheckFlags(VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES
, -1);
19328 /* Convert bandwidth MiB to bytes, if needed */
19329 if (!(flags
& VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES
)) {
19330 if (speed
> LLONG_MAX
>> 20) {
19331 virReportError(VIR_ERR_OVERFLOW
,
19332 _("bandwidth must be less than %llu"),
19339 if (!(vm
= qemuDomObjFromDomain(dom
)))
19342 if (virDomainBlockJobSetSpeedEnsureACL(dom
->conn
, vm
->def
) < 0)
19345 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
19348 if (virDomainObjCheckActive(vm
) < 0)
19351 if (qemuDomainSupportsBlockJobs(vm
) < 0)
19354 if (!(disk
= qemuDomainDiskByName(vm
->def
, path
)))
19357 if (!(device
= qemuAliasDiskDriveFromDisk(disk
)))
19360 qemuDomainObjEnterMonitor(driver
, vm
);
19361 ret
= qemuMonitorBlockJobSetSpeed(qemuDomainGetMonitor(vm
),
19364 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
19368 qemuDomainObjEndJob(driver
, vm
);
19372 virDomainObjEndAPI(&vm
);
19379 qemuDomainBlockCopyValidateMirror(virStorageSourcePtr mirror
,
19383 int desttype
= virStorageSourceGetActualType(mirror
);
19386 if (virStorageFileAccess(mirror
, F_OK
) < 0) {
19387 if (errno
!= ENOENT
) {
19388 virReportSystemError(errno
, "%s",
19389 _("unable to verify existence of "
19390 "block copy target"));
19394 if (*reuse
|| desttype
== VIR_STORAGE_TYPE_BLOCK
) {
19395 virReportSystemError(errno
,
19396 _("missing destination file for disk %s: %s"),
19397 dst
, mirror
->path
);
19401 if (virStorageFileStat(mirror
, &st
) < 0) {
19402 virReportSystemError(errno
,
19403 _("unable to stat block copy target '%s'"),
19408 if (S_ISBLK(st
.st_mode
)) {
19409 /* if the target is a block device, assume that we are reusing it,
19410 * so there are no attempts to create it */
19413 if (st
.st_size
&& !(*reuse
)) {
19414 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
19415 _("external destination file for disk %s already "
19416 "exists and is not a block device: %s"),
19417 dst
, mirror
->path
);
19421 if (desttype
== VIR_STORAGE_TYPE_BLOCK
) {
19422 virReportError(VIR_ERR_INVALID_ARG
,
19423 _("blockdev flag requested for disk %s, but file "
19424 "'%s' is not a block device"),
19425 dst
, mirror
->path
);
19435 /* bandwidth in bytes/s. Caller must lock vm beforehand, and not
19436 * access mirror afterwards. */
19438 qemuDomainBlockCopyCommon(virDomainObjPtr vm
,
19439 virConnectPtr conn
,
19441 virStorageSourcePtr mirror
,
19442 unsigned long long bandwidth
,
19443 unsigned int granularity
,
19444 unsigned long long buf_size
,
19445 unsigned int flags
,
19446 bool keepParentLabel
)
19448 virQEMUDriverPtr driver
= conn
->privateData
;
19449 qemuDomainObjPrivatePtr priv
;
19450 char *device
= NULL
;
19451 virDomainDiskDefPtr disk
= NULL
;
19453 bool need_unlink
= false;
19454 virQEMUDriverConfigPtr cfg
= NULL
;
19455 const char *format
= NULL
;
19456 virErrorPtr monitor_error
= NULL
;
19457 bool reuse
= !!(flags
& VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
);
19458 qemuBlockJobDataPtr job
= NULL
;
19460 /* Preliminaries: find the disk we are editing, sanity checks */
19461 virCheckFlags(VIR_DOMAIN_BLOCK_COPY_SHALLOW
|
19462 VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
|
19463 VIR_DOMAIN_BLOCK_COPY_TRANSIENT_JOB
, -1);
19465 priv
= vm
->privateData
;
19466 cfg
= virQEMUDriverGetConfig(driver
);
19468 if (virStorageSourceIsRelative(mirror
)) {
19469 virReportError(VIR_ERR_INVALID_ARG
, "%s",
19470 _("absolute path must be used as block copy target"));
19474 if (bandwidth
> LLONG_MAX
) {
19475 virReportError(VIR_ERR_INVALID_ARG
,
19476 _("bandwidth must be less than "
19477 "'%llu' bytes/s (%llu MiB/s)"),
19478 LLONG_MAX
, LLONG_MAX
>> 20);
19482 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
19485 if (virDomainObjCheckActive(vm
) < 0)
19488 if (!(disk
= qemuDomainDiskByName(vm
->def
, path
)))
19491 if (!(device
= qemuAliasDiskDriveFromDisk(disk
)))
19494 if (qemuDomainDiskBlockJobIsActive(disk
))
19497 if (disk
->device
== VIR_DOMAIN_DISK_DEVICE_LUN
&&
19498 qemuDomainDefValidateDiskLunSource(mirror
) < 0)
19501 if (!(virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DRIVE_MIRROR
) &&
19502 virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKJOB_ASYNC
))) {
19503 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
19504 _("block copy is not supported with this QEMU binary"));
19507 if (!(flags
& VIR_DOMAIN_BLOCK_COPY_TRANSIENT_JOB
) &&
19509 /* XXX if qemu ever lets us start a new domain with mirroring
19510 * already active, we can relax this; but for now, the risk of
19511 * 'managedsave' due to libvirt-guests means we can't risk
19512 * this on persistent domains. */
19513 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
19514 _("domain is not transient"));
19518 /* clear the _SHALLOW flag if there is only one layer */
19519 if (!virStorageSourceHasBacking(disk
->src
))
19520 flags
&= ~VIR_DOMAIN_BLOCK_COPY_SHALLOW
;
19522 /* unless the user provides a pre-created file, shallow copy into a raw
19523 * file is not possible */
19524 if ((flags
& VIR_DOMAIN_BLOCK_COPY_SHALLOW
) && !reuse
&&
19525 mirror
->format
== VIR_STORAGE_FILE_RAW
) {
19526 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
19527 _("shallow copy of disk '%s' into a raw file "
19528 "is not possible"),
19533 /* Prepare the destination file. */
19534 /* XXX Allow non-file mirror destinations */
19535 if (!virStorageSourceIsLocalStorage(mirror
)) {
19536 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
19537 _("non-file destination not supported yet"));
19541 if (qemuDomainStorageFileInit(driver
, vm
, mirror
, NULL
) < 0)
19544 if (qemuDomainBlockCopyValidateMirror(mirror
, disk
->dst
, &reuse
) < 0)
19547 if (!mirror
->format
) {
19548 if (!(flags
& VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
)) {
19549 mirror
->format
= disk
->src
->format
;
19551 /* If the user passed the REUSE_EXT flag, then either they
19552 * can also pass the RAW flag or use XML to tell us the format.
19553 * So if we get here, we assume it is safe for us to probe the
19554 * format from the file that we will be using. */
19555 mirror
->format
= virStorageFileProbeFormat(mirror
->path
, cfg
->user
,
19560 /* When copying a shareable disk we need to make sure that the disk can
19561 * be safely shared, since block copy may change the format. */
19562 if (disk
->src
->shared
&& !disk
->src
->readonly
&&
19563 !qemuBlockStorageSourceSupportsConcurrentAccess(mirror
)) {
19564 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
19565 _("can't pivot a shared disk to a storage volume not "
19566 "supporting sharing"));
19570 /* pre-create the image file */
19572 if (virStorageFileCreate(mirror
) < 0) {
19573 virReportSystemError(errno
, "%s", _("failed to create copy target"));
19577 need_unlink
= true;
19580 if (mirror
->format
> 0)
19581 format
= virStorageFileFormatTypeToString(mirror
->format
);
19583 if (virStorageSourceInitChainElement(mirror
, disk
->src
,
19584 keepParentLabel
) < 0)
19587 /* If reusing an external image that includes a backing file, the pivot may
19588 * result in qemu needing to open the entire backing chain, so we need to
19589 * label the full backing chain of the mirror instead of just the top image */
19590 if (flags
& VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
&&
19591 mirror
->format
>= VIR_STORAGE_FILE_BACKING
&&
19592 qemuDomainDetermineDiskChain(driver
, vm
, disk
, mirror
, true) < 0)
19595 if (flags
& VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
&&
19596 virStorageSourceHasBacking(mirror
)) {
19597 /* note that we don't really know whether a part of the backing chain
19598 * is shared so rolling this back is not as easy. Thus we do it only
19599 * if there's a backing chain */
19600 if (qemuDomainNamespaceSetupDisk(vm
, mirror
) < 0 ||
19601 qemuSetupImageChainCgroup(vm
, mirror
) < 0 ||
19602 qemuSecuritySetImageLabel(driver
, vm
, mirror
, true) < 0)
19605 if (qemuDomainDiskChainElementPrepare(driver
, vm
, mirror
, false, true) < 0) {
19606 qemuDomainDiskChainElementRevoke(driver
, vm
, mirror
);
19611 if (!(job
= qemuBlockJobDiskNew(disk
, QEMU_BLOCKJOB_TYPE_COPY
, device
)))
19614 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_NONE
;
19616 /* Actually start the mirroring */
19617 qemuDomainObjEnterMonitor(driver
, vm
);
19618 /* qemuMonitorDriveMirror needs to honor the REUSE_EXT flag as specified
19619 * by the user regardless of how @reuse was modified */
19620 ret
= qemuMonitorDriveMirror(priv
->mon
, device
, mirror
->path
, format
,
19621 bandwidth
, granularity
, buf_size
, flags
);
19622 virDomainAuditDisk(vm
, NULL
, mirror
, "mirror", ret
>= 0);
19623 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
19626 monitor_error
= virSaveLastError();
19627 qemuDomainDiskChainElementRevoke(driver
, vm
, mirror
);
19631 /* Update vm in place to match changes. */
19632 qemuBlockJobStarted(job
);
19633 need_unlink
= false;
19634 virStorageFileDeinit(mirror
);
19635 disk
->mirror
= mirror
;
19637 disk
->mirrorJob
= VIR_DOMAIN_BLOCK_JOB_TYPE_COPY
;
19639 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
19640 VIR_WARN("Unable to save status on vm %s after state change",
19644 if (need_unlink
&& virStorageFileUnlink(mirror
) < 0)
19645 VIR_WARN("%s", _("unable to remove just-created copy target"));
19646 virStorageFileDeinit(mirror
);
19647 qemuDomainObjEndJob(driver
, vm
);
19648 if (monitor_error
) {
19649 virSetError(monitor_error
);
19650 virFreeError(monitor_error
);
19652 qemuBlockJobStartupFinalize(job
);
19656 virObjectUnref(cfg
);
19657 virObjectUnref(mirror
);
19662 qemuDomainBlockRebase(virDomainPtr dom
, const char *path
, const char *base
,
19663 unsigned long bandwidth
, unsigned int flags
)
19665 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19666 virDomainObjPtr vm
;
19668 unsigned long long speed
= bandwidth
;
19669 VIR_AUTOUNREF(virStorageSourcePtr
) dest
= NULL
;
19671 virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW
|
19672 VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT
|
19673 VIR_DOMAIN_BLOCK_REBASE_COPY
|
19674 VIR_DOMAIN_BLOCK_REBASE_COPY_RAW
|
19675 VIR_DOMAIN_BLOCK_REBASE_RELATIVE
|
19676 VIR_DOMAIN_BLOCK_REBASE_COPY_DEV
|
19677 VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES
, -1);
19679 if (!(vm
= qemuDomObjFromDomain(dom
)))
19682 if (virDomainBlockRebaseEnsureACL(dom
->conn
, vm
->def
) < 0)
19685 /* For normal rebase (enhanced blockpull), the common code handles
19686 * everything, including vm cleanup. */
19687 if (!(flags
& VIR_DOMAIN_BLOCK_REBASE_COPY
))
19688 return qemuDomainBlockPullCommon(driver
, vm
, path
, base
, bandwidth
, flags
);
19690 /* If we got here, we are doing a block copy rebase. */
19691 if (!(dest
= virStorageSourceNew()))
19693 dest
->type
= (flags
& VIR_DOMAIN_BLOCK_REBASE_COPY_DEV
) ?
19694 VIR_STORAGE_TYPE_BLOCK
: VIR_STORAGE_TYPE_FILE
;
19695 if (VIR_STRDUP(dest
->path
, base
) < 0)
19697 if (flags
& VIR_DOMAIN_BLOCK_REBASE_COPY_RAW
)
19698 dest
->format
= VIR_STORAGE_FILE_RAW
;
19700 /* Convert bandwidth MiB to bytes, if necessary */
19701 if (!(flags
& VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES
)) {
19702 if (speed
> LLONG_MAX
>> 20) {
19703 virReportError(VIR_ERR_OVERFLOW
,
19704 _("bandwidth must be less than %llu"),
19711 /* XXX: If we are doing a shallow copy but not reusing an external
19712 * file, we should attempt to pre-create the destination with a
19713 * relative backing chain instead of qemu's default of absolute */
19714 if (flags
& VIR_DOMAIN_BLOCK_REBASE_RELATIVE
) {
19715 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
19716 _("Relative backing during copy not supported yet"));
19720 /* We rely on the fact that VIR_DOMAIN_BLOCK_REBASE_SHALLOW
19721 * and VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT map to the same values
19722 * as for block copy. */
19723 flags
&= (VIR_DOMAIN_BLOCK_REBASE_SHALLOW
|
19724 VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT
);
19725 ret
= qemuDomainBlockCopyCommon(vm
, dom
->conn
, path
, dest
,
19726 speed
, 0, 0, flags
, true);
19730 virDomainObjEndAPI(&vm
);
19736 qemuDomainBlockCopy(virDomainPtr dom
, const char *disk
, const char *destxml
,
19737 virTypedParameterPtr params
, int nparams
,
19738 unsigned int flags
)
19740 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19741 virDomainObjPtr vm
;
19743 unsigned long long bandwidth
= 0;
19744 unsigned int granularity
= 0;
19745 unsigned long long buf_size
= 0;
19746 virDomainDiskDefPtr diskdef
= NULL
;
19747 virStorageSourcePtr dest
= NULL
;
19750 virCheckFlags(VIR_DOMAIN_BLOCK_COPY_SHALLOW
|
19751 VIR_DOMAIN_BLOCK_COPY_REUSE_EXT
|
19752 VIR_DOMAIN_BLOCK_COPY_TRANSIENT_JOB
, -1);
19753 if (virTypedParamsValidate(params
, nparams
,
19754 VIR_DOMAIN_BLOCK_COPY_BANDWIDTH
,
19755 VIR_TYPED_PARAM_ULLONG
,
19756 VIR_DOMAIN_BLOCK_COPY_GRANULARITY
,
19757 VIR_TYPED_PARAM_UINT
,
19758 VIR_DOMAIN_BLOCK_COPY_BUF_SIZE
,
19759 VIR_TYPED_PARAM_ULLONG
,
19763 if (!(vm
= qemuDomObjFromDomain(dom
)))
19766 if (virDomainBlockCopyEnsureACL(dom
->conn
, vm
->def
) < 0)
19769 for (i
= 0; i
< nparams
; i
++) {
19770 virTypedParameterPtr param
= ¶ms
[i
];
19772 /* Typed params (wisely) refused to expose unsigned long, but
19773 * back-compat demands that we stick with a maximum of
19774 * unsigned long bandwidth in MiB/s, while our value is
19775 * unsigned long long in bytes/s. Hence, we have to do
19776 * overflow detection if this is a 32-bit server handling a
19777 * 64-bit client. */
19778 if (STREQ(param
->field
, VIR_DOMAIN_BLOCK_COPY_BANDWIDTH
)) {
19779 if (sizeof(unsigned long)< sizeof(bandwidth
) &&
19780 param
->value
.ul
> ULONG_MAX
* (1ULL << 20)) {
19781 virReportError(VIR_ERR_OVERFLOW
,
19782 _("bandwidth must be less than %llu bytes"),
19783 ULONG_MAX
* (1ULL << 20));
19786 bandwidth
= param
->value
.ul
;
19787 } else if (STREQ(param
->field
, VIR_DOMAIN_BLOCK_COPY_GRANULARITY
)) {
19788 if (param
->value
.ui
!= VIR_ROUND_UP_POWER_OF_TWO(param
->value
.ui
)) {
19789 virReportError(VIR_ERR_INVALID_ARG
, "%s",
19790 _("granularity must be power of 2"));
19793 granularity
= param
->value
.ui
;
19794 } else if (STREQ(param
->field
, VIR_DOMAIN_BLOCK_COPY_BUF_SIZE
)) {
19795 buf_size
= param
->value
.ul
;
19799 if (!(diskdef
= virDomainDiskDefParse(destxml
, vm
->def
, driver
->xmlopt
,
19800 VIR_DOMAIN_DEF_PARSE_INACTIVE
|
19801 VIR_DOMAIN_DEF_PARSE_DISK_SOURCE
)))
19804 VIR_STEAL_PTR(dest
, diskdef
->src
);
19806 ret
= qemuDomainBlockCopyCommon(vm
, dom
->conn
, disk
, dest
, bandwidth
,
19807 granularity
, buf_size
, flags
, false);
19810 virDomainDiskDefFree(diskdef
);
19811 virDomainObjEndAPI(&vm
);
19817 qemuDomainBlockPull(virDomainPtr dom
, const char *path
, unsigned long bandwidth
,
19818 unsigned int flags
)
19820 virDomainObjPtr vm
;
19821 virCheckFlags(VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES
, -1);
19823 if (!(vm
= qemuDomObjFromDomain(dom
)))
19826 if (virDomainBlockPullEnsureACL(dom
->conn
, vm
->def
) < 0) {
19827 virDomainObjEndAPI(&vm
);
19831 return qemuDomainBlockPullCommon(dom
->conn
->privateData
,
19832 vm
, path
, NULL
, bandwidth
, flags
);
19837 qemuDomainBlockCommit(virDomainPtr dom
,
19841 unsigned long bandwidth
,
19842 unsigned int flags
)
19844 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
19845 virQEMUDriverConfigPtr cfg
= NULL
;
19846 qemuDomainObjPrivatePtr priv
;
19847 virDomainObjPtr vm
= NULL
;
19848 char *device
= NULL
;
19850 virDomainDiskDefPtr disk
= NULL
;
19851 virStorageSourcePtr topSource
;
19852 unsigned int topIndex
= 0;
19853 virStorageSourcePtr baseSource
= NULL
;
19854 unsigned int baseIndex
= 0;
19855 virStorageSourcePtr top_parent
= NULL
;
19856 bool clean_access
= false;
19857 char *topPath
= NULL
;
19858 char *basePath
= NULL
;
19859 char *backingPath
= NULL
;
19860 unsigned long long speed
= bandwidth
;
19861 qemuBlockJobDataPtr job
= NULL
;
19862 qemuBlockJobType jobtype
= QEMU_BLOCKJOB_TYPE_COMMIT
;
19863 VIR_AUTOUNREF(virStorageSourcePtr
) mirror
= NULL
;
19865 /* XXX Add support for COMMIT_DELETE */
19866 virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW
|
19867 VIR_DOMAIN_BLOCK_COMMIT_ACTIVE
|
19868 VIR_DOMAIN_BLOCK_COMMIT_RELATIVE
|
19869 VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES
, -1);
19871 if (!(vm
= qemuDomObjFromDomain(dom
)))
19873 priv
= vm
->privateData
;
19874 cfg
= virQEMUDriverGetConfig(driver
);
19876 if (virDomainBlockCommitEnsureACL(dom
->conn
, vm
->def
) < 0)
19879 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
19882 if (virDomainObjCheckActive(vm
) < 0)
19884 /* Ensure that no one backports commit to RHEL 6.2, where cancel
19885 * behaved differently */
19886 if (!(virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCK_COMMIT
) &&
19887 virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKJOB_ASYNC
))) {
19888 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
19889 _("online commit not supported with this QEMU binary"));
19893 /* Convert bandwidth MiB to bytes, if necessary */
19894 if (!(flags
& VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES
)) {
19895 if (speed
> LLONG_MAX
>> 20) {
19896 virReportError(VIR_ERR_OVERFLOW
,
19897 _("bandwidth must be less than %llu"),
19904 if (!(disk
= qemuDomainDiskByName(vm
->def
, path
)))
19907 if (!(device
= qemuAliasDiskDriveFromDisk(disk
)))
19910 if (!disk
->src
->path
) {
19911 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
19912 _("disk %s has no source file to be committed"),
19917 if (qemuDomainDiskBlockJobIsActive(disk
))
19920 if (!top
|| STREQ(top
, disk
->dst
))
19921 topSource
= disk
->src
;
19922 else if (virStorageFileParseChainIndex(disk
->dst
, top
, &topIndex
) < 0 ||
19923 !(topSource
= virStorageFileChainLookup(disk
->src
, NULL
,
19928 if (topSource
== disk
->src
) {
19929 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_ACTIVE_COMMIT
)) {
19930 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
19931 _("active commit not supported with this QEMU binary"));
19934 /* XXX Should we auto-pivot when COMMIT_ACTIVE is not specified? */
19935 if (!(flags
& VIR_DOMAIN_BLOCK_COMMIT_ACTIVE
)) {
19936 virReportError(VIR_ERR_INVALID_ARG
,
19937 _("commit of '%s' active layer requires active flag"),
19942 jobtype
= QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT
;
19943 } else if (flags
& VIR_DOMAIN_BLOCK_COMMIT_ACTIVE
) {
19944 virReportError(VIR_ERR_INVALID_ARG
,
19945 _("active commit requested but '%s' is not active"),
19950 if (!virStorageSourceHasBacking(topSource
)) {
19951 virReportError(VIR_ERR_INVALID_ARG
,
19952 _("top '%s' in chain for '%s' has no backing file"),
19953 topSource
->path
, path
);
19957 if (!base
&& (flags
& VIR_DOMAIN_BLOCK_COMMIT_SHALLOW
))
19958 baseSource
= topSource
->backingStore
;
19959 else if (virStorageFileParseChainIndex(disk
->dst
, base
, &baseIndex
) < 0 ||
19960 !(baseSource
= virStorageFileChainLookup(disk
->src
, topSource
,
19961 base
, baseIndex
, NULL
)))
19964 if ((flags
& VIR_DOMAIN_BLOCK_COMMIT_SHALLOW
) &&
19965 baseSource
!= topSource
->backingStore
) {
19966 virReportError(VIR_ERR_INVALID_ARG
,
19967 _("base '%s' is not immediately below '%s' in chain "
19969 base
, topSource
->path
, path
);
19973 /* For an active commit, clone enough of the base to act as the mirror */
19974 if (topSource
== disk
->src
) {
19975 if (!(mirror
= virStorageSourceCopy(baseSource
, false)))
19977 if (virStorageSourceInitChainElement(mirror
,
19983 if (flags
& VIR_DOMAIN_BLOCK_COMMIT_RELATIVE
&&
19984 topSource
!= disk
->src
) {
19985 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_CHANGE_BACKING_FILE
)) {
19986 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
19987 _("this qemu doesn't support relative block commit"));
19991 if (virStorageFileGetRelativeBackingPath(topSource
, baseSource
,
19995 if (!backingPath
) {
19996 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
19997 _("can't keep relative backing relationship"));
20002 /* For the commit to succeed, we must allow qemu to open both the
20003 * 'base' image and the parent of 'top' as read/write; 'top' might
20004 * not have a parent, or might already be read-write. XXX It
20005 * would also be nice to revert 'base' to read-only, as well as
20006 * revoke access to files removed from the chain, when the commit
20007 * operation succeeds, but doing that requires tracking the
20008 * operation in XML across libvirtd restarts. */
20009 clean_access
= true;
20010 if (qemuDomainDiskChainElementPrepare(driver
, vm
, baseSource
, false, false) < 0 ||
20011 (top_parent
&& top_parent
!= disk
->src
&&
20012 qemuDomainDiskChainElementPrepare(driver
, vm
, top_parent
, false, false) < 0))
20015 if (!(job
= qemuBlockJobDiskNew(disk
, jobtype
, device
)))
20018 disk
->mirrorState
= VIR_DOMAIN_DISK_MIRROR_STATE_NONE
;
20020 /* Start the commit operation. Pass the user's original spelling,
20021 * if any, through to qemu, since qemu may behave differently
20022 * depending on whether the input was specified as relative or
20023 * absolute (that is, our absolute top_canon may do the wrong
20024 * thing if the user specified a relative name). */
20025 qemuDomainObjEnterMonitor(driver
, vm
);
20026 basePath
= qemuMonitorDiskNameLookup(priv
->mon
, device
, disk
->src
,
20028 topPath
= qemuMonitorDiskNameLookup(priv
->mon
, device
, disk
->src
,
20030 if (basePath
&& topPath
)
20031 ret
= qemuMonitorBlockCommit(priv
->mon
, device
,
20032 topPath
, basePath
, backingPath
,
20034 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || ret
< 0) {
20039 qemuBlockJobStarted(job
);
20041 VIR_STEAL_PTR(disk
->mirror
, mirror
);
20042 disk
->mirrorJob
= VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT
;
20045 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
, vm
, driver
->caps
) < 0)
20046 VIR_WARN("Unable to save status on vm %s after block job",
20050 if (ret
< 0 && clean_access
) {
20051 virErrorPtr orig_err
= virSaveLastError();
20052 /* Revert access to read-only, if possible. */
20053 qemuDomainDiskChainElementPrepare(driver
, vm
, baseSource
, true, false);
20054 if (top_parent
&& top_parent
!= disk
->src
)
20055 qemuDomainDiskChainElementPrepare(driver
, vm
, top_parent
, true, false);
20058 virSetError(orig_err
);
20059 virFreeError(orig_err
);
20062 qemuBlockJobStartupFinalize(job
);
20063 qemuDomainObjEndJob(driver
, vm
);
20067 VIR_FREE(basePath
);
20068 VIR_FREE(backingPath
);
20070 virObjectUnref(cfg
);
20071 virDomainObjEndAPI(&vm
);
20076 qemuDomainOpenGraphics(virDomainPtr dom
,
20079 unsigned int flags
)
20081 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20082 virDomainObjPtr vm
= NULL
;
20084 qemuDomainObjPrivatePtr priv
;
20085 const char *protocol
;
20087 virCheckFlags(VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
, -1);
20089 if (!(vm
= qemuDomObjFromDomain(dom
)))
20092 if (virDomainOpenGraphicsEnsureACL(dom
->conn
, vm
->def
) < 0)
20095 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
20098 if (virDomainObjCheckActive(vm
) < 0)
20101 priv
= vm
->privateData
;
20103 if (idx
>= vm
->def
->ngraphics
) {
20104 virReportError(VIR_ERR_INTERNAL_ERROR
,
20105 _("No graphics backend with index %d"), idx
);
20108 switch (vm
->def
->graphics
[idx
]->type
) {
20109 case VIR_DOMAIN_GRAPHICS_TYPE_VNC
:
20112 case VIR_DOMAIN_GRAPHICS_TYPE_SPICE
:
20113 protocol
= "spice";
20115 case VIR_DOMAIN_GRAPHICS_TYPE_SDL
:
20116 case VIR_DOMAIN_GRAPHICS_TYPE_RDP
:
20117 case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP
:
20118 case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS
:
20119 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
20120 _("Can only open VNC or SPICE graphics backends, not %s"),
20121 virDomainGraphicsTypeToString(vm
->def
->graphics
[idx
]->type
));
20123 case VIR_DOMAIN_GRAPHICS_TYPE_LAST
:
20125 virReportEnumRangeError(virDomainGraphicsType
,
20126 vm
->def
->graphics
[idx
]->type
);
20130 if (qemuSecuritySetImageFDLabel(driver
->securityManager
, vm
->def
, fd
) < 0)
20133 qemuDomainObjEnterMonitor(driver
, vm
);
20134 ret
= qemuMonitorOpenGraphics(priv
->mon
, protocol
, fd
, "graphicsfd",
20135 (flags
& VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
) != 0);
20136 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
20140 qemuDomainObjEndJob(driver
, vm
);
20143 virDomainObjEndAPI(&vm
);
20148 qemuDomainOpenGraphicsFD(virDomainPtr dom
,
20150 unsigned int flags
)
20152 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20153 virDomainObjPtr vm
= NULL
;
20155 qemuDomainObjPrivatePtr priv
;
20156 const char *protocol
;
20157 int pair
[2] = {-1, -1};
20159 virCheckFlags(VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
, -1);
20161 if (!(vm
= qemuDomObjFromDomain(dom
)))
20164 if (virDomainOpenGraphicsFdEnsureACL(dom
->conn
, vm
->def
) < 0)
20167 if (virDomainObjCheckActive(vm
) < 0)
20170 priv
= vm
->privateData
;
20172 if (idx
>= vm
->def
->ngraphics
) {
20173 virReportError(VIR_ERR_INTERNAL_ERROR
,
20174 _("No graphics backend with index %d"), idx
);
20177 switch (vm
->def
->graphics
[idx
]->type
) {
20178 case VIR_DOMAIN_GRAPHICS_TYPE_VNC
:
20181 case VIR_DOMAIN_GRAPHICS_TYPE_SPICE
:
20182 protocol
= "spice";
20184 case VIR_DOMAIN_GRAPHICS_TYPE_SDL
:
20185 case VIR_DOMAIN_GRAPHICS_TYPE_RDP
:
20186 case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP
:
20187 case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS
:
20188 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
,
20189 _("Can only open VNC or SPICE graphics backends, not %s"),
20190 virDomainGraphicsTypeToString(vm
->def
->graphics
[idx
]->type
));
20192 case VIR_DOMAIN_GRAPHICS_TYPE_LAST
:
20194 virReportEnumRangeError(virDomainGraphicsType
,
20195 vm
->def
->graphics
[idx
]->type
);
20199 if (qemuSecuritySetSocketLabel(driver
->securityManager
, vm
->def
) < 0)
20202 if (socketpair(PF_UNIX
, SOCK_STREAM
, 0, pair
) < 0)
20205 if (qemuSecurityClearSocketLabel(driver
->securityManager
, vm
->def
) < 0)
20208 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
20210 qemuDomainObjEnterMonitor(driver
, vm
);
20211 ret
= qemuMonitorOpenGraphics(priv
->mon
, protocol
, pair
[1], "graphicsfd",
20212 (flags
& VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
));
20213 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
20215 qemuDomainObjEndJob(driver
, vm
);
20223 VIR_FORCE_CLOSE(pair
[0]);
20224 VIR_FORCE_CLOSE(pair
[1]);
20225 virDomainObjEndAPI(&vm
);
20230 QEMU_BLOCK_IOTUNE_SET_BYTES
= 1 << 0,
20231 QEMU_BLOCK_IOTUNE_SET_IOPS
= 1 << 1,
20232 QEMU_BLOCK_IOTUNE_SET_BYTES_MAX
= 1 << 2,
20233 QEMU_BLOCK_IOTUNE_SET_IOPS_MAX
= 1 << 3,
20234 QEMU_BLOCK_IOTUNE_SET_SIZE_IOPS
= 1 << 4,
20235 QEMU_BLOCK_IOTUNE_SET_GROUP_NAME
= 1 << 5,
20236 QEMU_BLOCK_IOTUNE_SET_BYTES_MAX_LENGTH
= 1 << 6,
20237 QEMU_BLOCK_IOTUNE_SET_IOPS_MAX_LENGTH
= 1 << 7,
20238 } qemuBlockIoTuneSetFlags
;
20241 /* If the user didn't specify bytes limits, inherit previous values;
20242 * likewise if the user didn't specify iops limits. */
20244 qemuDomainSetBlockIoTuneDefaults(virDomainBlockIoTuneInfoPtr newinfo
,
20245 virDomainBlockIoTuneInfoPtr oldinfo
,
20246 qemuBlockIoTuneSetFlags set_fields
)
20248 #define SET_IOTUNE_DEFAULTS(BOOL, FIELD) \
20249 if (!(set_fields & QEMU_BLOCK_IOTUNE_SET_##BOOL)) { \
20250 newinfo->total_##FIELD = oldinfo->total_##FIELD; \
20251 newinfo->read_##FIELD = oldinfo->read_##FIELD; \
20252 newinfo->write_##FIELD = oldinfo->write_##FIELD; \
20255 SET_IOTUNE_DEFAULTS(BYTES
, bytes_sec
);
20256 SET_IOTUNE_DEFAULTS(BYTES_MAX
, bytes_sec_max
);
20257 SET_IOTUNE_DEFAULTS(IOPS
, iops_sec
);
20258 SET_IOTUNE_DEFAULTS(IOPS_MAX
, iops_sec_max
);
20259 #undef SET_IOTUNE_DEFAULTS
20261 if (!(set_fields
& QEMU_BLOCK_IOTUNE_SET_SIZE_IOPS
))
20262 newinfo
->size_iops_sec
= oldinfo
->size_iops_sec
;
20263 if (!(set_fields
& QEMU_BLOCK_IOTUNE_SET_GROUP_NAME
) &&
20264 VIR_STRDUP(newinfo
->group_name
, oldinfo
->group_name
) < 0)
20267 /* The length field is handled a bit differently. If not defined/set,
20268 * QEMU will default these to 0 or 1 depending on whether something in
20269 * the same family is set or not.
20271 * Similar to other values, if nothing in the family is defined/set,
20272 * then take whatever is in the oldinfo.
20274 * To clear an existing limit, a 0 is provided; however, passing that
20275 * 0 onto QEMU if there's a family value defined/set (or defaulted)
20276 * will cause an error. So, to mimic that, if our oldinfo was set and
20277 * our newinfo is clearing, then set max_length based on whether we
20278 * have a value in the family set/defined. */
20279 #define SET_MAX_LENGTH(BOOL, FIELD) \
20280 if (!(set_fields & QEMU_BLOCK_IOTUNE_SET_##BOOL)) \
20281 newinfo->FIELD##_max_length = oldinfo->FIELD##_max_length; \
20282 else if ((set_fields & QEMU_BLOCK_IOTUNE_SET_##BOOL) && \
20283 oldinfo->FIELD##_max_length && \
20284 !newinfo->FIELD##_max_length) \
20285 newinfo->FIELD##_max_length = (newinfo->FIELD || \
20286 newinfo->FIELD##_max) ? 1 : 0;
20288 SET_MAX_LENGTH(BYTES_MAX_LENGTH
, total_bytes_sec
);
20289 SET_MAX_LENGTH(BYTES_MAX_LENGTH
, read_bytes_sec
);
20290 SET_MAX_LENGTH(BYTES_MAX_LENGTH
, write_bytes_sec
);
20291 SET_MAX_LENGTH(IOPS_MAX_LENGTH
, total_iops_sec
);
20292 SET_MAX_LENGTH(IOPS_MAX_LENGTH
, read_iops_sec
);
20293 SET_MAX_LENGTH(IOPS_MAX_LENGTH
, write_iops_sec
);
20295 #undef SET_MAX_LENGTH
20302 qemuDomainSetBlockIoTune(virDomainPtr dom
,
20304 virTypedParameterPtr params
,
20306 unsigned int flags
)
20308 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20309 virDomainObjPtr vm
= NULL
;
20310 qemuDomainObjPrivatePtr priv
;
20311 virDomainDefPtr def
= NULL
;
20312 virDomainDefPtr persistentDef
= NULL
;
20313 virDomainBlockIoTuneInfo info
;
20314 char *drivealias
= NULL
;
20315 const char *qdevid
= NULL
;
20318 virDomainDiskDefPtr conf_disk
= NULL
;
20319 virDomainDiskDefPtr disk
;
20320 qemuBlockIoTuneSetFlags set_fields
= 0;
20321 bool supportMaxOptions
= true;
20322 bool supportGroupNameOption
= true;
20323 bool supportMaxLengthOptions
= true;
20324 virQEMUDriverConfigPtr cfg
= NULL
;
20325 virObjectEventPtr event
= NULL
;
20326 virTypedParameterPtr eventParams
= NULL
;
20327 int eventNparams
= 0;
20328 int eventMaxparams
= 0;
20330 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
20331 VIR_DOMAIN_AFFECT_CONFIG
, -1);
20332 if (virTypedParamsValidate(params
, nparams
,
20333 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC
,
20334 VIR_TYPED_PARAM_ULLONG
,
20335 VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC
,
20336 VIR_TYPED_PARAM_ULLONG
,
20337 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC
,
20338 VIR_TYPED_PARAM_ULLONG
,
20339 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC
,
20340 VIR_TYPED_PARAM_ULLONG
,
20341 VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC
,
20342 VIR_TYPED_PARAM_ULLONG
,
20343 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC
,
20344 VIR_TYPED_PARAM_ULLONG
,
20345 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX
,
20346 VIR_TYPED_PARAM_ULLONG
,
20347 VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX
,
20348 VIR_TYPED_PARAM_ULLONG
,
20349 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX
,
20350 VIR_TYPED_PARAM_ULLONG
,
20351 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX
,
20352 VIR_TYPED_PARAM_ULLONG
,
20353 VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX
,
20354 VIR_TYPED_PARAM_ULLONG
,
20355 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX
,
20356 VIR_TYPED_PARAM_ULLONG
,
20357 VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC
,
20358 VIR_TYPED_PARAM_ULLONG
,
20359 VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME
,
20360 VIR_TYPED_PARAM_STRING
,
20361 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX_LENGTH
,
20362 VIR_TYPED_PARAM_ULLONG
,
20363 VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX_LENGTH
,
20364 VIR_TYPED_PARAM_ULLONG
,
20365 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX_LENGTH
,
20366 VIR_TYPED_PARAM_ULLONG
,
20367 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX_LENGTH
,
20368 VIR_TYPED_PARAM_ULLONG
,
20369 VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX_LENGTH
,
20370 VIR_TYPED_PARAM_ULLONG
,
20371 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX_LENGTH
,
20372 VIR_TYPED_PARAM_ULLONG
,
20376 memset(&info
, 0, sizeof(info
));
20378 if (!(vm
= qemuDomObjFromDomain(dom
)))
20381 if (virDomainSetBlockIoTuneEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
20384 cfg
= virQEMUDriverGetConfig(driver
);
20386 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
20389 priv
= vm
->privateData
;
20391 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
20394 if (virTypedParamsAddString(&eventParams
, &eventNparams
, &eventMaxparams
,
20395 VIR_DOMAIN_TUNABLE_BLKDEV_DISK
, path
) < 0)
20398 #define SET_IOTUNE_FIELD(FIELD, BOOL, CONST) \
20399 if (STREQ(param->field, VIR_DOMAIN_BLOCK_IOTUNE_##CONST)) { \
20400 info.FIELD = param->value.ul; \
20401 set_fields |= QEMU_BLOCK_IOTUNE_SET_##BOOL; \
20402 if (virTypedParamsAddULLong(&eventParams, &eventNparams, \
20404 VIR_DOMAIN_TUNABLE_BLKDEV_##CONST, \
20405 param->value.ul) < 0) \
20410 for (i
= 0; i
< nparams
; i
++) {
20411 virTypedParameterPtr param
= ¶ms
[i
];
20413 if (param
->value
.ul
> QEMU_BLOCK_IOTUNE_MAX
) {
20414 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
,
20415 _("block I/O throttle limit value must"
20416 " be no more than %llu"), QEMU_BLOCK_IOTUNE_MAX
);
20420 SET_IOTUNE_FIELD(total_bytes_sec
, BYTES
, TOTAL_BYTES_SEC
);
20421 SET_IOTUNE_FIELD(read_bytes_sec
, BYTES
, READ_BYTES_SEC
);
20422 SET_IOTUNE_FIELD(write_bytes_sec
, BYTES
, WRITE_BYTES_SEC
);
20423 SET_IOTUNE_FIELD(total_iops_sec
, IOPS
, TOTAL_IOPS_SEC
);
20424 SET_IOTUNE_FIELD(read_iops_sec
, IOPS
, READ_IOPS_SEC
);
20425 SET_IOTUNE_FIELD(write_iops_sec
, IOPS
, WRITE_IOPS_SEC
);
20427 SET_IOTUNE_FIELD(total_bytes_sec_max
, BYTES_MAX
,
20428 TOTAL_BYTES_SEC_MAX
);
20429 SET_IOTUNE_FIELD(read_bytes_sec_max
, BYTES_MAX
,
20430 READ_BYTES_SEC_MAX
);
20431 SET_IOTUNE_FIELD(write_bytes_sec_max
, BYTES_MAX
,
20432 WRITE_BYTES_SEC_MAX
);
20433 SET_IOTUNE_FIELD(total_iops_sec_max
, IOPS_MAX
,
20434 TOTAL_IOPS_SEC_MAX
);
20435 SET_IOTUNE_FIELD(read_iops_sec_max
, IOPS_MAX
,
20436 READ_IOPS_SEC_MAX
);
20437 SET_IOTUNE_FIELD(write_iops_sec_max
, IOPS_MAX
,
20438 WRITE_IOPS_SEC_MAX
);
20439 SET_IOTUNE_FIELD(size_iops_sec
, SIZE_IOPS
, SIZE_IOPS_SEC
);
20441 /* NB: Cannot use macro since this is a value.s not a value.ul */
20442 if (STREQ(param
->field
, VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME
)) {
20443 if (VIR_STRDUP(info
.group_name
, param
->value
.s
) < 0)
20445 set_fields
|= QEMU_BLOCK_IOTUNE_SET_GROUP_NAME
;
20446 if (virTypedParamsAddString(&eventParams
, &eventNparams
,
20448 VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME
,
20449 param
->value
.s
) < 0)
20454 SET_IOTUNE_FIELD(total_bytes_sec_max_length
, BYTES_MAX_LENGTH
,
20455 TOTAL_BYTES_SEC_MAX_LENGTH
);
20456 SET_IOTUNE_FIELD(read_bytes_sec_max_length
, BYTES_MAX_LENGTH
,
20457 READ_BYTES_SEC_MAX_LENGTH
);
20458 SET_IOTUNE_FIELD(write_bytes_sec_max_length
, BYTES_MAX_LENGTH
,
20459 WRITE_BYTES_SEC_MAX_LENGTH
);
20460 SET_IOTUNE_FIELD(total_iops_sec_max_length
, IOPS_MAX_LENGTH
,
20461 TOTAL_IOPS_SEC_MAX_LENGTH
);
20462 SET_IOTUNE_FIELD(read_iops_sec_max_length
, IOPS_MAX_LENGTH
,
20463 READ_IOPS_SEC_MAX_LENGTH
);
20464 SET_IOTUNE_FIELD(write_iops_sec_max_length
, IOPS_MAX_LENGTH
,
20465 WRITE_IOPS_SEC_MAX_LENGTH
);
20468 #undef SET_IOTUNE_FIELD
20470 if ((info
.total_bytes_sec
&& info
.read_bytes_sec
) ||
20471 (info
.total_bytes_sec
&& info
.write_bytes_sec
)) {
20472 virReportError(VIR_ERR_INVALID_ARG
, "%s",
20473 _("total and read/write of bytes_sec "
20474 "cannot be set at the same time"));
20478 if ((info
.total_iops_sec
&& info
.read_iops_sec
) ||
20479 (info
.total_iops_sec
&& info
.write_iops_sec
)) {
20480 virReportError(VIR_ERR_INVALID_ARG
, "%s",
20481 _("total and read/write of iops_sec "
20482 "cannot be set at the same time"));
20486 if ((info
.total_bytes_sec_max
&& info
.read_bytes_sec_max
) ||
20487 (info
.total_bytes_sec_max
&& info
.write_bytes_sec_max
)) {
20488 virReportError(VIR_ERR_INVALID_ARG
, "%s",
20489 _("total and read/write of bytes_sec_max "
20490 "cannot be set at the same time"));
20494 if ((info
.total_iops_sec_max
&& info
.read_iops_sec_max
) ||
20495 (info
.total_iops_sec_max
&& info
.write_iops_sec_max
)) {
20496 virReportError(VIR_ERR_INVALID_ARG
, "%s",
20497 _("total and read/write of iops_sec_max "
20498 "cannot be set at the same time"));
20503 supportMaxOptions
= virQEMUCapsGet(priv
->qemuCaps
,
20504 QEMU_CAPS_DRIVE_IOTUNE_MAX
);
20505 supportGroupNameOption
= virQEMUCapsGet(priv
->qemuCaps
,
20506 QEMU_CAPS_DRIVE_IOTUNE_GROUP
);
20507 supportMaxLengthOptions
=
20508 virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DRIVE_IOTUNE_MAX_LENGTH
);
20510 if (!supportMaxOptions
&&
20511 (set_fields
& (QEMU_BLOCK_IOTUNE_SET_BYTES_MAX
|
20512 QEMU_BLOCK_IOTUNE_SET_IOPS_MAX
|
20513 QEMU_BLOCK_IOTUNE_SET_SIZE_IOPS
))) {
20514 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
20515 _("a block I/O throttling parameter is not "
20516 "supported with this QEMU binary"));
20520 if (!supportGroupNameOption
&&
20521 (set_fields
& QEMU_BLOCK_IOTUNE_SET_GROUP_NAME
)) {
20522 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
20523 _("the block I/O throttling group parameter is not "
20524 "supported with this QEMU binary"));
20528 if (!supportMaxLengthOptions
&&
20529 (set_fields
& (QEMU_BLOCK_IOTUNE_SET_BYTES_MAX_LENGTH
|
20530 QEMU_BLOCK_IOTUNE_SET_IOPS_MAX_LENGTH
))) {
20531 virReportError(VIR_ERR_CONFIG_UNSUPPORTED
, "%s",
20532 _("a block I/O throttling length parameter is not "
20533 "supported with this QEMU binary"));
20537 if (!(disk
= qemuDomainDiskByName(def
, path
)))
20540 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
)) {
20541 qdevid
= QEMU_DOMAIN_DISK_PRIVATE(disk
)->qomName
;
20543 if (!(drivealias
= qemuAliasDiskDriveFromDisk(disk
)))
20547 if (qemuDomainSetBlockIoTuneDefaults(&info
, &disk
->blkdeviotune
,
20551 #define CHECK_MAX(val, _bool) \
20553 if (info.val##_max) { \
20555 if (QEMU_BLOCK_IOTUNE_SET_##_bool) { \
20556 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
20557 _("cannot reset '%s' when " \
20559 #val, #val "_max"); \
20561 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
20562 _("value '%s' cannot be set if " \
20563 "'%s' is not set"), \
20564 #val "_max", #val); \
20568 if (info.val##_max < info.val) { \
20569 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
20570 _("value '%s' cannot be " \
20571 "smaller than '%s'"), \
20572 #val "_max", #val); \
20578 CHECK_MAX(total_bytes_sec
, BYTES
);
20579 CHECK_MAX(read_bytes_sec
, BYTES
);
20580 CHECK_MAX(write_bytes_sec
, BYTES
);
20581 CHECK_MAX(total_iops_sec
, IOPS
);
20582 CHECK_MAX(read_iops_sec
, IOPS
);
20583 CHECK_MAX(write_iops_sec
, IOPS
);
20587 /* NB: Let's let QEMU decide how to handle issues with _length
20588 * via the JSON error code from the block_set_io_throttle call */
20590 qemuDomainObjEnterMonitor(driver
, vm
);
20591 ret
= qemuMonitorSetBlockIoThrottle(priv
->mon
, drivealias
, qdevid
,
20592 &info
, supportMaxOptions
,
20593 set_fields
& QEMU_BLOCK_IOTUNE_SET_GROUP_NAME
,
20594 supportMaxLengthOptions
);
20595 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
20601 if (virDomainDiskSetBlockIOTune(disk
, &info
) < 0)
20604 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
,
20605 vm
, driver
->caps
) < 0)
20608 if (eventNparams
) {
20609 event
= virDomainEventTunableNewFromDom(dom
, eventParams
, eventNparams
);
20611 virObjectEventStateQueue(driver
->domainEventState
, event
);
20615 if (persistentDef
) {
20616 if (!(conf_disk
= virDomainDiskByName(persistentDef
, path
, true))) {
20617 virReportError(VIR_ERR_INVALID_ARG
,
20618 _("missing persistent configuration for disk '%s'"),
20623 if (qemuDomainSetBlockIoTuneDefaults(&info
, &conf_disk
->blkdeviotune
,
20627 if (virDomainDiskSetBlockIOTune(conf_disk
, &info
) < 0)
20630 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
20631 persistentDef
) < 0)
20637 qemuDomainObjEndJob(driver
, vm
);
20640 VIR_FREE(info
.group_name
);
20641 VIR_FREE(drivealias
);
20642 virDomainObjEndAPI(&vm
);
20644 virTypedParamsFree(eventParams
, eventNparams
);
20645 virObjectUnref(cfg
);
20650 qemuDomainGetBlockIoTune(virDomainPtr dom
,
20652 virTypedParameterPtr params
,
20654 unsigned int flags
)
20656 virDomainDiskDefPtr disk
;
20657 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20658 virDomainObjPtr vm
= NULL
;
20659 qemuDomainObjPrivatePtr priv
= NULL
;
20660 virDomainDefPtr def
= NULL
;
20661 virDomainDefPtr persistentDef
= NULL
;
20662 virDomainBlockIoTuneInfo reply
= {0};
20663 char *drivealias
= NULL
;
20664 const char *qdevid
= NULL
;
20668 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
20669 VIR_DOMAIN_AFFECT_CONFIG
|
20670 VIR_TYPED_PARAM_STRING_OKAY
, -1);
20672 /* We don't return strings, and thus trivially support this flag. */
20673 flags
&= ~VIR_TYPED_PARAM_STRING_OKAY
;
20675 if (!(vm
= qemuDomObjFromDomain(dom
)))
20678 priv
= vm
->privateData
;
20680 if (virDomainGetBlockIoTuneEnsureACL(dom
->conn
, vm
->def
) < 0)
20683 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
20686 /* the API check guarantees that only one of the definitions will be set */
20687 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
20691 /* If the VM is running, we can check if the current VM can use
20692 * optional parameters or not. */
20693 maxparams
= QEMU_NB_BLOCK_IO_TUNE_BASE_PARAMS
;
20694 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DRIVE_IOTUNE_MAX
))
20695 maxparams
+= QEMU_NB_BLOCK_IO_TUNE_MAX_PARAMS
;
20696 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DRIVE_IOTUNE_GROUP
))
20697 maxparams
+= QEMU_NB_BLOCK_IO_TUNE_GROUP_PARAMS
;
20698 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_DRIVE_IOTUNE_MAX_LENGTH
))
20699 maxparams
+= QEMU_NB_BLOCK_IO_TUNE_LENGTH_PARAMS
;
20701 maxparams
= QEMU_NB_BLOCK_IO_TUNE_ALL_PARAMS
;
20704 if (*nparams
== 0) {
20705 *nparams
= maxparams
;
20708 } else if (*nparams
< maxparams
) {
20709 maxparams
= *nparams
;
20715 if (!(disk
= qemuDomainDiskByName(def
, path
)))
20718 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
)) {
20719 qdevid
= QEMU_DOMAIN_DISK_PRIVATE(disk
)->qomName
;
20721 if (!(drivealias
= qemuAliasDiskDriveFromDisk(disk
)))
20724 qemuDomainObjEnterMonitor(driver
, vm
);
20725 ret
= qemuMonitorGetBlockIoThrottle(priv
->mon
, drivealias
, qdevid
, &reply
);
20726 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
20732 if (persistentDef
) {
20733 if (!(disk
= virDomainDiskByName(persistentDef
, path
, true))) {
20734 virReportError(VIR_ERR_INVALID_ARG
,
20735 _("disk '%s' was not found in the domain config"),
20739 reply
= disk
->blkdeviotune
;
20741 /* Group name needs to be copied since qemuMonitorGetBlockIoThrottle
20742 * allocates it as well */
20743 if (VIR_STRDUP(reply
.group_name
, disk
->blkdeviotune
.group_name
) < 0)
20747 #define BLOCK_IOTUNE_ASSIGN(name, var) \
20748 if (*nparams < maxparams && \
20749 virTypedParameterAssign(¶ms[(*nparams)++], \
20750 VIR_DOMAIN_BLOCK_IOTUNE_ ## name, \
20751 VIR_TYPED_PARAM_ULLONG, \
20756 BLOCK_IOTUNE_ASSIGN(TOTAL_BYTES_SEC
, total_bytes_sec
);
20757 BLOCK_IOTUNE_ASSIGN(READ_BYTES_SEC
, read_bytes_sec
);
20758 BLOCK_IOTUNE_ASSIGN(WRITE_BYTES_SEC
, write_bytes_sec
);
20760 BLOCK_IOTUNE_ASSIGN(TOTAL_IOPS_SEC
, total_iops_sec
);
20761 BLOCK_IOTUNE_ASSIGN(READ_IOPS_SEC
, read_iops_sec
);
20762 BLOCK_IOTUNE_ASSIGN(WRITE_IOPS_SEC
, write_iops_sec
);
20764 BLOCK_IOTUNE_ASSIGN(TOTAL_BYTES_SEC_MAX
, total_bytes_sec_max
);
20765 BLOCK_IOTUNE_ASSIGN(READ_BYTES_SEC_MAX
, read_bytes_sec_max
);
20766 BLOCK_IOTUNE_ASSIGN(WRITE_BYTES_SEC_MAX
, write_bytes_sec_max
);
20768 BLOCK_IOTUNE_ASSIGN(TOTAL_IOPS_SEC_MAX
, total_iops_sec_max
);
20769 BLOCK_IOTUNE_ASSIGN(READ_IOPS_SEC_MAX
, read_iops_sec_max
);
20770 BLOCK_IOTUNE_ASSIGN(WRITE_IOPS_SEC_MAX
, write_iops_sec_max
);
20772 BLOCK_IOTUNE_ASSIGN(SIZE_IOPS_SEC
, size_iops_sec
);
20774 if (*nparams
< maxparams
) {
20775 if (virTypedParameterAssign(¶ms
[(*nparams
)++],
20776 VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME
,
20777 VIR_TYPED_PARAM_STRING
,
20778 reply
.group_name
) < 0)
20781 reply
.group_name
= NULL
;
20784 BLOCK_IOTUNE_ASSIGN(TOTAL_BYTES_SEC_MAX_LENGTH
, total_bytes_sec_max_length
);
20785 BLOCK_IOTUNE_ASSIGN(READ_BYTES_SEC_MAX_LENGTH
, read_bytes_sec_max_length
);
20786 BLOCK_IOTUNE_ASSIGN(WRITE_BYTES_SEC_MAX_LENGTH
, write_bytes_sec_max_length
);
20788 BLOCK_IOTUNE_ASSIGN(TOTAL_IOPS_SEC_MAX_LENGTH
, total_iops_sec_max_length
);
20789 BLOCK_IOTUNE_ASSIGN(READ_IOPS_SEC_MAX_LENGTH
, read_iops_sec_max_length
);
20790 BLOCK_IOTUNE_ASSIGN(WRITE_IOPS_SEC_MAX_LENGTH
, write_iops_sec_max_length
);
20791 #undef BLOCK_IOTUNE_ASSIGN
20796 qemuDomainObjEndJob(driver
, vm
);
20799 VIR_FREE(reply
.group_name
);
20800 VIR_FREE(drivealias
);
20801 virDomainObjEndAPI(&vm
);
20806 qemuDomainGetDiskErrors(virDomainPtr dom
,
20807 virDomainDiskErrorPtr errors
,
20808 unsigned int nerrors
,
20809 unsigned int flags
)
20811 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20812 virDomainObjPtr vm
= NULL
;
20813 qemuDomainObjPrivatePtr priv
;
20814 virHashTablePtr table
= NULL
;
20815 bool blockdev
= false;
20820 virCheckFlags(0, -1);
20822 if (!(vm
= qemuDomObjFromDomain(dom
)))
20825 priv
= vm
->privateData
;
20826 blockdev
= virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
);
20828 if (virDomainGetDiskErrorsEnsureACL(dom
->conn
, vm
->def
) < 0)
20831 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
20834 if (virDomainObjCheckActive(vm
) < 0)
20838 ret
= vm
->def
->ndisks
;
20842 qemuDomainObjEnterMonitor(driver
, vm
);
20843 table
= qemuMonitorGetBlockInfo(priv
->mon
);
20844 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
20849 for (i
= n
= 0; i
< vm
->def
->ndisks
; i
++) {
20850 struct qemuDomainDiskInfo
*info
;
20851 virDomainDiskDefPtr disk
= vm
->def
->disks
[i
];
20852 qemuDomainDiskPrivatePtr diskPriv
= QEMU_DOMAIN_DISK_PRIVATE(disk
);
20853 const char *entryname
= disk
->info
.alias
;
20856 entryname
= diskPriv
->qomName
;
20858 if ((info
= virHashLookup(table
, entryname
)) &&
20859 info
->io_status
!= VIR_DOMAIN_DISK_ERROR_NONE
) {
20863 if (VIR_STRDUP(errors
[n
].disk
, disk
->dst
) < 0)
20865 errors
[n
].error
= info
->io_status
;
20873 qemuDomainObjEndJob(driver
, vm
);
20876 virDomainObjEndAPI(&vm
);
20877 virHashFree(table
);
20879 for (i
= 0; i
< n
; i
++)
20880 VIR_FREE(errors
[i
].disk
);
20886 qemuDomainSetMetadata(virDomainPtr dom
,
20888 const char *metadata
,
20891 unsigned int flags
)
20893 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
20894 virDomainObjPtr vm
;
20895 virQEMUDriverConfigPtr cfg
= NULL
;
20896 virCapsPtr caps
= NULL
;
20899 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
20900 VIR_DOMAIN_AFFECT_CONFIG
, -1);
20902 if (!(vm
= qemuDomObjFromDomain(dom
)))
20905 cfg
= virQEMUDriverGetConfig(driver
);
20907 if (virDomainSetMetadataEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
20910 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
20913 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
20916 ret
= virDomainObjSetMetadata(vm
, type
, metadata
, key
, uri
, caps
,
20917 driver
->xmlopt
, cfg
->stateDir
,
20918 cfg
->configDir
, flags
);
20921 virObjectEventPtr ev
= NULL
;
20922 ev
= virDomainEventMetadataChangeNewFromObj(vm
, type
, uri
);
20923 virObjectEventStateQueue(driver
->domainEventState
, ev
);
20926 qemuDomainObjEndJob(driver
, vm
);
20929 virDomainObjEndAPI(&vm
);
20930 virObjectUnref(caps
);
20931 virObjectUnref(cfg
);
20936 qemuDomainGetMetadata(virDomainPtr dom
,
20939 unsigned int flags
)
20941 virDomainObjPtr vm
;
20944 if (!(vm
= qemuDomObjFromDomain(dom
)))
20947 if (virDomainGetMetadataEnsureACL(dom
->conn
, vm
->def
) < 0)
20950 ret
= virDomainObjGetMetadata(vm
, type
, uri
, flags
);
20953 virDomainObjEndAPI(&vm
);
20959 qemuDomainGetCPUStats(virDomainPtr domain
,
20960 virTypedParameterPtr params
,
20961 unsigned int nparams
,
20963 unsigned int ncpus
,
20964 unsigned int flags
)
20966 virDomainObjPtr vm
= NULL
;
20968 qemuDomainObjPrivatePtr priv
;
20969 virBitmapPtr guestvcpus
= NULL
;
20971 virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY
, -1);
20973 if (!(vm
= qemuDomObjFromDomain(domain
)))
20976 priv
= vm
->privateData
;
20978 if (virDomainGetCPUStatsEnsureACL(domain
->conn
, vm
->def
) < 0)
20981 if (virDomainObjCheckActive(vm
) < 0)
20984 if (!virCgroupHasController(priv
->cgroup
, VIR_CGROUP_CONTROLLER_CPUACCT
)) {
20985 virReportError(VIR_ERR_OPERATION_INVALID
,
20986 "%s", _("cgroup CPUACCT controller is not mounted"));
20990 if (qemuDomainHasVcpuPids(vm
) &&
20991 !(guestvcpus
= virDomainDefGetOnlineVcpumap(vm
->def
)))
20994 if (start_cpu
== -1)
20995 ret
= virCgroupGetDomainTotalCpuStats(priv
->cgroup
,
20998 ret
= virCgroupGetPercpuStats(priv
->cgroup
, params
, nparams
,
20999 start_cpu
, ncpus
, guestvcpus
);
21001 virBitmapFree(guestvcpus
);
21002 virDomainObjEndAPI(&vm
);
21007 qemuDomainPMSuspendForDuration(virDomainPtr dom
,
21008 unsigned int target
,
21009 unsigned long long duration
,
21010 unsigned int flags
)
21012 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21013 virDomainObjPtr vm
;
21014 qemuAgentPtr agent
;
21017 virCheckFlags(0, -1);
21020 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
21021 _("Duration not supported. Use 0 for now"));
21025 if (!(target
== VIR_NODE_SUSPEND_TARGET_MEM
||
21026 target
== VIR_NODE_SUSPEND_TARGET_DISK
||
21027 target
== VIR_NODE_SUSPEND_TARGET_HYBRID
)) {
21028 virReportError(VIR_ERR_INVALID_ARG
,
21029 _("Unknown suspend target: %u"),
21034 if (!(vm
= qemuDomObjFromDomain(dom
)))
21037 if (virDomainPMSuspendForDurationEnsureACL(dom
->conn
, vm
->def
) < 0)
21040 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
21043 if (virDomainObjCheckActive(vm
) < 0)
21046 if (vm
->def
->pm
.s3
|| vm
->def
->pm
.s4
) {
21047 if (vm
->def
->pm
.s3
== VIR_TRISTATE_BOOL_NO
&&
21048 (target
== VIR_NODE_SUSPEND_TARGET_MEM
||
21049 target
== VIR_NODE_SUSPEND_TARGET_HYBRID
)) {
21050 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
21051 _("S3 state is disabled for this domain"));
21055 if (vm
->def
->pm
.s4
== VIR_TRISTATE_BOOL_NO
&&
21056 target
== VIR_NODE_SUSPEND_TARGET_DISK
) {
21057 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
21058 _("S4 state is disabled for this domain"));
21063 if (!qemuDomainAgentAvailable(vm
, true))
21066 agent
= qemuDomainObjEnterAgent(vm
);
21067 ret
= qemuAgentSuspend(agent
, target
);
21068 qemuDomainObjExitAgent(vm
, agent
);
21071 qemuDomainObjEndAgentJob(vm
);
21074 virDomainObjEndAPI(&vm
);
21079 qemuDomainPMWakeup(virDomainPtr dom
,
21080 unsigned int flags
)
21082 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21083 virDomainObjPtr vm
;
21085 qemuDomainObjPrivatePtr priv
;
21087 virCheckFlags(0, -1);
21089 if (!(vm
= qemuDomObjFromDomain(dom
)))
21092 if (virDomainPMWakeupEnsureACL(dom
->conn
, vm
->def
) < 0)
21095 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
21098 if (virDomainObjCheckActive(vm
) < 0)
21101 priv
= vm
->privateData
;
21103 qemuDomainObjEnterMonitor(driver
, vm
);
21104 ret
= qemuMonitorSystemWakeup(priv
->mon
);
21105 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
21109 qemuDomainObjEndJob(driver
, vm
);
21112 virDomainObjEndAPI(&vm
);
21117 qemuConnectListAllDomains(virConnectPtr conn
,
21118 virDomainPtr
**domains
,
21119 unsigned int flags
)
21121 virQEMUDriverPtr driver
= conn
->privateData
;
21124 virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL
, -1);
21126 if (virConnectListAllDomainsEnsureACL(conn
) < 0)
21129 ret
= virDomainObjListExport(driver
->domains
, conn
, domains
,
21130 virConnectListAllDomainsCheckACL
, flags
);
21137 qemuDomainQemuAgentCommand(virDomainPtr domain
,
21140 unsigned int flags
)
21142 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
21143 virDomainObjPtr vm
;
21145 char *result
= NULL
;
21146 qemuAgentPtr agent
;
21148 virCheckFlags(0, NULL
);
21150 if (!(vm
= qemuDomObjFromDomain(domain
)))
21153 if (virDomainQemuAgentCommandEnsureACL(domain
->conn
, vm
->def
) < 0)
21156 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
21159 if (virDomainObjCheckActive(vm
) < 0)
21162 if (!qemuDomainAgentAvailable(vm
, true))
21165 qemuDomainObjTaint(driver
, vm
, VIR_DOMAIN_TAINT_CUSTOM_GA_COMMAND
, NULL
);
21167 agent
= qemuDomainObjEnterAgent(vm
);
21168 ret
= qemuAgentArbitraryCommand(agent
, cmd
, &result
, timeout
);
21169 qemuDomainObjExitAgent(vm
, agent
);
21174 qemuDomainObjEndAgentJob(vm
);
21177 virDomainObjEndAPI(&vm
);
21183 qemuConnectDomainQemuMonitorEventRegister(virConnectPtr conn
,
21186 virConnectDomainQemuMonitorEventCallback callback
,
21188 virFreeCallback freecb
,
21189 unsigned int flags
)
21191 virQEMUDriverPtr driver
= conn
->privateData
;
21194 if (virConnectDomainQemuMonitorEventRegisterEnsureACL(conn
) < 0)
21197 if (virDomainQemuMonitorEventStateRegisterID(conn
,
21198 driver
->domainEventState
,
21199 dom
, event
, callback
,
21200 opaque
, freecb
, flags
,
21210 qemuConnectDomainQemuMonitorEventDeregister(virConnectPtr conn
,
21213 virQEMUDriverPtr driver
= conn
->privateData
;
21216 if (virConnectDomainQemuMonitorEventDeregisterEnsureACL(conn
) < 0)
21219 if (virObjectEventStateDeregisterID(conn
, driver
->domainEventState
,
21220 callbackID
, true) < 0)
21231 qemuDomainFSTrim(virDomainPtr dom
,
21232 const char *mountPoint
,
21233 unsigned long long minimum
,
21234 unsigned int flags
)
21236 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21237 virDomainObjPtr vm
;
21238 qemuAgentPtr agent
;
21241 virCheckFlags(0, -1);
21244 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
21245 _("Specifying mount point "
21246 "is not supported for now"));
21250 if (!(vm
= qemuDomObjFromDomain(dom
)))
21253 if (virDomainFSTrimEnsureACL(dom
->conn
, vm
->def
) < 0)
21256 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
21259 if (!qemuDomainAgentAvailable(vm
, true))
21262 if (virDomainObjCheckActive(vm
) < 0)
21265 agent
= qemuDomainObjEnterAgent(vm
);
21266 ret
= qemuAgentFSTrim(agent
, minimum
);
21267 qemuDomainObjExitAgent(vm
, agent
);
21270 qemuDomainObjEndAgentJob(vm
);
21273 virDomainObjEndAPI(&vm
);
21279 qemuNodeGetInfo(virConnectPtr conn
,
21280 virNodeInfoPtr nodeinfo
)
21282 if (virNodeGetInfoEnsureACL(conn
) < 0)
21285 return virCapabilitiesGetNodeInfo(nodeinfo
);
21290 qemuNodeGetCPUStats(virConnectPtr conn
,
21292 virNodeCPUStatsPtr params
,
21294 unsigned int flags
)
21296 if (virNodeGetCPUStatsEnsureACL(conn
) < 0)
21299 return virHostCPUGetStats(cpuNum
, params
, nparams
, flags
);
21304 qemuNodeGetMemoryStats(virConnectPtr conn
,
21306 virNodeMemoryStatsPtr params
,
21308 unsigned int flags
)
21310 if (virNodeGetMemoryStatsEnsureACL(conn
) < 0)
21313 return virHostMemGetStats(cellNum
, params
, nparams
, flags
);
21318 qemuNodeGetCellsFreeMemory(virConnectPtr conn
,
21319 unsigned long long *freeMems
,
21323 if (virNodeGetCellsFreeMemoryEnsureACL(conn
) < 0)
21326 return virHostMemGetCellsFree(freeMems
, startCell
, maxCells
);
21330 static unsigned long long
21331 qemuNodeGetFreeMemory(virConnectPtr conn
)
21333 unsigned long long freeMem
;
21335 if (virNodeGetFreeMemoryEnsureACL(conn
) < 0)
21338 if (virHostMemGetInfo(NULL
, &freeMem
) < 0)
21346 qemuNodeGetMemoryParameters(virConnectPtr conn
,
21347 virTypedParameterPtr params
,
21349 unsigned int flags
)
21351 if (virNodeGetMemoryParametersEnsureACL(conn
) < 0)
21354 return virHostMemGetParameters(params
, nparams
, flags
);
21359 qemuNodeSetMemoryParameters(virConnectPtr conn
,
21360 virTypedParameterPtr params
,
21362 unsigned int flags
)
21364 if (virNodeSetMemoryParametersEnsureACL(conn
) < 0)
21367 return virHostMemSetParameters(params
, nparams
, flags
);
21372 qemuNodeGetCPUMap(virConnectPtr conn
,
21373 unsigned char **cpumap
,
21374 unsigned int *online
,
21375 unsigned int flags
)
21377 if (virNodeGetCPUMapEnsureACL(conn
) < 0)
21380 return virHostCPUGetMap(cpumap
, online
, flags
);
21385 qemuNodeSuspendForDuration(virConnectPtr conn
,
21386 unsigned int target
,
21387 unsigned long long duration
,
21388 unsigned int flags
)
21390 if (virNodeSuspendForDurationEnsureACL(conn
) < 0)
21393 return virNodeSuspend(target
, duration
, flags
);
21397 qemuConnectGetCPUModelNames(virConnectPtr conn
,
21398 const char *archName
,
21400 unsigned int flags
)
21404 virCheckFlags(0, -1);
21405 if (virConnectGetCPUModelNamesEnsureACL(conn
) < 0)
21408 if (!(arch
= virArchFromString(archName
))) {
21409 virReportError(VIR_ERR_INVALID_ARG
,
21410 _("cannot find architecture %s"),
21415 return virCPUGetModels(arch
, models
);
21420 qemuDomainGetHostname(virDomainPtr dom
,
21421 unsigned int flags
)
21423 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21424 virDomainObjPtr vm
= NULL
;
21425 qemuAgentPtr agent
;
21426 char *hostname
= NULL
;
21428 virCheckFlags(0, NULL
);
21430 if (!(vm
= qemuDomObjFromDomain(dom
)))
21433 if (virDomainGetHostnameEnsureACL(dom
->conn
, vm
->def
) < 0)
21436 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
21439 if (virDomainObjCheckActive(vm
) < 0)
21442 if (!qemuDomainAgentAvailable(vm
, true))
21445 agent
= qemuDomainObjEnterAgent(vm
);
21446 ignore_value(qemuAgentGetHostname(agent
, &hostname
));
21447 qemuDomainObjExitAgent(vm
, agent
);
21450 qemuDomainObjEndAgentJob(vm
);
21453 virDomainObjEndAPI(&vm
);
21459 qemuDomainGetTime(virDomainPtr dom
,
21460 long long *seconds
,
21461 unsigned int *nseconds
,
21462 unsigned int flags
)
21464 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21465 virDomainObjPtr vm
= NULL
;
21466 qemuAgentPtr agent
;
21470 virCheckFlags(0, ret
);
21472 if (!(vm
= qemuDomObjFromDomain(dom
)))
21475 if (virDomainGetTimeEnsureACL(dom
->conn
, vm
->def
) < 0)
21478 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
21481 if (virDomainObjCheckActive(vm
) < 0)
21484 if (!qemuDomainAgentAvailable(vm
, true))
21487 agent
= qemuDomainObjEnterAgent(vm
);
21488 rv
= qemuAgentGetTime(agent
, seconds
, nseconds
);
21489 qemuDomainObjExitAgent(vm
, agent
);
21497 qemuDomainObjEndAgentJob(vm
);
21500 virDomainObjEndAPI(&vm
);
21506 qemuDomainSetTime(virDomainPtr dom
,
21508 unsigned int nseconds
,
21509 unsigned int flags
)
21511 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21512 qemuDomainObjPrivatePtr priv
;
21513 virDomainObjPtr vm
;
21514 qemuAgentPtr agent
;
21515 bool rtcSync
= flags
& VIR_DOMAIN_TIME_SYNC
;
21519 virCheckFlags(VIR_DOMAIN_TIME_SYNC
, ret
);
21521 if (!(vm
= qemuDomObjFromDomain(dom
)))
21524 if (virDomainSetTimeEnsureACL(dom
->conn
, vm
->def
) < 0)
21527 priv
= vm
->privateData
;
21529 if (qemuDomainObjBeginJobWithAgent(driver
, vm
,
21531 QEMU_AGENT_JOB_MODIFY
) < 0)
21534 if (virDomainObjCheckActive(vm
) < 0)
21537 /* On x86, the rtc-reset-reinjection QMP command must be called after
21538 * setting the time to avoid trouble down the line. If the command is
21539 * not available, don't set the time at all and report an error */
21540 if (ARCH_IS_X86(vm
->def
->os
.arch
) &&
21541 !virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_RTC_RESET_REINJECTION
))
21543 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
21544 _("cannot set time: qemu doesn't support "
21545 "rtc-reset-reinjection command"));
21549 if (!qemuDomainAgentAvailable(vm
, true))
21552 agent
= qemuDomainObjEnterAgent(vm
);
21553 rv
= qemuAgentSetTime(agent
, seconds
, nseconds
, rtcSync
);
21554 qemuDomainObjExitAgent(vm
, agent
);
21559 if (virDomainObjCheckActive(vm
) < 0)
21562 /* Don't try to call rtc-reset-reinjection if it's not available */
21563 if (virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_RTC_RESET_REINJECTION
)) {
21564 qemuDomainObjEnterMonitor(driver
, vm
);
21565 rv
= qemuMonitorRTCResetReinjection(priv
->mon
);
21566 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
21576 qemuDomainObjEndJobWithAgent(driver
, vm
);
21579 virDomainObjEndAPI(&vm
);
21585 qemuDomainFSFreeze(virDomainPtr dom
,
21586 const char **mountpoints
,
21587 unsigned int nmountpoints
,
21588 unsigned int flags
)
21590 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21591 virDomainObjPtr vm
;
21594 virCheckFlags(0, -1);
21596 if (!(vm
= qemuDomObjFromDomain(dom
)))
21599 if (virDomainFSFreezeEnsureACL(dom
->conn
, vm
->def
) < 0)
21602 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
21605 if (virDomainObjCheckActive(vm
) < 0)
21608 ret
= qemuDomainSnapshotFSFreeze(driver
, vm
, mountpoints
, nmountpoints
);
21611 qemuDomainObjEndAgentJob(vm
);
21614 virDomainObjEndAPI(&vm
);
21620 qemuDomainFSThaw(virDomainPtr dom
,
21621 const char **mountpoints
,
21622 unsigned int nmountpoints
,
21623 unsigned int flags
)
21625 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
21626 virDomainObjPtr vm
;
21629 virCheckFlags(0, -1);
21631 if (mountpoints
|| nmountpoints
) {
21632 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
, "%s",
21633 _("specifying mountpoints is not supported"));
21637 if (!(vm
= qemuDomObjFromDomain(dom
)))
21640 if (virDomainFSThawEnsureACL(dom
->conn
, vm
->def
) < 0)
21643 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
21646 if (virDomainObjCheckActive(vm
) < 0)
21649 ret
= qemuDomainSnapshotFSThaw(driver
, vm
, true);
21652 qemuDomainObjEndAgentJob(vm
);
21655 virDomainObjEndAPI(&vm
);
21661 qemuNodeGetFreePages(virConnectPtr conn
,
21662 unsigned int npages
,
21663 unsigned int *pages
,
21665 unsigned int cellCount
,
21666 unsigned long long *counts
,
21667 unsigned int flags
)
21669 virCheckFlags(0, -1);
21671 if (virNodeGetFreePagesEnsureACL(conn
) < 0)
21674 return virHostMemGetFreePages(npages
, pages
, startCell
, cellCount
, counts
);
21679 qemuConnectGetDomainCapabilities(virConnectPtr conn
,
21680 const char *emulatorbin
,
21681 const char *arch_str
,
21682 const char *machine
,
21683 const char *virttype_str
,
21684 unsigned int flags
)
21687 virQEMUDriverPtr driver
= conn
->privateData
;
21688 virQEMUCapsPtr qemuCaps
= NULL
;
21690 virDomainVirtType virttype
;
21691 virDomainCapsPtr domCaps
= NULL
;
21692 virQEMUDriverConfigPtr cfg
= NULL
;
21693 virCapsPtr caps
= NULL
;
21695 virCheckFlags(0, ret
);
21697 if (virConnectGetDomainCapabilitiesEnsureACL(conn
) < 0)
21700 cfg
= virQEMUDriverGetConfig(driver
);
21702 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
21705 qemuCaps
= virQEMUCapsCacheLookupDefault(driver
->qemuCapsCache
,
21710 &arch
, &virttype
, &machine
);
21714 if (!(domCaps
= virDomainCapsNew(virQEMUCapsGetBinary(qemuCaps
), machine
,
21718 if (virQEMUCapsFillDomainCaps(caps
, domCaps
, qemuCaps
,
21719 cfg
->firmwares
, cfg
->nfirmwares
) < 0)
21722 ret
= virDomainCapsFormat(domCaps
);
21724 virObjectUnref(cfg
);
21725 virObjectUnref(caps
);
21726 virObjectUnref(domCaps
);
21727 virObjectUnref(qemuCaps
);
21733 qemuDomainGetStatsState(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
21734 virDomainObjPtr dom
,
21735 virDomainStatsRecordPtr record
,
21737 unsigned int privflags ATTRIBUTE_UNUSED
)
21739 if (virTypedParamsAddInt(&record
->params
,
21743 dom
->state
.state
) < 0)
21746 if (virTypedParamsAddInt(&record
->params
,
21750 dom
->state
.reason
) < 0)
21758 QEMU_DOMAIN_STATS_HAVE_JOB
= 1 << 0, /* job is entered, monitor can be
21760 QEMU_DOMAIN_STATS_BACKING
= 1 << 1, /* include backing chain in
21762 } qemuDomainStatsFlags
;
21765 #define HAVE_JOB(flags) ((flags) & QEMU_DOMAIN_STATS_HAVE_JOB)
21768 typedef struct _virQEMUResctrlMonData virQEMUResctrlMonData
;
21769 typedef virQEMUResctrlMonData
*virQEMUResctrlMonDataPtr
;
21770 struct _virQEMUResctrlMonData
{
21773 virResctrlMonitorStatsPtr
*stats
;
21779 qemuDomainFreeResctrlMonData(virQEMUResctrlMonDataPtr resdata
)
21781 VIR_FREE(resdata
->name
);
21782 VIR_FREE(resdata
->vcpus
);
21783 virResctrlMonitorFreeStats(resdata
->stats
, resdata
->nstats
);
21789 * qemuDomainGetResctrlMonData:
21790 * @dom: Pointer for the domain that the resctrl monitors reside in
21791 * @resdata: Pointer of virQEMUResctrlMonDataPtr pointer for receiving the
21792 * virQEMUResctrlMonDataPtr array. Caller is responsible for
21793 * freeing the array.
21794 * @nresdata: Pointer of size_t to report the size virQEMUResctrlMonDataPtr
21795 * array to caller. If *@nresdata is not 0, even if function
21796 * returns an error, the caller is also required to call
21797 * qemuDomainFreeResctrlMonData to free each element in the
21798 * *@resdata array and then the array itself.
21799 * @tag: Could be VIR_RESCTRL_MONITOR_TYPE_CACHE for getting cache statistics
21800 * from @dom cache monitors. VIR_RESCTRL_MONITOR_TYPE_MEMBW for
21801 * getting memory bandwidth statistics from memory bandwidth monitors.
21803 * Get cache or memory bandwidth statistics from @dom monitors.
21805 * Returns -1 on failure, or 0 on success.
21808 qemuDomainGetResctrlMonData(virDomainObjPtr dom
,
21809 virQEMUResctrlMonDataPtr
**resdata
,
21811 virResctrlMonitorType tag
)
21813 virDomainResctrlDefPtr resctrl
= NULL
;
21814 virQEMUResctrlMonDataPtr res
= NULL
;
21818 for (i
= 0; i
< dom
->def
->nresctrls
; i
++) {
21819 resctrl
= dom
->def
->resctrls
[i
];
21821 for (j
= 0; j
< resctrl
->nmonitors
; j
++) {
21822 virDomainResctrlMonDefPtr domresmon
= NULL
;
21823 virResctrlMonitorPtr monitor
= NULL
;
21825 domresmon
= resctrl
->monitors
[j
];
21826 monitor
= domresmon
->instance
;
21828 if (domresmon
->tag
!= tag
)
21831 if (VIR_ALLOC(res
) < 0)
21834 /* If virBitmapFormat successfully returns an vcpu string, then
21835 * res.vcpus is assigned with an memory space holding it,
21836 * let this newly allocated memory buffer to be freed along with
21837 * the free of 'res' */
21838 if (!(res
->vcpus
= virBitmapFormat(domresmon
->vcpus
)))
21841 if (VIR_STRDUP(res
->name
, virResctrlMonitorGetID(monitor
)) < 0)
21844 if (virResctrlMonitorGetCacheOccupancy(monitor
,
21849 if (VIR_APPEND_ELEMENT(*resdata
, *nresdata
, res
) < 0)
21857 qemuDomainFreeResctrlMonData(res
);
21863 qemuDomainGetStatsCpuCache(virDomainObjPtr dom
,
21864 virDomainStatsRecordPtr record
,
21867 char param_name
[VIR_TYPED_PARAM_FIELD_LENGTH
];
21868 virQEMUResctrlMonDataPtr
*resdata
= NULL
;
21869 size_t nresdata
= 0;
21874 if (!virDomainObjIsActive(dom
))
21877 if (qemuDomainGetResctrlMonData(dom
, &resdata
, &nresdata
,
21878 VIR_RESCTRL_MONITOR_TYPE_CACHE
) < 0)
21881 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21882 "cpu.cache.monitor.count");
21883 if (virTypedParamsAddUInt(&record
->params
, &record
->nparams
,
21884 maxparams
, param_name
, nresdata
) < 0)
21887 for (i
= 0; i
< nresdata
; i
++) {
21888 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21889 "cpu.cache.monitor.%zu.name", i
);
21890 if (virTypedParamsAddString(&record
->params
,
21894 resdata
[i
]->name
) < 0)
21897 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21898 "cpu.cache.monitor.%zu.vcpus", i
);
21899 if (virTypedParamsAddString(&record
->params
, &record
->nparams
,
21900 maxparams
, param_name
,
21901 resdata
[i
]->vcpus
) < 0)
21904 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21905 "cpu.cache.monitor.%zu.bank.count", i
);
21906 if (virTypedParamsAddUInt(&record
->params
, &record
->nparams
,
21907 maxparams
, param_name
,
21908 resdata
[i
]->nstats
) < 0)
21911 for (j
= 0; j
< resdata
[i
]->nstats
; j
++) {
21912 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21913 "cpu.cache.monitor.%zu.bank.%zu.id", i
, j
);
21914 if (virTypedParamsAddUInt(&record
->params
, &record
->nparams
,
21915 maxparams
, param_name
,
21916 resdata
[i
]->stats
[j
]->id
) < 0)
21919 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
21920 "cpu.cache.monitor.%zu.bank.%zu.bytes", i
, j
);
21921 if (virTypedParamsAddUInt(&record
->params
, &record
->nparams
,
21922 maxparams
, param_name
,
21923 resdata
[i
]->stats
[j
]->val
) < 0)
21930 for (i
= 0; i
< nresdata
; i
++)
21931 qemuDomainFreeResctrlMonData(resdata
[i
]);
21938 qemuDomainGetStatsCpuCgroup(virDomainObjPtr dom
,
21939 virDomainStatsRecordPtr record
,
21942 qemuDomainObjPrivatePtr priv
= dom
->privateData
;
21943 unsigned long long cpu_time
= 0;
21944 unsigned long long user_time
= 0;
21945 unsigned long long sys_time
= 0;
21951 err
= virCgroupGetCpuacctUsage(priv
->cgroup
, &cpu_time
);
21952 if (!err
&& virTypedParamsAddULLong(&record
->params
,
21959 err
= virCgroupGetCpuacctStat(priv
->cgroup
, &user_time
, &sys_time
);
21960 if (!err
&& virTypedParamsAddULLong(&record
->params
,
21966 if (!err
&& virTypedParamsAddULLong(&record
->params
,
21978 qemuDomainGetStatsCpu(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
21979 virDomainObjPtr dom
,
21980 virDomainStatsRecordPtr record
,
21982 unsigned int privflags ATTRIBUTE_UNUSED
)
21984 if (qemuDomainGetStatsCpuCgroup(dom
, record
, maxparams
) < 0)
21987 if (qemuDomainGetStatsCpuCache(dom
, record
, maxparams
) < 0)
21995 qemuDomainGetStatsBalloon(virQEMUDriverPtr driver
,
21996 virDomainObjPtr dom
,
21997 virDomainStatsRecordPtr record
,
21999 unsigned int privflags
)
22001 virDomainMemoryStatStruct stats
[VIR_DOMAIN_MEMORY_STAT_NR
];
22003 unsigned long long cur_balloon
= 0;
22006 if (!virDomainDefHasMemballoon(dom
->def
)) {
22007 cur_balloon
= virDomainDefGetMemoryTotal(dom
->def
);
22009 cur_balloon
= dom
->def
->mem
.cur_balloon
;
22012 if (virTypedParamsAddULLong(&record
->params
,
22019 if (virTypedParamsAddULLong(&record
->params
,
22023 virDomainDefGetMemoryTotal(dom
->def
)) < 0)
22026 if (!HAVE_JOB(privflags
) || !virDomainObjIsActive(dom
))
22029 nr_stats
= qemuDomainMemoryStatsInternal(driver
, dom
, stats
,
22030 VIR_DOMAIN_MEMORY_STAT_NR
);
22034 #define STORE_MEM_RECORD(TAG, NAME) \
22035 if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_ ##TAG) \
22036 if (virTypedParamsAddULLong(&record->params, \
22037 &record->nparams, \
22040 stats[i].val) < 0) \
22043 for (i
= 0; i
< nr_stats
; i
++) {
22044 STORE_MEM_RECORD(SWAP_IN
, "swap_in")
22045 STORE_MEM_RECORD(SWAP_OUT
, "swap_out")
22046 STORE_MEM_RECORD(MAJOR_FAULT
, "major_fault")
22047 STORE_MEM_RECORD(MINOR_FAULT
, "minor_fault")
22048 STORE_MEM_RECORD(UNUSED
, "unused")
22049 STORE_MEM_RECORD(AVAILABLE
, "available")
22050 STORE_MEM_RECORD(RSS
, "rss")
22051 STORE_MEM_RECORD(LAST_UPDATE
, "last-update")
22052 STORE_MEM_RECORD(USABLE
, "usable")
22053 STORE_MEM_RECORD(DISK_CACHES
, "disk_caches")
22056 #undef STORE_MEM_RECORD
22063 qemuDomainGetStatsVcpu(virQEMUDriverPtr driver
,
22064 virDomainObjPtr dom
,
22065 virDomainStatsRecordPtr record
,
22067 unsigned int privflags
)
22069 virDomainVcpuDefPtr vcpu
;
22070 qemuDomainVcpuPrivatePtr vcpupriv
;
22073 char param_name
[VIR_TYPED_PARAM_FIELD_LENGTH
];
22074 virVcpuInfoPtr cpuinfo
= NULL
;
22075 unsigned long long *cpuwait
= NULL
;
22077 if (virTypedParamsAddUInt(&record
->params
,
22081 virDomainDefGetVcpus(dom
->def
)) < 0)
22084 if (virTypedParamsAddUInt(&record
->params
,
22088 virDomainDefGetVcpusMax(dom
->def
)) < 0)
22091 if (VIR_ALLOC_N(cpuinfo
, virDomainDefGetVcpus(dom
->def
)) < 0 ||
22092 VIR_ALLOC_N(cpuwait
, virDomainDefGetVcpus(dom
->def
)) < 0)
22095 if (HAVE_JOB(privflags
) && virDomainObjIsActive(dom
) &&
22096 qemuDomainRefreshVcpuHalted(driver
, dom
, QEMU_ASYNC_JOB_NONE
) < 0) {
22097 /* it's ok to be silent and go ahead, because halted vcpu info
22098 * wasn't here from the beginning */
22099 virResetLastError();
22102 if (qemuDomainHelperGetVcpus(dom
, cpuinfo
, cpuwait
,
22103 virDomainDefGetVcpus(dom
->def
),
22105 virResetLastError();
22106 ret
= 0; /* it's ok to be silent and go ahead */
22110 for (i
= 0; i
< virDomainDefGetVcpus(dom
->def
); i
++) {
22111 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
22112 "vcpu.%u.state", cpuinfo
[i
].number
);
22113 if (virTypedParamsAddInt(&record
->params
,
22117 cpuinfo
[i
].state
) < 0)
22120 /* stats below are available only if the VM is alive */
22121 if (!virDomainObjIsActive(dom
))
22124 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
22125 "vcpu.%u.time", cpuinfo
[i
].number
);
22126 if (virTypedParamsAddULLong(&record
->params
,
22130 cpuinfo
[i
].cpuTime
) < 0)
22132 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
22133 "vcpu.%u.wait", cpuinfo
[i
].number
);
22134 if (virTypedParamsAddULLong(&record
->params
,
22141 /* state below is extracted from the individual vcpu structs */
22142 if (!(vcpu
= virDomainDefGetVcpu(dom
->def
, cpuinfo
[i
].number
)))
22145 vcpupriv
= QEMU_DOMAIN_VCPU_PRIVATE(vcpu
);
22147 if (vcpupriv
->halted
!= VIR_TRISTATE_BOOL_ABSENT
) {
22148 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
,
22149 "vcpu.%u.halted", cpuinfo
[i
].number
);
22150 if (virTypedParamsAddBoolean(&record
->params
,
22154 vcpupriv
->halted
== VIR_TRISTATE_BOOL_YES
) < 0)
22167 #define QEMU_ADD_COUNT_PARAM(record, maxparams, type, count) \
22169 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22170 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "%s.count", type); \
22171 if (virTypedParamsAddUInt(&(record)->params, \
22172 &(record)->nparams, \
22179 #define QEMU_ADD_NAME_PARAM(record, maxparams, type, subtype, num, name) \
22181 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22182 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22183 "%s.%zu.%s", type, num, subtype); \
22184 if (virTypedParamsAddString(&(record)->params, \
22185 &(record)->nparams, \
22192 #define QEMU_ADD_NET_PARAM(record, maxparams, num, name, value) \
22194 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22195 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22196 "net.%zu.%s", num, name); \
22197 if (value >= 0 && virTypedParamsAddULLong(&(record)->params, \
22198 &(record)->nparams, \
22206 qemuDomainGetStatsInterface(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
22207 virDomainObjPtr dom
,
22208 virDomainStatsRecordPtr record
,
22210 unsigned int privflags ATTRIBUTE_UNUSED
)
22213 struct _virDomainInterfaceStats tmp
;
22216 if (!virDomainObjIsActive(dom
))
22219 QEMU_ADD_COUNT_PARAM(record
, maxparams
, "net", dom
->def
->nnets
);
22221 /* Check the path is one of the domain's network interfaces. */
22222 for (i
= 0; i
< dom
->def
->nnets
; i
++) {
22223 virDomainNetDefPtr net
= dom
->def
->nets
[i
];
22224 virDomainNetType actualType
;
22229 memset(&tmp
, 0, sizeof(tmp
));
22231 actualType
= virDomainNetGetActualType(net
);
22233 QEMU_ADD_NAME_PARAM(record
, maxparams
,
22234 "net", "name", i
, net
->ifname
);
22236 if (actualType
== VIR_DOMAIN_NET_TYPE_VHOSTUSER
) {
22237 if (virNetDevOpenvswitchInterfaceStats(net
->ifname
, &tmp
) < 0) {
22238 virResetLastError();
22242 if (virNetDevTapInterfaceStats(net
->ifname
, &tmp
,
22243 !virDomainNetTypeSharesHostView(net
)) < 0) {
22244 virResetLastError();
22249 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
22250 "rx.bytes", tmp
.rx_bytes
);
22251 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
22252 "rx.pkts", tmp
.rx_packets
);
22253 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
22254 "rx.errs", tmp
.rx_errs
);
22255 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
22256 "rx.drop", tmp
.rx_drop
);
22257 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
22258 "tx.bytes", tmp
.tx_bytes
);
22259 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
22260 "tx.pkts", tmp
.tx_packets
);
22261 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
22262 "tx.errs", tmp
.tx_errs
);
22263 QEMU_ADD_NET_PARAM(record
, maxparams
, i
,
22264 "tx.drop", tmp
.tx_drop
);
22272 #undef QEMU_ADD_NET_PARAM
22274 #define QEMU_ADD_BLOCK_PARAM_UI(record, maxparams, num, name, value) \
22276 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22277 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22278 "block.%zu.%s", num, name); \
22279 if (virTypedParamsAddUInt(&(record)->params, \
22280 &(record)->nparams, \
22287 /* expects a LL, but typed parameter must be ULL */
22288 #define QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, num, name, value) \
22290 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22291 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22292 "block.%zu.%s", num, name); \
22293 if (value >= 0 && virTypedParamsAddULLong(&(record)->params, \
22294 &(record)->nparams, \
22301 #define QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, num, name, value) \
22303 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22304 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22305 "block.%zu.%s", num, name); \
22306 if (virTypedParamsAddULLong(&(record)->params, \
22307 &(record)->nparams, \
22314 /* refresh information by opening images on the disk */
22316 qemuDomainGetStatsOneBlockFallback(virQEMUDriverPtr driver
,
22317 virQEMUDriverConfigPtr cfg
,
22318 virDomainObjPtr dom
,
22319 virDomainStatsRecordPtr record
,
22321 virStorageSourcePtr src
,
22326 if (virStorageSourceIsEmpty(src
))
22329 if (qemuStorageLimitsRefresh(driver
, cfg
, dom
, src
) < 0) {
22330 virResetLastError();
22334 if (src
->allocation
)
22335 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22336 "allocation", src
->allocation
);
22338 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22339 "capacity", src
->capacity
);
22341 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22342 "physical", src
->physical
);
22350 * qemuDomainGetStatsOneBlockRefreshNamed:
22351 * @src: disk source structure
22352 * @alias: disk alias
22353 * @stats: hash table containing stats for all disks
22354 * @nodedata: reply containing 'query-named-block-nodes' data
22356 * Refresh disk block stats data (qemuBlockStatsPtr) which are present only
22357 * in the reply of 'query-named-block-nodes' in cases when the data was gathered
22358 * by using query-block originally.
22361 qemuDomainGetStatsOneBlockRefreshNamed(virStorageSourcePtr src
,
22363 virHashTablePtr stats
,
22364 virHashTablePtr nodedata
)
22366 qemuBlockStatsPtr entry
;
22368 virJSONValuePtr data
;
22369 unsigned long long tmp
;
22371 if (!nodedata
|| !src
->nodestorage
)
22374 if (!(entry
= virHashLookup(stats
, alias
)))
22377 if (!(data
= virHashLookup(nodedata
, src
->nodestorage
)))
22380 if (virJSONValueObjectGetNumberUlong(data
, "write_threshold", &tmp
) == 0)
22381 entry
->write_threshold
= tmp
;
22386 qemuDomainGetStatsOneBlock(virQEMUDriverPtr driver
,
22387 virQEMUDriverConfigPtr cfg
,
22388 virDomainObjPtr dom
,
22389 virDomainStatsRecordPtr record
,
22391 const char *entryname
,
22392 virStorageSourcePtr src
,
22394 virHashTablePtr stats
)
22396 qemuBlockStats
*entry
;
22399 /* the VM is offline so we have to go and load the stast from the disk by
22401 if (!virDomainObjIsActive(dom
)) {
22402 ret
= qemuDomainGetStatsOneBlockFallback(driver
, cfg
, dom
, record
,
22403 maxparams
, src
, block_idx
);
22407 /* In case where qemu didn't provide the stats we stop here rather than
22408 * trying to refresh the stats from the disk. Inability to provide stats is
22409 * usually caused by blocked storage so this would make libvirtd hang */
22410 if (!stats
|| !entryname
|| !(entry
= virHashLookup(stats
, entryname
))) {
22415 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22416 "allocation", entry
->wr_highest_offset
);
22418 if (entry
->capacity
)
22419 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22420 "capacity", entry
->capacity
);
22421 if (entry
->physical
) {
22422 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22423 "physical", entry
->physical
);
22425 if (qemuDomainStorageUpdatePhysical(driver
, cfg
, dom
, src
) == 0) {
22426 QEMU_ADD_BLOCK_PARAM_ULL(record
, maxparams
, block_idx
,
22427 "physical", src
->physical
);
22429 virResetLastError();
22440 qemuDomainGetStatsBlockExportBackendStorage(const char *entryname
,
22441 virHashTablePtr stats
,
22443 virDomainStatsRecordPtr records
,
22446 qemuBlockStats
*entry
;
22449 if (!stats
|| !entryname
|| !(entry
= virHashLookup(stats
, entryname
))) {
22454 if (entry
->write_threshold
)
22455 QEMU_ADD_BLOCK_PARAM_ULL(records
, nrecords
, recordnr
, "threshold",
22456 entry
->write_threshold
);
22465 qemuDomainGetStatsBlockExportFrontend(const char *frontendname
,
22466 virHashTablePtr stats
,
22468 virDomainStatsRecordPtr records
,
22471 qemuBlockStats
*entry
;
22474 /* In case where qemu didn't provide the stats we stop here rather than
22475 * trying to refresh the stats from the disk. Inability to provide stats is
22476 * usually caused by blocked storage so this would make libvirtd hang */
22477 if (!stats
|| !frontendname
|| !(entry
= virHashLookup(stats
, frontendname
))) {
22482 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "rd.reqs", entry
->rd_req
);
22483 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "rd.bytes", entry
->rd_bytes
);
22484 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "rd.times", entry
->rd_total_times
);
22485 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "wr.reqs", entry
->wr_req
);
22486 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "wr.bytes", entry
->wr_bytes
);
22487 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "wr.times", entry
->wr_total_times
);
22488 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "fl.reqs", entry
->flush_req
);
22489 QEMU_ADD_BLOCK_PARAM_LL(records
, nrecords
, recordnr
, "fl.times", entry
->flush_total_times
);
22498 qemuDomainGetStatsBlockExportHeader(virDomainDiskDefPtr disk
,
22499 virStorageSourcePtr src
,
22501 virDomainStatsRecordPtr records
,
22506 QEMU_ADD_NAME_PARAM(records
, nrecords
, "block", "name", recordnr
, disk
->dst
);
22508 if (virStorageSourceIsLocalStorage(src
) && src
->path
)
22509 QEMU_ADD_NAME_PARAM(records
, nrecords
, "block", "path", recordnr
, src
->path
);
22511 QEMU_ADD_BLOCK_PARAM_UI(records
, nrecords
, recordnr
, "backingIndex",
22521 qemuDomainGetStatsBlockExportDisk(virDomainDiskDefPtr disk
,
22522 virHashTablePtr stats
,
22523 virHashTablePtr nodestats
,
22524 virDomainStatsRecordPtr records
,
22528 virQEMUDriverPtr driver
,
22529 virQEMUDriverConfigPtr cfg
,
22530 virDomainObjPtr dom
,
22534 char *alias
= NULL
;
22535 virStorageSourcePtr n
;
22536 const char *frontendalias
;
22537 const char *backendalias
;
22538 const char *backendstoragealias
;
22542 * This helps to keep logs clean from error messages on getting stats
22543 * for optional disk with nonexistent source file. We won't get any
22544 * stats for such a disk anyway in below code.
22546 if (!virDomainObjIsActive(dom
) &&
22547 qemuDomainDiskIsMissingLocalOptional(disk
)) {
22548 VIR_INFO("optional disk '%s' source file is missing, "
22549 "skip getting stats", disk
->dst
);
22551 return qemuDomainGetStatsBlockExportHeader(disk
, disk
->src
, *recordnr
,
22552 records
, nrecords
);
22555 for (n
= disk
->src
; virStorageSourceIsBacking(n
); n
= n
->backingStore
) {
22557 frontendalias
= QEMU_DOMAIN_DISK_PRIVATE(disk
)->qomName
;
22558 backendalias
= n
->nodeformat
;
22559 backendstoragealias
= n
->nodestorage
;
22561 /* alias may be NULL if the VM is not running */
22562 if (disk
->info
.alias
&&
22563 !(alias
= qemuDomainStorageAlias(disk
->info
.alias
, n
->id
)))
22566 qemuDomainGetStatsOneBlockRefreshNamed(n
, alias
, stats
, nodestats
);
22568 frontendalias
= alias
;
22569 backendalias
= alias
;
22570 backendstoragealias
= alias
;
22573 if (qemuDomainGetStatsBlockExportHeader(disk
, n
, *recordnr
,
22574 records
, nrecords
) < 0)
22577 /* The following stats make sense only for the frontend device */
22578 if (n
== disk
->src
) {
22579 if (qemuDomainGetStatsBlockExportFrontend(frontendalias
, stats
, *recordnr
,
22580 records
, nrecords
) < 0)
22584 if (qemuDomainGetStatsOneBlock(driver
, cfg
, dom
, records
, nrecords
,
22585 backendalias
, n
, *recordnr
,
22589 if (qemuDomainGetStatsBlockExportBackendStorage(backendstoragealias
,
22591 records
, nrecords
) < 0)
22610 qemuDomainGetStatsBlock(virQEMUDriverPtr driver
,
22611 virDomainObjPtr dom
,
22612 virDomainStatsRecordPtr record
,
22614 unsigned int privflags
)
22619 virHashTablePtr stats
= NULL
;
22620 virHashTablePtr nodestats
= NULL
;
22621 virJSONValuePtr nodedata
= NULL
;
22622 qemuDomainObjPrivatePtr priv
= dom
->privateData
;
22623 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
22624 bool blockdev
= virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCKDEV
);
22625 bool fetchnodedata
= virQEMUCapsGet(priv
->qemuCaps
,
22626 QEMU_CAPS_QUERY_NAMED_BLOCK_NODES
) && !blockdev
;
22627 int count_index
= -1;
22628 size_t visited
= 0;
22629 bool visitBacking
= !!(privflags
& QEMU_DOMAIN_STATS_BACKING
);
22631 if (HAVE_JOB(privflags
) && virDomainObjIsActive(dom
)) {
22632 qemuDomainObjEnterMonitor(driver
, dom
);
22634 rc
= qemuMonitorGetAllBlockStatsInfo(priv
->mon
, &stats
, visitBacking
);
22638 rc
= qemuMonitorBlockStatsUpdateCapacityBlockdev(priv
->mon
, stats
);
22640 ignore_value(qemuMonitorBlockStatsUpdateCapacity(priv
->mon
, stats
,
22645 nodedata
= qemuMonitorQueryNamedBlockNodes(priv
->mon
);
22647 if (qemuDomainObjExitMonitor(driver
, dom
) < 0)
22650 /* failure to retrieve stats is fine at this point */
22651 if (rc
< 0 || (fetchnodedata
&& !nodedata
))
22652 virResetLastError();
22656 !(nodestats
= qemuBlockGetNodeData(nodedata
)))
22659 /* When listing backing chains, it's easier to fix up the count
22660 * after the iteration than it is to iterate twice; but we still
22661 * want count listed first. */
22662 count_index
= record
->nparams
;
22663 QEMU_ADD_COUNT_PARAM(record
, maxparams
, "block", 0);
22665 for (i
= 0; i
< dom
->def
->ndisks
; i
++) {
22666 if (qemuDomainGetStatsBlockExportDisk(dom
->def
->disks
[i
], stats
, nodestats
,
22667 record
, maxparams
, &visited
,
22668 visitBacking
, driver
, cfg
, dom
,
22673 record
->params
[count_index
].value
.ui
= visited
;
22677 virHashFree(stats
);
22678 virHashFree(nodestats
);
22679 virJSONValueFree(nodedata
);
22680 virObjectUnref(cfg
);
22684 #undef QEMU_ADD_BLOCK_PARAM_LL
22686 #undef QEMU_ADD_BLOCK_PARAM_ULL
22688 #undef QEMU_ADD_NAME_PARAM
22690 #define QEMU_ADD_IOTHREAD_PARAM_UI(record, maxparams, id, name, value) \
22692 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22693 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22694 "iothread.%u.%s", id, name); \
22695 if (virTypedParamsAddUInt(&(record)->params, \
22696 &(record)->nparams, \
22703 #define QEMU_ADD_IOTHREAD_PARAM_ULL(record, maxparams, id, name, value) \
22705 char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
22706 snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
22707 "iothread.%u.%s", id, name); \
22708 if (virTypedParamsAddULLong(&(record)->params, \
22709 &(record)->nparams, \
22717 qemuDomainGetStatsIOThread(virQEMUDriverPtr driver
,
22718 virDomainObjPtr dom
,
22719 virDomainStatsRecordPtr record
,
22721 unsigned int privflags ATTRIBUTE_UNUSED
)
22723 qemuDomainObjPrivatePtr priv
= dom
->privateData
;
22725 qemuMonitorIOThreadInfoPtr
*iothreads
= NULL
;
22729 if (!virDomainObjIsActive(dom
))
22732 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_OBJECT_IOTHREAD
))
22735 if ((niothreads
= qemuDomainGetIOThreadsMon(driver
, dom
, &iothreads
)) < 0)
22738 if (niothreads
== 0)
22741 QEMU_ADD_COUNT_PARAM(record
, maxparams
, "iothread", niothreads
);
22743 for (i
= 0; i
< niothreads
; i
++) {
22744 if (iothreads
[i
]->poll_valid
) {
22745 QEMU_ADD_IOTHREAD_PARAM_ULL(record
, maxparams
,
22746 iothreads
[i
]->iothread_id
,
22748 iothreads
[i
]->poll_max_ns
);
22749 QEMU_ADD_IOTHREAD_PARAM_UI(record
, maxparams
,
22750 iothreads
[i
]->iothread_id
,
22752 iothreads
[i
]->poll_grow
);
22753 QEMU_ADD_IOTHREAD_PARAM_UI(record
, maxparams
,
22754 iothreads
[i
]->iothread_id
,
22756 iothreads
[i
]->poll_shrink
);
22763 for (i
= 0; i
< niothreads
; i
++)
22764 VIR_FREE(iothreads
[i
]);
22765 VIR_FREE(iothreads
);
22770 #undef QEMU_ADD_IOTHREAD_PARAM_UI
22772 #undef QEMU_ADD_IOTHREAD_PARAM_ULL
22774 #undef QEMU_ADD_COUNT_PARAM
22777 qemuDomainGetStatsPerfOneEvent(virPerfPtr perf
,
22778 virPerfEventType type
,
22779 virDomainStatsRecordPtr record
,
22782 char param_name
[VIR_TYPED_PARAM_FIELD_LENGTH
];
22783 uint64_t value
= 0;
22785 if (virPerfReadEvent(perf
, type
, &value
) < 0)
22788 snprintf(param_name
, VIR_TYPED_PARAM_FIELD_LENGTH
, "perf.%s",
22789 virPerfEventTypeToString(type
));
22791 if (virTypedParamsAddULLong(&record
->params
,
22802 qemuDomainGetStatsPerf(virQEMUDriverPtr driver ATTRIBUTE_UNUSED
,
22803 virDomainObjPtr dom
,
22804 virDomainStatsRecordPtr record
,
22806 unsigned int privflags ATTRIBUTE_UNUSED
)
22809 qemuDomainObjPrivatePtr priv
= dom
->privateData
;
22812 for (i
= 0; i
< VIR_PERF_EVENT_LAST
; i
++) {
22813 if (!virPerfEventIsEnabled(priv
->perf
, i
))
22816 if (qemuDomainGetStatsPerfOneEvent(priv
->perf
, i
,
22817 record
, maxparams
) < 0)
22828 (*qemuDomainGetStatsFunc
)(virQEMUDriverPtr driver
,
22829 virDomainObjPtr dom
,
22830 virDomainStatsRecordPtr record
,
22832 unsigned int flags
);
22834 struct qemuDomainGetStatsWorker
{
22835 qemuDomainGetStatsFunc func
;
22836 unsigned int stats
;
22840 static struct qemuDomainGetStatsWorker qemuDomainGetStatsWorkers
[] = {
22841 { qemuDomainGetStatsState
, VIR_DOMAIN_STATS_STATE
, false },
22842 { qemuDomainGetStatsCpu
, VIR_DOMAIN_STATS_CPU_TOTAL
, false },
22843 { qemuDomainGetStatsBalloon
, VIR_DOMAIN_STATS_BALLOON
, true },
22844 { qemuDomainGetStatsVcpu
, VIR_DOMAIN_STATS_VCPU
, true },
22845 { qemuDomainGetStatsInterface
, VIR_DOMAIN_STATS_INTERFACE
, false },
22846 { qemuDomainGetStatsBlock
, VIR_DOMAIN_STATS_BLOCK
, true },
22847 { qemuDomainGetStatsPerf
, VIR_DOMAIN_STATS_PERF
, false },
22848 { qemuDomainGetStatsIOThread
, VIR_DOMAIN_STATS_IOTHREAD
, true },
22854 qemuDomainGetStatsCheckSupport(unsigned int *stats
,
22857 unsigned int supportedstats
= 0;
22860 for (i
= 0; qemuDomainGetStatsWorkers
[i
].func
; i
++)
22861 supportedstats
|= qemuDomainGetStatsWorkers
[i
].stats
;
22864 *stats
= supportedstats
;
22869 *stats
& ~supportedstats
) {
22870 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
,
22871 _("Stats types bits 0x%x are not supported by this daemon"),
22872 *stats
& ~supportedstats
);
22876 *stats
&= supportedstats
;
22882 qemuDomainGetStatsNeedMonitor(unsigned int stats
)
22886 for (i
= 0; qemuDomainGetStatsWorkers
[i
].func
; i
++)
22887 if (stats
& qemuDomainGetStatsWorkers
[i
].stats
&&
22888 qemuDomainGetStatsWorkers
[i
].monitor
)
22896 qemuDomainGetStats(virConnectPtr conn
,
22897 virDomainObjPtr dom
,
22898 unsigned int stats
,
22899 virDomainStatsRecordPtr
*record
,
22900 unsigned int flags
)
22903 virDomainStatsRecordPtr tmp
;
22907 if (VIR_ALLOC(tmp
) < 0)
22910 for (i
= 0; qemuDomainGetStatsWorkers
[i
].func
; i
++) {
22911 if (stats
& qemuDomainGetStatsWorkers
[i
].stats
) {
22912 if (qemuDomainGetStatsWorkers
[i
].func(conn
->privateData
, dom
, tmp
,
22913 &maxparams
, flags
) < 0)
22918 if (!(tmp
->dom
= virGetDomain(conn
, dom
->def
->name
,
22919 dom
->def
->uuid
, dom
->def
->id
)))
22928 virTypedParamsFree(tmp
->params
, tmp
->nparams
);
22937 qemuConnectGetAllDomainStats(virConnectPtr conn
,
22938 virDomainPtr
*doms
,
22939 unsigned int ndoms
,
22940 unsigned int stats
,
22941 virDomainStatsRecordPtr
**retStats
,
22942 unsigned int flags
)
22944 virQEMUDriverPtr driver
= conn
->privateData
;
22945 virErrorPtr orig_err
= NULL
;
22946 virDomainObjPtr
*vms
= NULL
;
22947 virDomainObjPtr vm
;
22949 virDomainStatsRecordPtr
*tmpstats
= NULL
;
22950 bool enforce
= !!(flags
& VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS
);
22954 unsigned int privflags
= 0;
22955 unsigned int domflags
= 0;
22956 unsigned int lflags
= flags
& (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE
|
22957 VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT
|
22958 VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE
);
22960 virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE
|
22961 VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT
|
22962 VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE
|
22963 VIR_CONNECT_GET_ALL_DOMAINS_STATS_NOWAIT
|
22964 VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING
|
22965 VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS
, -1);
22967 if (virConnectGetAllDomainStatsEnsureACL(conn
) < 0)
22970 if (qemuDomainGetStatsCheckSupport(&stats
, enforce
) < 0)
22974 if (virDomainObjListConvert(driver
->domains
, conn
, doms
, ndoms
, &vms
,
22975 &nvms
, virConnectGetAllDomainStatsCheckACL
,
22979 if (virDomainObjListCollect(driver
->domains
, conn
, &vms
, &nvms
,
22980 virConnectGetAllDomainStatsCheckACL
,
22985 if (VIR_ALLOC_N(tmpstats
, nvms
+ 1) < 0)
22988 if (qemuDomainGetStatsNeedMonitor(stats
))
22989 privflags
|= QEMU_DOMAIN_STATS_HAVE_JOB
;
22991 for (i
= 0; i
< nvms
; i
++) {
22992 virDomainStatsRecordPtr tmp
= NULL
;
22998 if (HAVE_JOB(privflags
)) {
23001 if (flags
& VIR_CONNECT_GET_ALL_DOMAINS_STATS_NOWAIT
)
23002 rv
= qemuDomainObjBeginJobNowait(driver
, vm
, QEMU_JOB_QUERY
);
23004 rv
= qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
);
23007 domflags
|= QEMU_DOMAIN_STATS_HAVE_JOB
;
23009 /* else: without a job it's still possible to gather some data */
23011 if (flags
& VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING
)
23012 domflags
|= QEMU_DOMAIN_STATS_BACKING
;
23013 if (qemuDomainGetStats(conn
, vm
, stats
, &tmp
, domflags
) < 0) {
23014 if (HAVE_JOB(domflags
) && vm
)
23015 qemuDomainObjEndJob(driver
, vm
);
23017 virObjectUnlock(vm
);
23022 tmpstats
[nstats
++] = tmp
;
23024 if (HAVE_JOB(domflags
))
23025 qemuDomainObjEndJob(driver
, vm
);
23027 virObjectUnlock(vm
);
23030 *retStats
= tmpstats
;
23036 virErrorPreserveLast(&orig_err
);
23037 virDomainStatsRecordListFree(tmpstats
);
23038 virObjectListFreeCount(vms
, nvms
);
23039 virErrorRestore(&orig_err
);
23046 qemuNodeAllocPages(virConnectPtr conn
,
23047 unsigned int npages
,
23048 unsigned int *pageSizes
,
23049 unsigned long long *pageCounts
,
23051 unsigned int cellCount
,
23052 unsigned int flags
)
23054 bool add
= !(flags
& VIR_NODE_ALLOC_PAGES_SET
);
23056 virCheckFlags(VIR_NODE_ALLOC_PAGES_SET
, -1);
23058 if (virNodeAllocPagesEnsureACL(conn
) < 0)
23061 return virHostMemAllocPages(npages
, pageSizes
, pageCounts
,
23062 startCell
, cellCount
, add
);
23067 qemuDomainGetFSInfo(virDomainPtr dom
,
23068 virDomainFSInfoPtr
**info
,
23069 unsigned int flags
)
23071 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23072 virDomainObjPtr vm
;
23073 qemuAgentPtr agent
;
23074 virCapsPtr caps
= NULL
;
23075 virDomainDefPtr def
= NULL
;
23078 virCheckFlags(0, ret
);
23080 if (!(vm
= qemuDomObjFromDomain(dom
)))
23083 if (virDomainGetFSInfoEnsureACL(dom
->conn
, vm
->def
) < 0)
23086 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
23089 if (virDomainObjCheckActive(vm
) < 0)
23092 if (!qemuDomainAgentAvailable(vm
, true))
23095 if (!(caps
= virQEMUDriverGetCapabilities(driver
, false)))
23098 if (!(def
= virDomainDefCopy(vm
->def
, caps
, driver
->xmlopt
, NULL
, false)))
23101 agent
= qemuDomainObjEnterAgent(vm
);
23102 ret
= qemuAgentGetFSInfo(agent
, info
, def
);
23103 qemuDomainObjExitAgent(vm
, agent
);
23106 qemuDomainObjEndAgentJob(vm
);
23109 virDomainObjEndAPI(&vm
);
23110 virDomainDefFree(def
);
23111 virObjectUnref(caps
);
23116 qemuDomainInterfaceAddresses(virDomainPtr dom
,
23117 virDomainInterfacePtr
**ifaces
,
23118 unsigned int source
,
23119 unsigned int flags
)
23121 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23122 virDomainObjPtr vm
= NULL
;
23123 qemuAgentPtr agent
;
23126 virCheckFlags(0, -1);
23128 if (!(vm
= qemuDomObjFromDomain(dom
)))
23131 if (virDomainInterfaceAddressesEnsureACL(dom
->conn
, vm
->def
) < 0)
23134 if (virDomainObjCheckActive(vm
) < 0)
23138 case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE
:
23139 ret
= qemuGetDHCPInterfaces(dom
, vm
, ifaces
);
23142 case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT
:
23143 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
23146 if (!qemuDomainAgentAvailable(vm
, true))
23149 agent
= qemuDomainObjEnterAgent(vm
);
23150 ret
= qemuAgentGetInterfaces(agent
, ifaces
);
23151 qemuDomainObjExitAgent(vm
, agent
);
23154 qemuDomainObjEndAgentJob(vm
);
23158 case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP
:
23159 ret
= qemuARPGetInterfaces(vm
, ifaces
);
23163 virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED
,
23164 _("Unknown IP address data source %d"),
23170 virDomainObjEndAPI(&vm
);
23175 qemuGetDHCPInterfaces(virDomainPtr dom
,
23176 virDomainObjPtr vm
,
23177 virDomainInterfacePtr
**ifaces
)
23182 size_t ifaces_count
= 0;
23183 virNetworkPtr network
= NULL
;
23184 char macaddr
[VIR_MAC_STRING_BUFLEN
];
23185 virDomainInterfacePtr iface
= NULL
;
23186 virNetworkDHCPLeasePtr
*leases
= NULL
;
23187 virDomainInterfacePtr
*ifaces_ret
= NULL
;
23189 if (!dom
->conn
->networkDriver
||
23190 !dom
->conn
->networkDriver
->networkGetDHCPLeases
) {
23191 virReportError(VIR_ERR_INTERNAL_ERROR
, "%s",
23192 _("Network driver does not support DHCP lease query"));
23196 for (i
= 0; i
< vm
->def
->nnets
; i
++) {
23197 if (vm
->def
->nets
[i
]->type
!= VIR_DOMAIN_NET_TYPE_NETWORK
)
23200 virMacAddrFormat(&(vm
->def
->nets
[i
]->mac
), macaddr
);
23201 virObjectUnref(network
);
23202 network
= virNetworkLookupByName(dom
->conn
,
23203 vm
->def
->nets
[i
]->data
.network
.name
);
23205 if ((n_leases
= virNetworkGetDHCPLeases(network
, macaddr
,
23210 if (VIR_EXPAND_N(ifaces_ret
, ifaces_count
, 1) < 0)
23213 if (VIR_ALLOC(ifaces_ret
[ifaces_count
- 1]) < 0)
23216 iface
= ifaces_ret
[ifaces_count
- 1];
23217 /* Assuming each lease corresponds to a separate IP */
23218 iface
->naddrs
= n_leases
;
23220 if (VIR_ALLOC_N(iface
->addrs
, iface
->naddrs
) < 0)
23223 if (VIR_STRDUP(iface
->name
, vm
->def
->nets
[i
]->ifname
) < 0)
23226 if (VIR_STRDUP(iface
->hwaddr
, macaddr
) < 0)
23230 for (j
= 0; j
< n_leases
; j
++) {
23231 virNetworkDHCPLeasePtr lease
= leases
[j
];
23232 virDomainIPAddressPtr ip_addr
= &iface
->addrs
[j
];
23234 if (VIR_STRDUP(ip_addr
->addr
, lease
->ipaddr
) < 0)
23237 ip_addr
->type
= lease
->type
;
23238 ip_addr
->prefix
= lease
->prefix
;
23241 for (j
= 0; j
< n_leases
; j
++)
23242 virNetworkDHCPLeaseFree(leases
[j
]);
23247 VIR_STEAL_PTR(*ifaces
, ifaces_ret
);
23251 virObjectUnref(network
);
23253 for (i
= 0; i
< n_leases
; i
++)
23254 virNetworkDHCPLeaseFree(leases
[i
]);
23262 for (i
= 0; i
< ifaces_count
; i
++)
23263 virDomainInterfaceFree(ifaces_ret
[i
]);
23265 VIR_FREE(ifaces_ret
);
23272 qemuARPGetInterfaces(virDomainObjPtr vm
,
23273 virDomainInterfacePtr
**ifaces
)
23276 size_t ifaces_count
= 0;
23278 char macaddr
[VIR_MAC_STRING_BUFLEN
];
23279 virDomainInterfacePtr
*ifaces_ret
= NULL
;
23280 virDomainInterfacePtr iface
= NULL
;
23281 virArpTablePtr table
;
23283 table
= virArpTableGet();
23287 for (i
= 0; i
< vm
->def
->nnets
; i
++) {
23288 virMacAddrFormat(&(vm
->def
->nets
[i
]->mac
), macaddr
);
23289 for (j
= 0; j
< table
->n
; j
++) {
23290 virArpTableEntry entry
= table
->t
[j
];
23292 if (STREQ(entry
.mac
, macaddr
)) {
23293 if (VIR_ALLOC(iface
) < 0)
23296 if (VIR_STRDUP(iface
->name
, vm
->def
->nets
[i
]->ifname
) < 0)
23299 if (VIR_STRDUP(iface
->hwaddr
, macaddr
) < 0)
23302 if (VIR_ALLOC(iface
->addrs
) < 0)
23306 if (VIR_STRDUP(iface
->addrs
->addr
, entry
.ipaddr
) < 0)
23309 if (VIR_APPEND_ELEMENT(ifaces_ret
, ifaces_count
, iface
) < 0)
23315 VIR_STEAL_PTR(*ifaces
, ifaces_ret
);
23316 ret
= ifaces_count
;
23319 virArpTableFree(table
);
23320 virDomainInterfaceFree(iface
);
23323 for (i
= 0; i
< ifaces_count
; i
++)
23324 virDomainInterfaceFree(ifaces_ret
[i
]);
23326 VIR_FREE(ifaces_ret
);
23333 qemuDomainSetUserPassword(virDomainPtr dom
,
23335 const char *password
,
23336 unsigned int flags
)
23338 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23339 virDomainObjPtr vm
;
23340 qemuAgentPtr agent
;
23344 virCheckFlags(VIR_DOMAIN_PASSWORD_ENCRYPTED
, -1);
23346 if (!(vm
= qemuDomObjFromDomain(dom
)))
23349 if (virDomainSetUserPasswordEnsureACL(dom
->conn
, vm
->def
) < 0)
23352 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
23355 if (virDomainObjCheckActive(vm
) < 0)
23358 if (!qemuDomainAgentAvailable(vm
, true))
23361 agent
= qemuDomainObjEnterAgent(vm
);
23362 rv
= qemuAgentSetUserPassword(agent
, user
, password
,
23363 flags
& VIR_DOMAIN_PASSWORD_ENCRYPTED
);
23364 qemuDomainObjExitAgent(vm
, agent
);
23372 qemuDomainObjEndAgentJob(vm
);
23375 virDomainObjEndAPI(&vm
);
23381 qemuDomainRenameCallback(virDomainObjPtr vm
,
23382 const char *new_name
,
23383 unsigned int flags
,
23386 virQEMUDriverPtr driver
= opaque
;
23387 virQEMUDriverConfigPtr cfg
= NULL
;
23388 virObjectEventPtr event_new
= NULL
;
23389 virObjectEventPtr event_old
= NULL
;
23391 char *new_dom_name
= NULL
;
23392 char *old_dom_name
= NULL
;
23393 char *new_dom_cfg_file
= NULL
;
23394 char *old_dom_cfg_file
= NULL
;
23395 char *new_dom_autostart_link
= NULL
;
23396 char *old_dom_autostart_link
= NULL
;
23398 virCheckFlags(0, ret
);
23400 if (strchr(new_name
, '/')) {
23401 virReportError(VIR_ERR_XML_ERROR
,
23402 _("name %s cannot contain '/'"), new_name
);
23406 cfg
= virQEMUDriverGetConfig(driver
);
23408 if (VIR_STRDUP(new_dom_name
, new_name
) < 0)
23411 if (!(new_dom_cfg_file
= virDomainConfigFile(cfg
->configDir
,
23413 !(old_dom_cfg_file
= virDomainConfigFile(cfg
->configDir
,
23417 if (vm
->autostart
) {
23418 if (!(new_dom_autostart_link
= virDomainConfigFile(cfg
->autostartDir
,
23420 !(old_dom_autostart_link
= virDomainConfigFile(cfg
->autostartDir
,
23424 if (symlink(new_dom_cfg_file
, new_dom_autostart_link
) < 0) {
23425 virReportSystemError(errno
,
23426 _("Failed to create symlink '%s to '%s'"),
23427 new_dom_autostart_link
, new_dom_cfg_file
);
23432 event_old
= virDomainEventLifecycleNewFromObj(vm
,
23433 VIR_DOMAIN_EVENT_UNDEFINED
,
23434 VIR_DOMAIN_EVENT_UNDEFINED_RENAMED
);
23436 /* Switch name in domain definition. */
23437 old_dom_name
= vm
->def
->name
;
23438 vm
->def
->name
= new_dom_name
;
23439 new_dom_name
= NULL
;
23441 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
, vm
->def
) < 0)
23444 if (virFileExists(old_dom_cfg_file
) &&
23445 unlink(old_dom_cfg_file
) < 0) {
23446 virReportSystemError(errno
,
23447 _("cannot remove old domain config file %s"),
23452 if (vm
->autostart
) {
23453 if (virFileIsLink(old_dom_autostart_link
) &&
23454 unlink(old_dom_autostart_link
) < 0) {
23455 virReportSystemError(errno
,
23456 _("Failed to delete symlink '%s'"),
23457 old_dom_autostart_link
);
23462 event_new
= virDomainEventLifecycleNewFromObj(vm
,
23463 VIR_DOMAIN_EVENT_DEFINED
,
23464 VIR_DOMAIN_EVENT_DEFINED_RENAMED
);
23468 VIR_FREE(old_dom_autostart_link
);
23469 VIR_FREE(new_dom_autostart_link
);
23470 VIR_FREE(old_dom_cfg_file
);
23471 VIR_FREE(new_dom_cfg_file
);
23472 VIR_FREE(old_dom_name
);
23473 VIR_FREE(new_dom_name
);
23474 virObjectEventStateQueue(driver
->domainEventState
, event_old
);
23475 virObjectEventStateQueue(driver
->domainEventState
, event_new
);
23476 virObjectUnref(cfg
);
23480 if (old_dom_name
) {
23481 new_dom_name
= vm
->def
->name
;
23482 vm
->def
->name
= old_dom_name
;
23483 old_dom_name
= NULL
;
23486 if (virFileExists(new_dom_cfg_file
))
23487 unlink(new_dom_cfg_file
);
23489 if (vm
->autostart
&&
23490 virFileExists(new_dom_autostart_link
))
23491 unlink(new_dom_autostart_link
);
23496 static int qemuDomainRename(virDomainPtr dom
,
23497 const char *new_name
,
23498 unsigned int flags
)
23500 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23501 virDomainObjPtr vm
= NULL
;
23504 virCheckFlags(0, ret
);
23506 if (!(vm
= qemuDomObjFromDomain(dom
)))
23509 if (virDomainRenameEnsureACL(dom
->conn
, vm
->def
) < 0)
23512 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
23515 if (virDomainObjIsActive(vm
)) {
23516 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
23517 _("cannot rename active domain"));
23521 if (!vm
->persistent
) {
23522 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
23523 _("cannot rename a transient domain"));
23527 if (vm
->hasManagedSave
) {
23528 virReportError(VIR_ERR_OPERATION_INVALID
, "%s",
23529 _("domain with a managed saved state can't be renamed"));
23533 if (virDomainObjGetState(vm
, NULL
) != VIR_DOMAIN_SHUTOFF
) {
23534 virReportError(VIR_ERR_OPERATION_INVALID
,
23535 "%s", _("domain has to be shutoff before renaming"));
23539 if (virDomainSnapshotObjListNum(vm
->snapshots
, NULL
, 0) > 0) {
23540 virReportError(VIR_ERR_OPERATION_INVALID
,
23541 "%s", _("cannot rename domain with snapshots"));
23545 if (virDomainListAllCheckpoints(vm
->checkpoints
, NULL
, dom
, NULL
, flags
) > 0) {
23546 virReportError(VIR_ERR_OPERATION_INVALID
,
23547 "%s", _("cannot rename domain with checkpoints"));
23551 if (virDomainObjListRename(driver
->domains
, vm
, new_name
, flags
,
23552 qemuDomainRenameCallback
, driver
) < 0)
23555 /* Success, domain has been renamed. */
23559 qemuDomainObjEndJob(driver
, vm
);
23562 virDomainObjEndAPI(&vm
);
23568 qemuDomainGetGuestVcpusParams(virTypedParameterPtr
*params
,
23569 unsigned int *nparams
,
23570 qemuAgentCPUInfoPtr info
,
23573 virTypedParameterPtr par
= NULL
;
23576 virBitmapPtr vcpus
= NULL
;
23577 virBitmapPtr online
= NULL
;
23578 virBitmapPtr offlinable
= NULL
;
23583 if (!(vcpus
= virBitmapNew(QEMU_GUEST_VCPU_MAX_ID
)) ||
23584 !(online
= virBitmapNew(QEMU_GUEST_VCPU_MAX_ID
)) ||
23585 !(offlinable
= virBitmapNew(QEMU_GUEST_VCPU_MAX_ID
)))
23588 for (i
= 0; i
< ninfo
; i
++) {
23589 if (virBitmapSetBit(vcpus
, info
[i
].id
) < 0) {
23590 virReportError(VIR_ERR_INTERNAL_ERROR
,
23591 _("vcpu id '%u' reported by guest agent is out of "
23592 "range"), info
[i
].id
);
23596 if (info
[i
].online
)
23597 ignore_value(virBitmapSetBit(online
, info
[i
].id
));
23599 if (info
[i
].offlinable
)
23600 ignore_value(virBitmapSetBit(offlinable
, info
[i
].id
));
23603 #define ADD_BITMAP(name) \
23604 if (!(tmp = virBitmapFormat(name))) \
23606 if (virTypedParamsAddString(&par, &npar, &maxpar, #name, tmp) < 0) \
23611 ADD_BITMAP(online
);
23612 ADD_BITMAP(offlinable
);
23623 virBitmapFree(vcpus
);
23624 virBitmapFree(online
);
23625 virBitmapFree(offlinable
);
23626 virTypedParamsFree(par
, npar
);
23632 qemuDomainGetGuestVcpus(virDomainPtr dom
,
23633 virTypedParameterPtr
*params
,
23634 unsigned int *nparams
,
23635 unsigned int flags
)
23637 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23638 virDomainObjPtr vm
= NULL
;
23639 qemuAgentPtr agent
;
23640 qemuAgentCPUInfoPtr info
= NULL
;
23644 virCheckFlags(0, ret
);
23646 if (!(vm
= qemuDomObjFromDomain(dom
)))
23649 if (virDomainGetGuestVcpusEnsureACL(dom
->conn
, vm
->def
) < 0)
23652 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_QUERY
) < 0)
23655 if (!qemuDomainAgentAvailable(vm
, true))
23658 agent
= qemuDomainObjEnterAgent(vm
);
23659 ninfo
= qemuAgentGetVCPUs(agent
, &info
);
23660 qemuDomainObjExitAgent(vm
, agent
);
23665 if (qemuDomainGetGuestVcpusParams(params
, nparams
, info
, ninfo
) < 0)
23671 qemuDomainObjEndAgentJob(vm
);
23675 virDomainObjEndAPI(&vm
);
23681 qemuDomainSetGuestVcpus(virDomainPtr dom
,
23682 const char *cpumap
,
23684 unsigned int flags
)
23686 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23687 virDomainObjPtr vm
= NULL
;
23688 virBitmapPtr map
= NULL
;
23689 qemuAgentCPUInfoPtr info
= NULL
;
23690 qemuAgentPtr agent
;
23695 virCheckFlags(0, -1);
23697 if (state
!= 0 && state
!= 1) {
23698 virReportInvalidArg(state
, "%s", _("unsupported state value"));
23702 if (virBitmapParse(cpumap
, &map
, QEMU_GUEST_VCPU_MAX_ID
) < 0)
23705 if (!(vm
= qemuDomObjFromDomain(dom
)))
23708 if (virDomainSetGuestVcpusEnsureACL(dom
->conn
, vm
->def
) < 0)
23711 if (qemuDomainObjBeginAgentJob(driver
, vm
, QEMU_AGENT_JOB_MODIFY
) < 0)
23714 if (!qemuDomainAgentAvailable(vm
, true))
23717 agent
= qemuDomainObjEnterAgent(vm
);
23718 ninfo
= qemuAgentGetVCPUs(agent
, &info
);
23719 qemuDomainObjExitAgent(vm
, agent
);
23725 for (i
= 0; i
< ninfo
; i
++) {
23726 if (!virBitmapIsBitSet(map
, info
[i
].id
))
23729 if (!state
&& !info
[i
].offlinable
) {
23730 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
23731 _("vCPU '%u' is not offlinable"), info
[i
].id
);
23735 info
[i
].online
= !!state
;
23736 info
[i
].modified
= true;
23738 ignore_value(virBitmapClearBit(map
, info
[i
].id
));
23741 if (!virBitmapIsAllClear(map
)) {
23742 char *tmp
= virBitmapFormat(map
);
23743 virReportError(VIR_ERR_INVALID_ARG
,
23744 _("guest is missing vCPUs '%s'"), NULLSTR(tmp
));
23749 if (!qemuDomainAgentAvailable(vm
, true))
23752 agent
= qemuDomainObjEnterAgent(vm
);
23753 ret
= qemuAgentSetVCPUs(agent
, info
, ninfo
);
23754 qemuDomainObjExitAgent(vm
, agent
);
23757 qemuDomainObjEndAgentJob(vm
);
23761 virBitmapFree(map
);
23762 virDomainObjEndAPI(&vm
);
23768 qemuDomainSetVcpu(virDomainPtr dom
,
23769 const char *cpumap
,
23771 unsigned int flags
)
23773 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23774 virDomainObjPtr vm
= NULL
;
23775 virDomainDefPtr def
= NULL
;
23776 virDomainDefPtr persistentDef
= NULL
;
23777 virBitmapPtr map
= NULL
;
23781 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
23782 VIR_DOMAIN_AFFECT_CONFIG
, -1);
23784 if (state
!= 0 && state
!= 1) {
23785 virReportInvalidArg(state
, "%s", _("unsupported state value"));
23789 if (virBitmapParse(cpumap
, &map
, QEMU_GUEST_VCPU_MAX_ID
) < 0)
23792 if ((lastvcpu
= virBitmapLastSetBit(map
)) < 0) {
23793 virReportError(VIR_ERR_INVALID_ARG
, "%s",
23794 _("no vcpus selected for modification"));
23798 if (!(vm
= qemuDomObjFromDomain(dom
)))
23801 if (virDomainSetVcpuEnsureACL(dom
->conn
, vm
->def
, flags
) < 0)
23804 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
23807 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
23810 if (persistentDef
) {
23811 if (lastvcpu
>= virDomainDefGetVcpusMax(persistentDef
)) {
23812 virReportError(VIR_ERR_INVALID_ARG
,
23813 _("vcpu %zd is not present in persistent config"),
23820 if (lastvcpu
>= virDomainDefGetVcpusMax(def
)) {
23821 virReportError(VIR_ERR_INVALID_ARG
,
23822 _("vcpu %zd is not present in live config"),
23828 ret
= qemuDomainSetVcpuInternal(driver
, vm
, def
, persistentDef
, map
, !!state
);
23831 qemuDomainObjEndJob(driver
, vm
);
23834 virBitmapFree(map
);
23835 virDomainObjEndAPI(&vm
);
23841 qemuDomainSetBlockThreshold(virDomainPtr dom
,
23843 unsigned long long threshold
,
23844 unsigned int flags
)
23846 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23847 qemuDomainObjPrivatePtr priv
;
23848 virDomainObjPtr vm
= NULL
;
23849 virStorageSourcePtr src
;
23850 char *nodename
= NULL
;
23854 virCheckFlags(0, -1);
23856 if (!(vm
= qemuDomObjFromDomain(dom
)))
23859 priv
= vm
->privateData
;
23861 if (virDomainSetBlockThresholdEnsureACL(dom
->conn
, vm
->def
) < 0)
23864 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
23867 if (virDomainObjCheckActive(vm
) < 0)
23870 if (!virQEMUCapsGet(priv
->qemuCaps
, QEMU_CAPS_BLOCK_WRITE_THRESHOLD
)) {
23871 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
23872 _("this qemu does not support setting device threshold"));
23876 if (!(src
= qemuDomainGetStorageSourceByDevstr(dev
, vm
->def
)))
23879 if (!src
->nodestorage
&&
23880 qemuBlockNodeNamesDetect(driver
, vm
, QEMU_ASYNC_JOB_NONE
) < 0)
23883 if (!src
->nodestorage
) {
23884 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
,
23885 _("threshold currently can't be set for block device '%s'"),
23890 if (VIR_STRDUP(nodename
, src
->nodestorage
) < 0)
23893 qemuDomainObjEnterMonitor(driver
, vm
);
23894 rc
= qemuMonitorSetBlockThreshold(priv
->mon
, nodename
, threshold
);
23895 if (qemuDomainObjExitMonitor(driver
, vm
) < 0 || rc
< 0)
23901 qemuDomainObjEndJob(driver
, vm
);
23904 VIR_FREE(nodename
);
23905 virDomainObjEndAPI(&vm
);
23911 qemuDomainModifyLifecycleAction(virDomainDefPtr def
,
23912 virDomainLifecycle type
,
23913 virDomainLifecycleAction action
)
23916 case VIR_DOMAIN_LIFECYCLE_POWEROFF
:
23917 def
->onPoweroff
= action
;
23919 case VIR_DOMAIN_LIFECYCLE_REBOOT
:
23920 def
->onReboot
= action
;
23922 case VIR_DOMAIN_LIFECYCLE_CRASH
:
23923 def
->onCrash
= action
;
23925 case VIR_DOMAIN_LIFECYCLE_LAST
:
23933 qemuDomainSetLifecycleAction(virDomainPtr dom
,
23935 unsigned int action
,
23936 unsigned int flags
)
23938 virQEMUDriverPtr driver
= dom
->conn
->privateData
;
23939 virQEMUDriverConfigPtr cfg
= virQEMUDriverGetConfig(driver
);
23940 qemuDomainObjPrivatePtr priv
;
23941 virDomainObjPtr vm
= NULL
;
23942 virDomainDefPtr def
= NULL
;
23943 virDomainDefPtr persistentDef
= NULL
;
23946 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE
|
23947 VIR_DOMAIN_AFFECT_CONFIG
, -1);
23949 if (!virDomainDefLifecycleActionAllowed(type
, action
))
23952 if (!(vm
= qemuDomObjFromDomain(dom
)))
23955 priv
= vm
->privateData
;
23957 if (virDomainSetLifecycleActionEnsureACL(dom
->conn
, vm
->def
) < 0)
23960 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_MODIFY
) < 0)
23963 if (virDomainObjGetDefs(vm
, flags
, &def
, &persistentDef
) < 0)
23967 if (priv
->allowReboot
== VIR_TRISTATE_BOOL_NO
) {
23968 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
23969 _("cannot update lifecycle action because QEMU "
23970 "was started with -no-reboot option"));
23974 qemuDomainModifyLifecycleAction(def
, type
, action
);
23976 if (virDomainSaveStatus(driver
->xmlopt
, cfg
->stateDir
,
23977 vm
, driver
->caps
) < 0)
23981 if (persistentDef
) {
23982 qemuDomainModifyLifecycleAction(persistentDef
, type
, action
);
23984 if (virDomainSaveConfig(cfg
->configDir
, driver
->caps
,
23985 persistentDef
) < 0)
23992 qemuDomainObjEndJob(driver
, vm
);
23995 virDomainObjEndAPI(&vm
);
23996 virObjectUnref(cfg
);
24002 qemuGetSEVInfoToParams(virQEMUCapsPtr qemuCaps
,
24003 virTypedParameterPtr
*params
,
24005 unsigned int flags
)
24009 virSEVCapabilityPtr sev
= virQEMUCapsGetSEVCapabilities(qemuCaps
);
24010 virTypedParameterPtr sevParams
= NULL
;
24012 virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY
, -1);
24014 if (virTypedParamsAddString(&sevParams
, &n
, &maxpar
,
24015 VIR_NODE_SEV_PDH
, sev
->pdh
) < 0)
24018 if (virTypedParamsAddString(&sevParams
, &n
, &maxpar
,
24019 VIR_NODE_SEV_CERT_CHAIN
, sev
->cert_chain
) < 0)
24022 if (virTypedParamsAddUInt(&sevParams
, &n
, &maxpar
,
24023 VIR_NODE_SEV_CBITPOS
, sev
->cbitpos
) < 0)
24026 if (virTypedParamsAddUInt(&sevParams
, &n
, &maxpar
,
24027 VIR_NODE_SEV_REDUCED_PHYS_BITS
,
24028 sev
->reduced_phys_bits
) < 0)
24031 VIR_STEAL_PTR(*params
, sevParams
);
24036 virTypedParamsFree(sevParams
, n
);
24042 qemuNodeGetSEVInfo(virConnectPtr conn
,
24043 virTypedParameterPtr
*params
,
24045 unsigned int flags
)
24047 virQEMUDriverPtr driver
= conn
->privateData
;
24048 virQEMUCapsPtr qemucaps
= NULL
;
24051 if (virNodeGetSevInfoEnsureACL(conn
) < 0)
24054 qemucaps
= virQEMUCapsCacheLookupByArch(driver
->qemuCapsCache
,
24055 virArchFromHost());
24059 if (!virQEMUCapsGet(qemucaps
, QEMU_CAPS_SEV_GUEST
)) {
24060 virReportError(VIR_ERR_OPERATION_UNSUPPORTED
, "%s",
24061 _("QEMU does not support SEV guest"));
24065 if (qemuGetSEVInfoToParams(qemucaps
, params
, nparams
, flags
) < 0)
24071 virObjectUnref(qemucaps
);
24078 qemuDomainGetSEVMeasurement(virQEMUDriverPtr driver
,
24079 virDomainObjPtr vm
,
24080 virTypedParameterPtr
*params
,
24082 unsigned int flags
)
24088 virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY
, -1);
24090 if (qemuDomainObjBeginJob(driver
, vm
, QEMU_JOB_QUERY
) < 0)
24093 qemuDomainObjEnterMonitor(driver
, vm
);
24094 tmp
= qemuMonitorGetSEVMeasurement(QEMU_DOMAIN_PRIVATE(vm
)->mon
);
24096 if (qemuDomainObjExitMonitor(driver
, vm
) < 0)
24102 if (virTypedParamsAddString(params
, nparams
, &maxpar
,
24103 VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT
,
24111 qemuDomainObjEndJob(driver
, vm
);
24117 qemuDomainGetLaunchSecurityInfo(virDomainPtr domain
,
24118 virTypedParameterPtr
*params
,
24120 unsigned int flags
)
24122 virQEMUDriverPtr driver
= domain
->conn
->privateData
;
24123 virDomainObjPtr vm
;
24126 if (!(vm
= qemuDomObjFromDomain(domain
)))
24129 if (virDomainGetLaunchSecurityInfoEnsureACL(domain
->conn
, vm
->def
) < 0)
24132 if (vm
->def
->sev
) {
24133 if (qemuDomainGetSEVMeasurement(driver
, vm
, params
, nparams
, flags
) < 0)
24140 virDomainObjEndAPI(&vm
);
24144 static virHypervisorDriver qemuHypervisorDriver
= {
24145 .name
= QEMU_DRIVER_NAME
,
24146 .connectURIProbe
= qemuConnectURIProbe
,
24147 .connectOpen
= qemuConnectOpen
, /* 0.2.0 */
24148 .connectClose
= qemuConnectClose
, /* 0.2.0 */
24149 .connectSupportsFeature
= qemuConnectSupportsFeature
, /* 0.5.0 */
24150 .connectGetType
= qemuConnectGetType
, /* 0.2.0 */
24151 .connectGetVersion
= qemuConnectGetVersion
, /* 0.2.0 */
24152 .connectGetHostname
= qemuConnectGetHostname
, /* 0.3.3 */
24153 .connectGetSysinfo
= qemuConnectGetSysinfo
, /* 0.8.8 */
24154 .connectGetMaxVcpus
= qemuConnectGetMaxVcpus
, /* 0.2.1 */
24155 .nodeGetInfo
= qemuNodeGetInfo
, /* 0.2.0 */
24156 .connectGetCapabilities
= qemuConnectGetCapabilities
, /* 0.2.1 */
24157 .connectListDomains
= qemuConnectListDomains
, /* 0.2.0 */
24158 .connectNumOfDomains
= qemuConnectNumOfDomains
, /* 0.2.0 */
24159 .connectListAllDomains
= qemuConnectListAllDomains
, /* 0.9.13 */
24160 .domainCreateXML
= qemuDomainCreateXML
, /* 0.2.0 */
24161 .domainLookupByID
= qemuDomainLookupByID
, /* 0.2.0 */
24162 .domainLookupByUUID
= qemuDomainLookupByUUID
, /* 0.2.0 */
24163 .domainLookupByName
= qemuDomainLookupByName
, /* 0.2.0 */
24164 .domainSuspend
= qemuDomainSuspend
, /* 0.2.0 */
24165 .domainResume
= qemuDomainResume
, /* 0.2.0 */
24166 .domainShutdown
= qemuDomainShutdown
, /* 0.2.0 */
24167 .domainShutdownFlags
= qemuDomainShutdownFlags
, /* 0.9.10 */
24168 .domainReboot
= qemuDomainReboot
, /* 0.9.3 */
24169 .domainReset
= qemuDomainReset
, /* 0.9.7 */
24170 .domainDestroy
= qemuDomainDestroy
, /* 0.2.0 */
24171 .domainDestroyFlags
= qemuDomainDestroyFlags
, /* 0.9.4 */
24172 .domainGetOSType
= qemuDomainGetOSType
, /* 0.2.2 */
24173 .domainGetMaxMemory
= qemuDomainGetMaxMemory
, /* 0.4.2 */
24174 .domainSetMaxMemory
= qemuDomainSetMaxMemory
, /* 0.4.2 */
24175 .domainSetMemory
= qemuDomainSetMemory
, /* 0.4.2 */
24176 .domainSetMemoryFlags
= qemuDomainSetMemoryFlags
, /* 0.9.0 */
24177 .domainSetMemoryParameters
= qemuDomainSetMemoryParameters
, /* 0.8.5 */
24178 .domainGetMemoryParameters
= qemuDomainGetMemoryParameters
, /* 0.8.5 */
24179 .domainSetMemoryStatsPeriod
= qemuDomainSetMemoryStatsPeriod
, /* 1.1.1 */
24180 .domainSetBlkioParameters
= qemuDomainSetBlkioParameters
, /* 0.9.0 */
24181 .domainGetBlkioParameters
= qemuDomainGetBlkioParameters
, /* 0.9.0 */
24182 .domainGetInfo
= qemuDomainGetInfo
, /* 0.2.0 */
24183 .domainGetState
= qemuDomainGetState
, /* 0.9.2 */
24184 .domainGetControlInfo
= qemuDomainGetControlInfo
, /* 0.9.3 */
24185 .domainSave
= qemuDomainSave
, /* 0.2.0 */
24186 .domainSaveFlags
= qemuDomainSaveFlags
, /* 0.9.4 */
24187 .domainRestore
= qemuDomainRestore
, /* 0.2.0 */
24188 .domainRestoreFlags
= qemuDomainRestoreFlags
, /* 0.9.4 */
24189 .domainSaveImageGetXMLDesc
= qemuDomainSaveImageGetXMLDesc
, /* 0.9.4 */
24190 .domainSaveImageDefineXML
= qemuDomainSaveImageDefineXML
, /* 0.9.4 */
24191 .domainCoreDump
= qemuDomainCoreDump
, /* 0.7.0 */
24192 .domainCoreDumpWithFormat
= qemuDomainCoreDumpWithFormat
, /* 1.2.3 */
24193 .domainScreenshot
= qemuDomainScreenshot
, /* 0.9.2 */
24194 .domainSetVcpus
= qemuDomainSetVcpus
, /* 0.4.4 */
24195 .domainSetVcpusFlags
= qemuDomainSetVcpusFlags
, /* 0.8.5 */
24196 .domainGetVcpusFlags
= qemuDomainGetVcpusFlags
, /* 0.8.5 */
24197 .domainPinVcpu
= qemuDomainPinVcpu
, /* 0.4.4 */
24198 .domainPinVcpuFlags
= qemuDomainPinVcpuFlags
, /* 0.9.3 */
24199 .domainGetVcpuPinInfo
= qemuDomainGetVcpuPinInfo
, /* 0.9.3 */
24200 .domainPinEmulator
= qemuDomainPinEmulator
, /* 0.10.0 */
24201 .domainGetEmulatorPinInfo
= qemuDomainGetEmulatorPinInfo
, /* 0.10.0 */
24202 .domainGetVcpus
= qemuDomainGetVcpus
, /* 0.4.4 */
24203 .domainGetMaxVcpus
= qemuDomainGetMaxVcpus
, /* 0.4.4 */
24204 .domainGetIOThreadInfo
= qemuDomainGetIOThreadInfo
, /* 1.2.14 */
24205 .domainPinIOThread
= qemuDomainPinIOThread
, /* 1.2.14 */
24206 .domainAddIOThread
= qemuDomainAddIOThread
, /* 1.2.15 */
24207 .domainDelIOThread
= qemuDomainDelIOThread
, /* 1.2.15 */
24208 .domainSetIOThreadParams
= qemuDomainSetIOThreadParams
, /* 4.10.0 */
24209 .domainGetSecurityLabel
= qemuDomainGetSecurityLabel
, /* 0.6.1 */
24210 .domainGetSecurityLabelList
= qemuDomainGetSecurityLabelList
, /* 0.10.0 */
24211 .nodeGetSecurityModel
= qemuNodeGetSecurityModel
, /* 0.6.1 */
24212 .domainGetXMLDesc
= qemuDomainGetXMLDesc
, /* 0.2.0 */
24213 .connectDomainXMLFromNative
= qemuConnectDomainXMLFromNative
, /* 0.6.4 */
24214 .connectDomainXMLToNative
= qemuConnectDomainXMLToNative
, /* 0.6.4 */
24215 .connectListDefinedDomains
= qemuConnectListDefinedDomains
, /* 0.2.0 */
24216 .connectNumOfDefinedDomains
= qemuConnectNumOfDefinedDomains
, /* 0.2.0 */
24217 .domainCreate
= qemuDomainCreate
, /* 0.2.0 */
24218 .domainCreateWithFlags
= qemuDomainCreateWithFlags
, /* 0.8.2 */
24219 .domainDefineXML
= qemuDomainDefineXML
, /* 0.2.0 */
24220 .domainDefineXMLFlags
= qemuDomainDefineXMLFlags
, /* 1.2.12 */
24221 .domainUndefine
= qemuDomainUndefine
, /* 0.2.0 */
24222 .domainUndefineFlags
= qemuDomainUndefineFlags
, /* 0.9.4 */
24223 .domainAttachDevice
= qemuDomainAttachDevice
, /* 0.4.1 */
24224 .domainAttachDeviceFlags
= qemuDomainAttachDeviceFlags
, /* 0.7.7 */
24225 .domainDetachDevice
= qemuDomainDetachDevice
, /* 0.5.0 */
24226 .domainDetachDeviceFlags
= qemuDomainDetachDeviceFlags
, /* 0.7.7 */
24227 .domainUpdateDeviceFlags
= qemuDomainUpdateDeviceFlags
, /* 0.8.0 */
24228 .domainDetachDeviceAlias
= qemuDomainDetachDeviceAlias
, /* 4.4.0 */
24229 .domainGetAutostart
= qemuDomainGetAutostart
, /* 0.2.1 */
24230 .domainSetAutostart
= qemuDomainSetAutostart
, /* 0.2.1 */
24231 .domainGetSchedulerType
= qemuDomainGetSchedulerType
, /* 0.7.0 */
24232 .domainGetSchedulerParameters
= qemuDomainGetSchedulerParameters
, /* 0.7.0 */
24233 .domainGetSchedulerParametersFlags
= qemuDomainGetSchedulerParametersFlags
, /* 0.9.2 */
24234 .domainSetSchedulerParameters
= qemuDomainSetSchedulerParameters
, /* 0.7.0 */
24235 .domainSetSchedulerParametersFlags
= qemuDomainSetSchedulerParametersFlags
, /* 0.9.2 */
24236 .domainMigratePerform
= qemuDomainMigratePerform
, /* 0.5.0 */
24237 .domainBlockResize
= qemuDomainBlockResize
, /* 0.9.8 */
24238 .domainBlockStats
= qemuDomainBlockStats
, /* 0.4.1 */
24239 .domainBlockStatsFlags
= qemuDomainBlockStatsFlags
, /* 0.9.5 */
24240 .domainInterfaceStats
= qemuDomainInterfaceStats
, /* 0.4.1 */
24241 .domainMemoryStats
= qemuDomainMemoryStats
, /* 0.7.5 */
24242 .domainBlockPeek
= qemuDomainBlockPeek
, /* 0.4.4 */
24243 .domainMemoryPeek
= qemuDomainMemoryPeek
, /* 0.4.4 */
24244 .domainGetBlockInfo
= qemuDomainGetBlockInfo
, /* 0.8.1 */
24245 .nodeGetCPUStats
= qemuNodeGetCPUStats
, /* 0.9.3 */
24246 .nodeGetMemoryStats
= qemuNodeGetMemoryStats
, /* 0.9.3 */
24247 .nodeGetCellsFreeMemory
= qemuNodeGetCellsFreeMemory
, /* 0.4.4 */
24248 .nodeGetFreeMemory
= qemuNodeGetFreeMemory
, /* 0.4.4 */
24249 .connectDomainEventRegister
= qemuConnectDomainEventRegister
, /* 0.5.0 */
24250 .connectDomainEventDeregister
= qemuConnectDomainEventDeregister
, /* 0.5.0 */
24251 .domainMigratePrepare2
= qemuDomainMigratePrepare2
, /* 0.5.0 */
24252 .domainMigrateFinish2
= qemuDomainMigrateFinish2
, /* 0.5.0 */
24253 .nodeDeviceDettach
= qemuNodeDeviceDettach
, /* 0.6.1 */
24254 .nodeDeviceDetachFlags
= qemuNodeDeviceDetachFlags
, /* 1.0.5 */
24255 .nodeDeviceReAttach
= qemuNodeDeviceReAttach
, /* 0.6.1 */
24256 .nodeDeviceReset
= qemuNodeDeviceReset
, /* 0.6.1 */
24257 .domainMigratePrepareTunnel
= qemuDomainMigratePrepareTunnel
, /* 0.7.2 */
24258 .connectIsEncrypted
= qemuConnectIsEncrypted
, /* 0.7.3 */
24259 .connectIsSecure
= qemuConnectIsSecure
, /* 0.7.3 */
24260 .domainIsActive
= qemuDomainIsActive
, /* 0.7.3 */
24261 .domainIsPersistent
= qemuDomainIsPersistent
, /* 0.7.3 */
24262 .domainIsUpdated
= qemuDomainIsUpdated
, /* 0.8.6 */
24263 .connectCompareCPU
= qemuConnectCompareCPU
, /* 0.7.5 */
24264 .connectBaselineCPU
= qemuConnectBaselineCPU
, /* 0.7.7 */
24265 .domainGetJobInfo
= qemuDomainGetJobInfo
, /* 0.7.7 */
24266 .domainGetJobStats
= qemuDomainGetJobStats
, /* 1.0.3 */
24267 .domainAbortJob
= qemuDomainAbortJob
, /* 0.7.7 */
24268 .domainMigrateGetMaxDowntime
= qemuDomainMigrateGetMaxDowntime
, /* 3.7.0 */
24269 .domainMigrateSetMaxDowntime
= qemuDomainMigrateSetMaxDowntime
, /* 0.8.0 */
24270 .domainMigrateGetCompressionCache
= qemuDomainMigrateGetCompressionCache
, /* 1.0.3 */
24271 .domainMigrateSetCompressionCache
= qemuDomainMigrateSetCompressionCache
, /* 1.0.3 */
24272 .domainMigrateSetMaxSpeed
= qemuDomainMigrateSetMaxSpeed
, /* 0.9.0 */
24273 .domainMigrateGetMaxSpeed
= qemuDomainMigrateGetMaxSpeed
, /* 0.9.5 */
24274 .connectDomainEventRegisterAny
= qemuConnectDomainEventRegisterAny
, /* 0.8.0 */
24275 .connectDomainEventDeregisterAny
= qemuConnectDomainEventDeregisterAny
, /* 0.8.0 */
24276 .domainManagedSave
= qemuDomainManagedSave
, /* 0.8.0 */
24277 .domainHasManagedSaveImage
= qemuDomainHasManagedSaveImage
, /* 0.8.0 */
24278 .domainManagedSaveRemove
= qemuDomainManagedSaveRemove
, /* 0.8.0 */
24279 .domainManagedSaveGetXMLDesc
= qemuDomainManagedSaveGetXMLDesc
, /* 3.7.0 */
24280 .domainManagedSaveDefineXML
= qemuDomainManagedSaveDefineXML
, /* 3.7.0 */
24281 .domainSnapshotCreateXML
= qemuDomainSnapshotCreateXML
, /* 0.8.0 */
24282 .domainSnapshotGetXMLDesc
= qemuDomainSnapshotGetXMLDesc
, /* 0.8.0 */
24283 .domainSnapshotNum
= qemuDomainSnapshotNum
, /* 0.8.0 */
24284 .domainSnapshotListNames
= qemuDomainSnapshotListNames
, /* 0.8.0 */
24285 .domainListAllSnapshots
= qemuDomainListAllSnapshots
, /* 0.9.13 */
24286 .domainSnapshotNumChildren
= qemuDomainSnapshotNumChildren
, /* 0.9.7 */
24287 .domainSnapshotListChildrenNames
= qemuDomainSnapshotListChildrenNames
, /* 0.9.7 */
24288 .domainSnapshotListAllChildren
= qemuDomainSnapshotListAllChildren
, /* 0.9.13 */
24289 .domainSnapshotLookupByName
= qemuDomainSnapshotLookupByName
, /* 0.8.0 */
24290 .domainHasCurrentSnapshot
= qemuDomainHasCurrentSnapshot
, /* 0.8.0 */
24291 .domainSnapshotGetParent
= qemuDomainSnapshotGetParent
, /* 0.9.7 */
24292 .domainSnapshotCurrent
= qemuDomainSnapshotCurrent
, /* 0.8.0 */
24293 .domainSnapshotIsCurrent
= qemuDomainSnapshotIsCurrent
, /* 0.9.13 */
24294 .domainSnapshotHasMetadata
= qemuDomainSnapshotHasMetadata
, /* 0.9.13 */
24295 .domainRevertToSnapshot
= qemuDomainRevertToSnapshot
, /* 0.8.0 */
24296 .domainSnapshotDelete
= qemuDomainSnapshotDelete
, /* 0.8.0 */
24297 .domainQemuMonitorCommand
= qemuDomainQemuMonitorCommand
, /* 0.8.3 */
24298 .domainQemuAttach
= qemuDomainQemuAttach
, /* 0.9.4 */
24299 .domainQemuAgentCommand
= qemuDomainQemuAgentCommand
, /* 0.10.0 */
24300 .connectDomainQemuMonitorEventRegister
= qemuConnectDomainQemuMonitorEventRegister
, /* 1.2.3 */
24301 .connectDomainQemuMonitorEventDeregister
= qemuConnectDomainQemuMonitorEventDeregister
, /* 1.2.3 */
24302 .domainOpenConsole
= qemuDomainOpenConsole
, /* 0.8.6 */
24303 .domainOpenGraphics
= qemuDomainOpenGraphics
, /* 0.9.7 */
24304 .domainOpenGraphicsFD
= qemuDomainOpenGraphicsFD
, /* 1.2.8 */
24305 .domainInjectNMI
= qemuDomainInjectNMI
, /* 0.9.2 */
24306 .domainMigrateBegin3
= qemuDomainMigrateBegin3
, /* 0.9.2 */
24307 .domainMigratePrepare3
= qemuDomainMigratePrepare3
, /* 0.9.2 */
24308 .domainMigratePrepareTunnel3
= qemuDomainMigratePrepareTunnel3
, /* 0.9.2 */
24309 .domainMigratePerform3
= qemuDomainMigratePerform3
, /* 0.9.2 */
24310 .domainMigrateFinish3
= qemuDomainMigrateFinish3
, /* 0.9.2 */
24311 .domainMigrateConfirm3
= qemuDomainMigrateConfirm3
, /* 0.9.2 */
24312 .domainSendKey
= qemuDomainSendKey
, /* 0.9.4 */
24313 .domainGetPerfEvents
= qemuDomainGetPerfEvents
, /* 1.3.3 */
24314 .domainSetPerfEvents
= qemuDomainSetPerfEvents
, /* 1.3.3 */
24315 .domainBlockJobAbort
= qemuDomainBlockJobAbort
, /* 0.9.4 */
24316 .domainGetBlockJobInfo
= qemuDomainGetBlockJobInfo
, /* 0.9.4 */
24317 .domainBlockJobSetSpeed
= qemuDomainBlockJobSetSpeed
, /* 0.9.4 */
24318 .domainBlockPull
= qemuDomainBlockPull
, /* 0.9.4 */
24319 .domainBlockRebase
= qemuDomainBlockRebase
, /* 0.9.10 */
24320 .domainBlockCopy
= qemuDomainBlockCopy
, /* 1.2.9 */
24321 .domainBlockCommit
= qemuDomainBlockCommit
, /* 1.0.0 */
24322 .connectIsAlive
= qemuConnectIsAlive
, /* 0.9.8 */
24323 .nodeSuspendForDuration
= qemuNodeSuspendForDuration
, /* 0.9.8 */
24324 .domainSetBlockIoTune
= qemuDomainSetBlockIoTune
, /* 0.9.8 */
24325 .domainGetBlockIoTune
= qemuDomainGetBlockIoTune
, /* 0.9.8 */
24326 .domainSetNumaParameters
= qemuDomainSetNumaParameters
, /* 0.9.9 */
24327 .domainGetNumaParameters
= qemuDomainGetNumaParameters
, /* 0.9.9 */
24328 .domainGetInterfaceParameters
= qemuDomainGetInterfaceParameters
, /* 0.9.9 */
24329 .domainSetInterfaceParameters
= qemuDomainSetInterfaceParameters
, /* 0.9.9 */
24330 .domainGetDiskErrors
= qemuDomainGetDiskErrors
, /* 0.9.10 */
24331 .domainSetMetadata
= qemuDomainSetMetadata
, /* 0.9.10 */
24332 .domainGetMetadata
= qemuDomainGetMetadata
, /* 0.9.10 */
24333 .domainPMSuspendForDuration
= qemuDomainPMSuspendForDuration
, /* 0.9.11 */
24334 .domainPMWakeup
= qemuDomainPMWakeup
, /* 0.9.11 */
24335 .domainGetCPUStats
= qemuDomainGetCPUStats
, /* 0.9.11 */
24336 .nodeGetMemoryParameters
= qemuNodeGetMemoryParameters
, /* 0.10.2 */
24337 .nodeSetMemoryParameters
= qemuNodeSetMemoryParameters
, /* 0.10.2 */
24338 .nodeGetCPUMap
= qemuNodeGetCPUMap
, /* 1.0.0 */
24339 .domainFSTrim
= qemuDomainFSTrim
, /* 1.0.1 */
24340 .domainOpenChannel
= qemuDomainOpenChannel
, /* 1.0.2 */
24341 .domainMigrateBegin3Params
= qemuDomainMigrateBegin3Params
, /* 1.1.0 */
24342 .domainMigratePrepare3Params
= qemuDomainMigratePrepare3Params
, /* 1.1.0 */
24343 .domainMigratePrepareTunnel3Params
= qemuDomainMigratePrepareTunnel3Params
, /* 1.1.0 */
24344 .domainMigratePerform3Params
= qemuDomainMigratePerform3Params
, /* 1.1.0 */
24345 .domainMigrateFinish3Params
= qemuDomainMigrateFinish3Params
, /* 1.1.0 */
24346 .domainMigrateConfirm3Params
= qemuDomainMigrateConfirm3Params
, /* 1.1.0 */
24347 .connectGetCPUModelNames
= qemuConnectGetCPUModelNames
, /* 1.1.3 */
24348 .domainFSFreeze
= qemuDomainFSFreeze
, /* 1.2.5 */
24349 .domainFSThaw
= qemuDomainFSThaw
, /* 1.2.5 */
24350 .domainGetHostname
= qemuDomainGetHostname
, /* 4.8.0 */
24351 .domainGetTime
= qemuDomainGetTime
, /* 1.2.5 */
24352 .domainSetTime
= qemuDomainSetTime
, /* 1.2.5 */
24353 .nodeGetFreePages
= qemuNodeGetFreePages
, /* 1.2.6 */
24354 .connectGetDomainCapabilities
= qemuConnectGetDomainCapabilities
, /* 1.2.7 */
24355 .connectGetAllDomainStats
= qemuConnectGetAllDomainStats
, /* 1.2.8 */
24356 .nodeAllocPages
= qemuNodeAllocPages
, /* 1.2.9 */
24357 .domainGetFSInfo
= qemuDomainGetFSInfo
, /* 1.2.11 */
24358 .domainInterfaceAddresses
= qemuDomainInterfaceAddresses
, /* 1.2.14 */
24359 .domainSetUserPassword
= qemuDomainSetUserPassword
, /* 1.2.16 */
24360 .domainRename
= qemuDomainRename
, /* 1.2.19 */
24361 .domainMigrateStartPostCopy
= qemuDomainMigrateStartPostCopy
, /* 1.3.3 */
24362 .domainGetGuestVcpus
= qemuDomainGetGuestVcpus
, /* 2.0.0 */
24363 .domainSetGuestVcpus
= qemuDomainSetGuestVcpus
, /* 2.0.0 */
24364 .domainSetVcpu
= qemuDomainSetVcpu
, /* 3.1.0 */
24365 .domainSetBlockThreshold
= qemuDomainSetBlockThreshold
, /* 3.2.0 */
24366 .domainSetLifecycleAction
= qemuDomainSetLifecycleAction
, /* 3.9.0 */
24367 .connectCompareHypervisorCPU
= qemuConnectCompareHypervisorCPU
, /* 4.4.0 */
24368 .connectBaselineHypervisorCPU
= qemuConnectBaselineHypervisorCPU
, /* 4.4.0 */
24369 .nodeGetSEVInfo
= qemuNodeGetSEVInfo
, /* 4.5.0 */
24370 .domainGetLaunchSecurityInfo
= qemuDomainGetLaunchSecurityInfo
, /* 4.5.0 */
24371 .domainCheckpointCreateXML
= qemuDomainCheckpointCreateXML
, /* 5.2.0 */
24372 .domainCheckpointGetXMLDesc
= qemuDomainCheckpointGetXMLDesc
, /* 5.2.0 */
24374 .domainListCheckpoints
= qemuDomainListCheckpoints
, /* 5.2.0 */
24375 .domainCheckpointListChildren
= qemuDomainCheckpointListChildren
, /* 5.2.0 */
24376 .domainCheckpointLookupByName
= qemuDomainCheckpointLookupByName
, /* 5.2.0 */
24377 .domainHasCurrentCheckpoint
= qemuDomainHasCurrentCheckpoint
, /* 5.2.0 */
24378 .domainCheckpointGetParent
= qemuDomainCheckpointGetParent
, /* 5.2.0 */
24379 .domainCheckpointCurrent
= qemuDomainCheckpointCurrent
, /* 5.2.0 */
24380 .domainCheckpointIsCurrent
= qemuDomainCheckpointIsCurrent
, /* 5.2.0 */
24381 .domainCheckpointHasMetadata
= qemuDomainCheckpointHasMetadata
, /* 5.2.0 */
24382 .domainCheckpointDelete
= qemuDomainCheckpointDelete
, /* 5.2.0 */
24383 .domainBackupBegin
= qemuDomainBackupBegin
, /* 5.2.0 */
24384 .domainBackupGetXMLDesc
= qemuDomainBackupGetXMLDesc
, /* 5.2.0 */
24385 .domainBackupEnd
= qemuDomainBackupEnd
, /* 5.2.0 */
24389 static virConnectDriver qemuConnectDriver
= {
24391 .uriSchemes
= (const char *[]){ "qemu", NULL
},
24392 .hypervisorDriver
= &qemuHypervisorDriver
,
24395 static virStateDriver qemuStateDriver
= {
24396 .name
= QEMU_DRIVER_NAME
,
24397 .stateInitialize
= qemuStateInitialize
,
24398 .stateCleanup
= qemuStateCleanup
,
24399 .stateReload
= qemuStateReload
,
24400 .stateStop
= qemuStateStop
,
24403 int qemuRegister(void)
24405 if (virRegisterConnectDriver(&qemuConnectDriver
,
24408 if (virRegisterStateDriver(&qemuStateDriver
) < 0)