[PATCH 0/3] Add a retry procedure after failing to do post parsing

Get default emulator based on guest's arch, and replace it in domain's definition after domainPostParseDataAlloc's failure, then alloc again. This will solve the migration problem because of qemu emulator location error, especially, from host with to host without qemu-kvm. This commit will also allow user to create a domain with wrong emulator location, and correct it to the default one. zhangjl02 (3): qemu_domain: introduce qemuDomainPostParseDataDefEmulator domain_conf: introduce virDomainPostParseDataDefEmulator type domain_conf: set default emulator into def if it fails to alloc src/conf/domain_conf.c | 10 +++++++++- src/conf/domain_conf.h | 2 ++ src/qemu/qemu_domain.c | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) -- 2.35.1.windows.2

From: zhangjl02 <zhangjl02@inspur.com> qemuDomainPostParseDataDefEmulator will try to get default emulator based on guest's arch from capabilities, and replace the emulator in definition. Signed-off-by: zhangjl02 <zhangjl02@inspur.com> --- src/qemu/qemu_domain.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 7974cdb00b..98a4070226 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5972,6 +5972,23 @@ qemuDomainPostParseDataAlloc(const virDomainDef *def, } +static int +qemuDomainPostParseDataDefEmulator(virDomainDef *def) +{ + char *emulator = NULL; + struct stat sb; + virArch hostArch = virArchFromHost(); + emulator = virQEMUCapsGetDefaultEmulator(hostArch, def->os.arch); + if (stat(emulator, &sb) < 0) { + virReportSystemError(errno, _("Cannot check QEMU binary %s"), + emulator); + return 0; + } + def->emulator = emulator; + return 1; +} + + static void qemuDomainPostParseDataFree(void *parseOpaque) { @@ -5984,6 +6001,7 @@ qemuDomainPostParseDataFree(void *parseOpaque) virDomainDefParserConfig virQEMUDriverDomainDefParserConfig = { .domainPostParseBasicCallback = qemuDomainDefPostParseBasic, .domainPostParseDataAlloc = qemuDomainPostParseDataAlloc, + .domainPostParseDataDefEmulator = qemuDomainPostParseDataDefEmulator, .domainPostParseDataFree = qemuDomainPostParseDataFree, .devicesPostParseCallback = qemuDomainDeviceDefPostParse, .domainPostParseCallback = qemuDomainDefPostParse, -- 2.35.1.windows.2

From: zhangjl02 <zhangjl02@inspur.com> Add virDomainPostParseDataDefEmulator typedef. Add a definition callback into _virDomainDefParserConfig. Signed-off-by: zhangjl02 <zhangjl02@inspur.com> --- src/conf/domain_conf.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 88a411d00c..86d627136a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3130,6 +3130,7 @@ typedef int (*virDomainDefPostParseDataAlloc)(const virDomainDef *def, unsigned int parseFlags, void *opaque, void **parseOpaque); +typedef int (*virDomainPostParseDataDefEmulator)(virDomainDef *def); typedef void (*virDomainDefPostParseDataFree)(void *parseOpaque); /* Called in appropriate places where the domain conf parser can return failure @@ -3150,6 +3151,7 @@ struct _virDomainDefParserConfig { /* driver domain definition callbacks */ virDomainDefPostParseBasicCallback domainPostParseBasicCallback; virDomainDefPostParseDataAlloc domainPostParseDataAlloc; + virDomainPostParseDataDefEmulator domainPostParseDataDefEmulator; virDomainDefPostParseCallback domainPostParseCallback; virDomainDeviceDefPostParseCallback devicesPostParseCallback; virDomainDefAssignAddressesCallback assignAddressesCallback; -- 2.35.1.windows.2

