[libvirt] [REPOSTv2 PATCH v3 3/6] qemu: Alter VM Generation ID for specific startup/launch transitions
Michal Privoznik
mprivozn at redhat.com
Fri May 25 11:39:20 UTC 2018
On 05/25/2018 12:58 PM, John Ferlan wrote:
>
>
> On 05/25/2018 04:24 AM, Michal Privoznik wrote:
>> On 05/17/2018 02:42 PM, John Ferlan wrote:
>>> Before we generate the command line for qemu, if the domain about to
>>> be launched desires to utilize the VM Generation ID functionality, then
>>> handle both the regenerating the GUID value for backup recovery (restore
>>> operation) and the startup after snapshot as both require a new GUID to
>>> be generated to allow the guest operating system to recognize the VM
>>> is re-executing something that has already executed before.
>>>
>>> Signed-off-by: John Ferlan <jferlan at redhat.com>
>>> ---
>>> src/qemu/qemu_driver.c | 17 ++++++++++++++---
>>> src/qemu/qemu_process.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
>>> src/qemu/qemu_process.h | 1 +
>>> 3 files changed, 59 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>>> index b697838070..7e968f475d 100644
>>> --- a/src/qemu/qemu_driver.c
>>> +++ b/src/qemu/qemu_driver.c
>>> @@ -6554,7 +6554,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) {
>>> @@ -15827,6 +15828,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();
>>>
>>> @@ -15907,7 +15917,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,
>>> @@ -15993,7 +16004,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 5b73a61962..f9bba69f80 100644
>>> --- a/src/qemu/qemu_process.c
>>> +++ b/src/qemu/qemu_process.c
>>> @@ -6072,6 +6072,43 @@ qemuProcessPrepareHost(virQEMUDriverPtr driver,
>>> }
>>>
>>>
>>> +/**
>>> + * qemuProcessGenID:
>>> + * @vm: Pointer to domain object
>>> + * @flags: qemuProcessStartFlags
>>> + *
>>> + * If this domain is requesting to use genid
>>> + */
>>> +static int
>>> +qemuProcessGenID(virDomainObjPtr vm,
>>> + unsigned int flags)
>>> +{
>>> + qemuDomainObjPrivatePtr priv = vm->privateData;
>>> +
>>> + if (!vm->def->genidRequested)
>>> + return 0;
>>> +
>>> + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VMGENID)) {
>>> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
>>> + _("this QEMU does not support the 'genid' capability"));
>>> + return -1;
>>> + }
>>
>> This looks misplaced to me. Firstly, if domain is required to generate
>> new vmid this function should do that. Secondly, this check is missing
>> when generating command line.
>>
>
> I dunno, it's just before building the command line in qemuProcessLaunch
> - IDC if it moves, but there may have been a request from some earlier
> review to make it be called earlier.
>
> Still moving it has implications on the entire logic. Essentially it's a
> "common" place before we generate the command line to make sure if GenID
> is desired/wanted that we have the capability and then can if we need to
> for this path change the genid value. That need is based on starting
> the domain after specific events - there is a list in the spec:
>
> http://go.microsoft.com/fwlink/?LinkId=260709
>
> and you'd have to read the replies from the v2 review series:
>
> https://www.redhat.com/archives/libvir-list/2018-April/msg02234.html
>
> in particular lots of discussion in patch 6
Okay, so leave it here.
>
>>> +
>>> + /* 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)) {
>>
>> Please do explicit comparison here. It might bite us in the future when
>> we want virUUIDGenerate to return a positive value (which would still be
>> success).
>>
>
> Right, strange - that got chopped off somewhere either during a rebase
> or cut-paste-copy from a previous review... I even posted/pushed the
> patch that changed all of them to use the < 0 syntax. Fixed this.
>
>
>>> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>>> + _("failed to regenerate genid"));
>>> + return -1;
>>> + }
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +
>>> /**
>>> * qemuProcessLaunch:
>>> *
>>> @@ -6124,7 +6161,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);
>>>
>>> @@ -6148,6 +6186,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),
>>> @@ -6513,7 +6554,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 */
>>
>> I wonder if we can do without this flag. Basically, only a handful of
>> paths require VMID regeneration. But I haven't read older versions so
>> maybe you had what I'm suggesting and were told to switch to flag.
>>
>
> That was the whole point of adding the flag - only a handful of explicit
> paths require changing the vmgen id. Those are controlled by calls to
> qemuProcessStart which eventually calls ProcessLaunch where we not only
> check the capability but the flag in order to force a change to the
> GenID based on whether we're in a path that requires a change.
>
Okay. For some reason having a special flag looked as an overkill to me,
but I can live with that.
Michal
More information about the libvir-list
mailing list