diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 3a328e5d46..4a8059ebd1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6578,7 +6578,8 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, 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) { @@ -15852,6 +15853,15 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, 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(); @@ -15932,7 +15942,8 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, 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, @@ -16018,7 +16029,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, 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; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index ac2049b95d..5f5759c9c8 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6050,6 +6050,39 @@ qemuProcessPrepareHost(virQEMUDriverPtr driver, } +/** + * 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: * @@ -6102,7 +6135,8 @@ qemuProcessLaunch(virConnectPtr conn, 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); @@ -6126,6 +6160,9 @@ qemuProcessLaunch(virConnectPtr conn, goto cleanup; logfile = qemuDomainLogContextGetWriteFD(logCtxt); + if (qemuProcessGenID(vm, flags) < 0) + goto cleanup; + VIR_DEBUG("Building emulator command line"); if (!(cmd = qemuBuildCommandLine(driver, qemuDomainLogContextGetManager(logCtxt), @@ -6491,7 +6528,8 @@ qemuProcessStart(virConnectPtr conn, 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; diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index a0e34b1c85..5098eacfe8 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -80,6 +80,7 @@ typedef enum { 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,