From: zhangjl02 <zhangjl02@inspur.com> When emulator is not found on host, domainPostParseDataAlloc will return 1, and the domain will fail to start. Call domainPostParseDataDefEmulator to replace emulator with the default one of guest's arch, and try to alloc again after domainPostParseDataAlloc's failure. This will increase error tolerance, if emulator defined in xml is not found on host. Signed-off-by: zhangjl02 <zhangjl02@inspur.com> --- src/conf/domain_conf.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index bd2884088c..485f66357c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6266,7 +6266,15 @@ virDomainDefPostParse(virDomainDef *def, ret = xmlopt->config.domainPostParseDataAlloc(def, parseFlags, xmlopt->config.priv, &data.parseOpaque); - + if (ret == 1){ + int to_default = 0; + to_default = xmlopt->config.domainPostParseDataDefEmulator(def); + if (to_default) { + ret = xmlopt->config.domainPostParseDataAlloc(def, parseFlags, + xmlopt->config.priv, + &data.parseOpaque); + } + } if (virDomainDefPostParseCheckFailure(def, parseFlags, ret) < 0) goto cleanup; localParseOpaque = true; -- 2.35.1.windows.2

On Sat, May 07, 2022 at 17:40:16 +0800, zhangjl02 wrote:
From: zhangjl02 <zhangjl02@inspur.com>
When emulator is not found on host, domainPostParseDataAlloc will return 1, and the domain will fail to start. Call domainPostParseDataDefEmulator to replace emulator with the default one of guest's arch, and try to alloc again after domainPostParseDataAlloc's failure. This will increase error tolerance, if emulator defined in xml is not found on host.
What you describe here is definitely not desired. When the user specifies an emulator path in the XML we must not change it even if the emulator is not present and we could theoretically use a different one. This could mask problems and make users use a different binary without even knowing about it. If the user wishes to use the default they can certainly omit the emulator.

On Sat, May 07, 2022 at 05:40:13PM +0800, zhangjl02 wrote:
Get default emulator based on guest's arch, and replace it in domain's definition after domainPostParseDataAlloc's failure, then alloc again. This will solve the migration problem because of qemu emulator location error, especially, from host with to host without qemu-kvm.
When you're migrating between hosts it is possible to provide libvirt an updated XML doc at the time you initiate the migration. This allows you to change any aspect that doesn't impact guest ABI, so you can provide an updated emulator binary path at time of migration. With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On Mon, May 09, 2022 at 09:12:51 +0100, Daniel P. Berrangé wrote:
On Sat, May 07, 2022 at 05:40:13PM +0800, zhangjl02 wrote:
Get default emulator based on guest's arch, and replace it in domain's definition after domainPostParseDataAlloc's failure, then alloc again. This will solve the migration problem because of qemu emulator location error, especially, from host with to host without qemu-kvm.
[please primarily put justification of why you are doing something into the patches themselves. Apart from making it more obvious to reviewers it also records the justification in git once patches are commited]
When you're migrating between hosts it is possible to provide libvirt an updated XML doc at the time you initiate the migration. This allows you to change any aspect that doesn't impact guest ABI, so you can provide an updated emulator binary path at time of migration.
Actually there might be a problem with this. I've discussed this recently with Jirka. Specifically the ABI stability check is done on the source of the migration. This means that the source has to actually parse and interpret the destination XML too if it's provided by the user. Now if your source host doesn't have the qemu binary or doesn't have it in the path you have it on the destination this will fail. I mentioned to Jirka that I think this is sub-optimal: 1) see problem above 2) the post-parse callbacks might fill in different defaults e.g. if the destination qemu has different capabilities 3) if it were done on destination, the source portion of the XML can be parsed without post-parse callbacks as it comes actually from a live libvirt instance So with the above if they have problem of qemu not being where they expect, using of the destination XML will not help. They might be able to use the hook script to filter it on the destination though: https://www.libvirt.org/hooks.html#qemu-guest-migration

On Mon, May 09, 2022 at 10:22:56AM +0200, Peter Krempa wrote:
On Mon, May 09, 2022 at 09:12:51 +0100, Daniel P. Berrangé wrote:
On Sat, May 07, 2022 at 05:40:13PM +0800, zhangjl02 wrote:
Get default emulator based on guest's arch, and replace it in domain's definition after domainPostParseDataAlloc's failure, then alloc again. This will solve the migration problem because of qemu emulator location error, especially, from host with to host without qemu-kvm.
[please primarily put justification of why you are doing something into the patches themselves. Apart from making it more obvious to reviewers it also records the justification in git once patches are commited]
When you're migrating between hosts it is possible to provide libvirt an updated XML doc at the time you initiate the migration. This allows you to change any aspect that doesn't impact guest ABI, so you can provide an updated emulator binary path at time of migration.
Actually there might be a problem with this. I've discussed this recently with Jirka.
Specifically the ABI stability check is done on the source of the migration. This means that the source has to actually parse and interpret the destination XML too if it's provided by the user.
Now if your source host doesn't have the qemu binary or doesn't have it in the path you have it on the destination this will fail.
I mentioned to Jirka that I think this is sub-optimal:
1) see problem above 2) the post-parse callbacks might fill in different defaults e.g. if the destination qemu has different capabilities 3) if it were done on destination, the source portion of the XML can be parsed without post-parse callbacks as it comes actually from a live libvirt instance
Right so we need to pass the XML to the dest, have its details expanded, then sent back to the src for ABI checking. Or alternatively just send the current live XML from src to dest, and let the dest do the ABI checking in the Prepare step.
So with the above if they have problem of qemu not being where they expect, using of the destination XML will not help.
Hmm, yes, annoying.
They might be able to use the hook script to filter it on the destination though:
With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
participants (3)
-
Daniel P. Berrangé
-
Peter Krempa
-
zhangjl02