if (qemuProcessStart(conn, driver, vm, cookie ? cookie->cpu : NULL,
asyncJob, "stdio", *fd, path, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_RESTORE,
- VIR_QEMU_PROCESS_START_PAUSED) == 0)
+ VIR_QEMU_PROCESS_START_PAUSED |
+ VIR_QEMU_PROCESS_START_GEN_VMID) == 0)
restored = true;
if (intermediatefd != -1) {
compatible = qemuDomainCheckABIStability(driver, vm, config);
}
+ /* If using VM GenID, there is no way currently to change
+ * the genid for the running guest, so set an error and
+ * mark as incompatible. */
+ if (compatible && config->genidRequested) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("domain genid update requires restart"));
+ compatible = false;
+ }
+
if (!compatible) {
virErrorPtr err = virGetLastError();
cookie ? cookie->cpu : NULL,
QEMU_ASYNC_JOB_START, NULL, -1, NULL, snap,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
- VIR_QEMU_PROCESS_START_PAUSED);
+ VIR_QEMU_PROCESS_START_PAUSED |
+ VIR_QEMU_PROCESS_START_GEN_VMID);
virDomainAuditStart(vm, "from-snapshot", rc >= 0);
detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;
event = virDomainEventLifecycleNewFromObj(vm,
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
/* Flush first event, now do transition 2 or 3 */
bool paused = (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED) != 0;
- unsigned int start_flags = 0;
+ unsigned int start_flags = VIR_QEMU_PROCESS_START_GEN_VMID;
start_flags |= paused ? VIR_QEMU_PROCESS_START_PAUSED : 0;
}
+/**
+ * qemuProcessGenID:
+ * @vm: Pointer to domain object
+ * @flags: qemuProcessStartFlags
+ *
+ * If this domain is requesting to use genid, then update the GUID
+ * value if the VIR_QEMU_PROCESS_START_GEN_VMID flag is set. This
+ * flag is set on specific paths during domain start processing when
+ * there is the possibility that the VM is potentially re-executing
+ * something that has already been executed before.
+ */
+static int
+qemuProcessGenID(virDomainObjPtr vm,
+ unsigned int flags)
+{
+ if (!vm->def->genidRequested)
+ return 0;
+
+ /* If we are coming from a path where we must provide a new gen id
+ * value regardless of whether it was previously generated or provided,
+ * then generate a new GUID value before we build the command line. */
+ if (flags & VIR_QEMU_PROCESS_START_GEN_VMID) {
+ if (virUUIDGenerate(vm->def->genid) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to regenerate genid"));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
/**
* qemuProcessLaunch:
*
virCheckFlags(VIR_QEMU_PROCESS_START_COLD |
VIR_QEMU_PROCESS_START_PAUSED |
VIR_QEMU_PROCESS_START_AUTODESTROY |
- VIR_QEMU_PROCESS_START_NEW, -1);
+ VIR_QEMU_PROCESS_START_NEW |
+ VIR_QEMU_PROCESS_START_GEN_VMID, -1);
cfg = virQEMUDriverGetConfig(driver);
goto cleanup;
logfile = qemuDomainLogContextGetWriteFD(logCtxt);
+ if (qemuProcessGenID(vm, flags) < 0)
+ goto cleanup;
+
VIR_DEBUG("Building emulator command line");
if (!(cmd = qemuBuildCommandLine(driver,
qemuDomainLogContextGetManager(logCtxt),
virCheckFlagsGoto(VIR_QEMU_PROCESS_START_COLD |
VIR_QEMU_PROCESS_START_PAUSED |
- VIR_QEMU_PROCESS_START_AUTODESTROY, cleanup);
+ VIR_QEMU_PROCESS_START_AUTODESTROY |
+ VIR_QEMU_PROCESS_START_GEN_VMID, cleanup);
if (!migrateFrom && !snapshot)
flags |= VIR_QEMU_PROCESS_START_NEW;
VIR_QEMU_PROCESS_START_AUTODESTROY = 1 << 2,
VIR_QEMU_PROCESS_START_PRETEND = 1 << 3,
VIR_QEMU_PROCESS_START_NEW = 1 << 4, /* internal, new VM is starting */
+ VIR_QEMU_PROCESS_START_GEN_VMID = 1 << 5, /* Generate a new VMID */
} qemuProcessStartFlags;
int qemuProcessStart(virConnectPtr conn,