Re: [libvirt] [PATCH 0/7] Keep non-persistent changes alive in snapshot
On Mon, 2017-10-30 at 14:21 +0530, Kothapally Madhu Pavan wrote: > Restoring to a snapshot should not overwrite the persistent XML > configuration > of a snapshot as a side effect. This patchset fixes the same. > Currently, > virDomainSnapshotDef only saves active domain definition of the > guest. > And on restore the active domain definition is used as both active > and > inactive domain definitions. This will make the non-persistent > changes > persistent in snapshot image. This patchset allows to save inactive > domain > definition as well and on snapshot-revert non-persistent > configuration is > restored as is. > > Currently, snapshot-revert is making non-presistent changes as > persistent. > Here are the steps to reproduce. > Step1: virsh define $dom > Step2: virsh attach-device $dom $memory-device.xml --live > Step3: virsh snapshot-create $dom > Step4: virsh destroy $dom > Step5: virsh snapshot-revert $dom $snapshot-name > Step6: virsh destroy $dom > Step7: virsh start $dom > Here we still have $memory-device attached in Step2. > > This patchset is attempting to solve this issue. This patchset will > also > allow user to dump and edit inactive XML configuration of a snapshot. > Dumping inactive domain definition of a snapshot is important as > --redefine uses snapshot-dumpxml output to redefine a snapshot. > > Kothapally Madhu Pavan (7): > qemu: Store inactive domain configuration in snapshot > qemu: Use active and inactive snapshot configuration on restore > conf: Allow editing inactive snapshot configuration > virsh: Dump inactive XML configuration of snapshot using > snapshot-dumpxml > virsh: Edit inactive XML configuration of snapshot using snapshot- > edit > virsh: Allow restoring snapshot with non-persistent configuration > tests: docs: Add schema and testcase for domainsnapshot > > docs/schemas/domainsnapshot.rng| 19 + > include/libvirt/libvirt-domain-snapshot.h | 10 ++- > include/libvirt/libvirt-domain.h | 1 + > src/conf/domain_conf.c | 6 +- > src/conf/domain_conf.h | 2 + > src/conf/snapshot_conf.c | 48 > - > src/conf/snapshot_conf.h | 1 + > src/qemu/qemu_driver.c | 33 - > .../full_domain_withinactive.xml | 83 > ++ > tests/domainsnapshotxml2xmltest.c | 1 + > tools/virsh-snapshot.c | 20 ++ > tools/virsh.pod| 37 +- > 12 files changed, 251 insertions(+), 10 deletions(-) > create mode 100644 > tests/domainsnapshotxml2xmlout/full_domain_withinactive.xml Could someone please review the patch set? Jiri mentioned in early December that it was on his list; perhaps this fell through the cracks or got displaced by the (admittedly more urgent) Spectre/Meltdown patches. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2] treat host models as case-insensitive strings
On Thu, 2018-01-11 at 11:19 -0500, John Ferlan wrote: > > On 12/26/2017 02:55 PM, Scott Garfinkle wrote: > > Qemu now allows case-insensitive specification of CPU models. This > > fixes the resulting problems on (at least) POWER arch machines. > > Would have been great to reference which qemu commit number, but > there's probably way too many. Perhaps best to note it's as of QEMU > 2.11. My quick search turns up "03c9141d75" and "4a12c699d", is that > about right? Thanks, next time I'll try to be more specific. Yes Qemu 2.11. The full patch series is at https://lists.gnu.org/archive/html/qemu-devel/2017-08/msg04651.html > > > > Patch V2: Change only the internal interface. This solves the > > actual problem at > > hand of reporting unsupported models now that qemu allows case- > > insensitive > > strings (e.g. "Power8" instead of "POWER8"). > > This hunk would typically go under the "---" below to give a hint to > the reviewer about what changed. ack > Hopefully no one someday decides POWER8 is more "powerful" than > Power8 ;-) (couldn't resist). groan :-) > > > > Signed-off-by: Scott Garfinkle <scott...@linux.vnet.ibm.com> > > --- > > src/conf/domain_capabilities.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > This seems like a reasonable way to approach the problem. I can fix > up the comment message a bit and will push later... Just want to make > sure that no one else comes up with a latent concern... The only > thing that springs to my mind is migration possibly. It seems to me that the in the worst we might be more permissive with the patch than without; I am hopeful for the sake of sanity that nobody actually has two model names disambiguated only by case! > Reviewed-by: John Ferlan <jfer...@redhat.com> > > John > > > diff --git a/src/conf/domain_capabilities.c > > b/src/conf/domain_capabilities.c > > index e7323a8..f7d9be5 100644 > > --- a/src/conf/domain_capabilities.c > > +++ b/src/conf/domain_capabilities.c > > @@ -271,7 +271,7 @@ > > virDomainCapsCPUModelsGet(virDomainCapsCPUModelsPtr cpuModels, > > return NULL; > > > > for (i = 0; i < cpuModels->nmodels; i++) { > > -if (STREQ(cpuModels->models[i].name, name)) > > +if (STRCASEEQ(cpuModels->models[i].name, name)) > > return cpuModels->models + i; > > } > > > > > > -- > libvir-list mailing list > libvir-list@redhat.com > https://www.redhat.com/mailman/listinfo/libvir-list > -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2] treat host models as case-insensitive strings
Qemu now allows case-insensitive specification of CPU models. This fixes the resulting problems on (at least) POWER arch machines. Patch V2: Change only the internal interface. This solves the actual problem at hand of reporting unsupported models now that qemu allows case-insensitive strings (e.g. "Power8" instead of "POWER8"). Signed-off-by: Scott Garfinkle <scott...@linux.vnet.ibm.com> --- src/conf/domain_capabilities.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index e7323a8..f7d9be5 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -271,7 +271,7 @@ virDomainCapsCPUModelsGet(virDomainCapsCPUModelsPtr cpuModels, return NULL; for (i = 0; i < cpuModels->nmodels; i++) { -if (STREQ(cpuModels->models[i].name, name)) +if (STRCASEEQ(cpuModels->models[i].name, name)) return cpuModels->models + i; } -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] treat host models as case-insensitive strings
On Tue, 2017-12-19 at 20:05 +0100, Jiri Denemark wrote: > On Tue, Dec 19, 2017 at 12:39:26 -0600, Scott Garfinkle wrote: > > Qemu now allows case-insensitive specification of CPU models. This fixes the > > resulting problems on POWER arch machines. I believe a similar change is > > needed > > in src/cpu/cpu_x86.c but I don't have a way to test this. > > I believe this change is not needed or even acceptable at all. What kind > of issue are you trying to solve? So, the problem is that as of qemu 2.11, Power arch guests don't start, since libvirt ppc code is looking for the string POWER to determine whether the system supports the model at hand. Comment from our qemu maintainer: "There was a rework in QEMU side to allow case-insensitive specification of CPU models. As a side-effect of that some models no longer show up as all caps in -cpu ? / query-cpu-definitions. This requires libvirt changes to avoid relying on specific capitalized models." Are you concerned that we SHOULD be looking for case-sensitive models in libvirt? Is this a problem absent qemu? -Scott -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] treat host models as case-insensitive strings
Qemu now allows case-insensitive specification of CPU models. This fixes the resulting problems on POWER arch machines. I believe a similar change is needed in src/cpu/cpu_x86.c but I don't have a way to test this. Signed-off-by: Scott Garfinkle <scott...@linux.vnet.ibm.com> --- src/conf/domain_capabilities.c | 2 +- src/cpu/cpu_ppc64.c| 16 src/internal.h | 1 + 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index e7323a8..f7d9be5 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -271,7 +271,7 @@ virDomainCapsCPUModelsGet(virDomainCapsCPUModelsPtr cpuModels, return NULL; for (i = 0; i < cpuModels->nmodels; i++) { -if (STREQ(cpuModels->models[i].name, name)) +if (STRCASEEQ(cpuModels->models[i].name, name)) return cpuModels->models + i; } diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c index 76582d4..9f7e2bb 100644 --- a/src/cpu/cpu_ppc64.c +++ b/src/cpu/cpu_ppc64.c @@ -67,10 +67,10 @@ static int virCPUppc64ConvertLegacy(virCPUDefPtr cpu) { if (cpu->model && -(STREQ(cpu->model, "POWER7_v2.1") || - STREQ(cpu->model, "POWER7_v2.3") || - STREQ(cpu->model, "POWER7+_v2.1") || - STREQ(cpu->model, "POWER8_v1.0"))) { +(STRCASEEQ(cpu->model, "POWER7_v2.1") || + STRCASEEQ(cpu->model, "POWER7_v2.3") || + STRCASEEQ(cpu->model, "POWER7+_v2.1") || + STRCASEEQ(cpu->model, "POWER8_v1.0"))) { cpu->model[strlen("POWERx")] = 0; } @@ -93,7 +93,7 @@ ppc64CheckCompatibilityMode(const char *host_model, return VIR_CPU_COMPARE_IDENTICAL; /* Valid host CPUs: POWER6, POWER7, POWER8, POWER9 */ -if (!STRPREFIX(host_model, "POWER") || +if (!STRCASEPREFIX(host_model, "POWER") || !(tmp = (char *) host_model + strlen("POWER")) || virStrToLong_i(tmp, NULL, 10, ) < 0 || host < 6 || host > 9) { @@ -104,7 +104,7 @@ ppc64CheckCompatibilityMode(const char *host_model, } /* Valid compatibility modes: power6, power7, power8, power9 */ -if (!STRPREFIX(compat_mode, "power") || +if (!STRCASEPREFIX(compat_mode, "power") || !(tmp = (char *) compat_mode + strlen("power")) || virStrToLong_i(tmp, NULL, 10, ) < 0 || compat < 6 || compat > 9) { @@ -168,7 +168,7 @@ ppc64VendorFind(const struct ppc64_map *map, size_t i; for (i = 0; i < map->nvendors; i++) { -if (STREQ(map->vendors[i]->name, name)) +if (STRCASEEQ(map->vendors[i]->name, name)) return map->vendors[i]; } @@ -216,7 +216,7 @@ ppc64ModelFind(const struct ppc64_map *map, size_t i; for (i = 0; i < map->nmodels; i++) { -if (STREQ(map->models[i]->name, name)) +if (STRCASEEQ(map->models[i]->name, name)) return map->models[i]; } diff --git a/src/internal.h b/src/internal.h index 5895030..1760e3b 100644 --- a/src/internal.h +++ b/src/internal.h @@ -75,6 +75,7 @@ # define STRNEQLEN(a, b, n) (strncmp(a, b, n) != 0) # define STRCASENEQLEN(a, b, n) (c_strncasecmp(a, b, n) != 0) # define STRPREFIX(a, b) (strncmp(a, b, strlen(b)) == 0) +# define STRCASEPREFIX(a, b) (c_strncasecmp(a, b, strlen(b)) == 0) # define STRSKIP(a, b) (STRPREFIX(a, b) ? (a) + strlen(b) : NULL) # define STREQ_NULLABLE(a, b) \ -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 4/4] docs: document migrate-getmaxdowntime support
--- docs/news.xml | 10 ++ 1 file changed, 10 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 26bd9bd..640e5f5 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -35,6 +35,16 @@ + + + qemu: Add migrate-getmaxdowntime command + + + Currently, the maximum tolerable downtime for a domain being migrated + is write-only from libvirt, via migrate-setmaxdowntime. This + implements a complementary migrate-getmaxdowntime command + + bhyve: Support autoport for VNC ports -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 2/4] qemu: Implement virDomainMigrateGetMaxDowntime
Add code to support querying maximum allowable downtime during live migration. --- src/qemu/qemu_driver.c | 58 src/qemu/qemu_monitor.h | 3 +++ src/qemu/qemu_monitor_json.c | 4 +++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 16 +++- src/remote_protocol-structs | 8 ++ 6 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e9f07c6..ca7f531 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13150,6 +13150,63 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom, return ret; } + +static int +qemuDomainMigrateGetMaxDowntime(virDomainPtr dom, +unsigned long long *downtime, +unsigned int flags) +{ +virQEMUDriverPtr driver = dom->conn->privateData; +virDomainObjPtr vm; +qemuDomainObjPrivatePtr priv; +qemuMonitorMigrationParams migparams; +int ret = -1; + +virCheckFlags(0, -1); + +if (!(vm = qemuDomObjFromDomain(dom))) +goto cleanup; + +if (virDomainMigrateGetMaxDowntimeEnsureACL(dom->conn, vm->def) < 0) +goto cleanup; + +if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0) +goto cleanup; + +if (!virDomainObjIsActive(vm)) { +virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); +goto endjob; +} + +priv = vm->privateData; +qemuDomainObjEnterMonitor(driver, vm); + +if (qemuMonitorGetMigrationParams(priv->mon, ) >= 0 && +migparams.downtimeLimit_set) +{ +*downtime = migparams.downtimeLimit; +ret = 0; +} + +if (ret < 0) { +virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("Querying migration downtime is not supported by " + "QEMU binary")); +} + +if (qemuDomainObjExitMonitor(driver, vm) < 0) +ret = -1; + + endjob: +qemuDomainObjEndJob(driver, vm); + + cleanup: +virDomainObjEndAPI(); +return ret; +} + + static int qemuDomainMigrateGetCompressionCache(virDomainPtr dom, unsigned long long *cacheSize, @@ -20829,6 +20886,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainGetJobInfo = qemuDomainGetJobInfo, /* 0.7.7 */ .domainGetJobStats = qemuDomainGetJobStats, /* 1.0.3 */ .domainAbortJob = qemuDomainAbortJob, /* 0.7.7 */ +.domainMigrateGetMaxDowntime = qemuDomainMigrateGetMaxDowntime, /* 3.7.0 */ .domainMigrateSetMaxDowntime = qemuDomainMigrateSetMaxDowntime, /* 0.8.0 */ .domainMigrateGetCompressionCache = qemuDomainMigrateGetCompressionCache, /* 1.0.3 */ .domainMigrateSetCompressionCache = qemuDomainMigrateSetCompressionCache, /* 1.0.3 */ diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 31f7e97..9805a33 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -627,6 +627,9 @@ struct _qemuMonitorMigrationParams { * whereas, some string value indicates we can support setting/clearing */ char *migrateTLSAlias; char *migrateTLSHostname; + +bool downtimeLimit_set; +unsigned long long downtimeLimit; }; int qemuMonitorGetMigrationParams(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index b8a6815..df5fb7c 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2705,6 +2705,10 @@ qemuMonitorJSONGetMigrationParams(qemuMonitorPtr mon, #undef PARSE +if (virJSONValueObjectGetNumberUlong(result, "downtime-limit", + >downtimeLimit) == 0) +params->downtimeLimit_set = true; + if ((tlsStr = virJSONValueObjectGetString(result, "tls-creds"))) { if (VIR_STRDUP(params->migrateTLSAlias, tlsStr) < 0) goto cleanup; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index a57d25f..027b073 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8400,6 +8400,7 @@ static virHypervisorDriver hypervisor_driver = { .domainGetJobInfo = remoteDomainGetJobInfo, /* 0.7.7 */ .domainGetJobStats = remoteDomainGetJobStats, /* 1.0.3 */ .domainAbortJob = remoteDomainAbortJob, /* 0.7.7 */ +.domainMigrateGetMaxDowntime = remoteDomainMigrateGetMaxDowntime, /* 3.7.0 */ .domainMigrateSetMaxDowntime = remoteDomainMigrateSetMaxDowntime, /* 0.8.0 */ .domainMigrateGetCompressionCache = remoteDomainMigrateGetCompressionCache, /* 1.0.3 */ .domainMigrateSetCompressionCache = remoteDomainMigrateSetCompressionCache, /* 1.0.3 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 0943208..2d49ceb 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2326,6 +2326,15 @@ struct remote_domain_abort_job_args { }; +struct
[libvirt] [PATCH v4 3/4] virsh: Add support for virDomainMigrateGetMaxDowntime
Implement a migrate-getmaxdowntime command to complement migrate-setmaxdowntime. --- tools/virsh-domain.c | 42 ++ tools/virsh.pod | 6 ++ 2 files changed, 48 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 40f1673..012c96e 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -10719,6 +10719,42 @@ cmdMigrateSetMaxDowntime(vshControl *ctl, const vshCmd *cmd) return ret; } + /* + * "migrate-getmaxdowntime" command + */ +static const vshCmdInfo info_migrate_getmaxdowntime[] = { +{.name = "help", + .data = N_("get maximum tolerable downtime") +}, +{.name = "desc", + .data = N_("Get maximum tolerable downtime of a domain which is being live-migrated to another host.") +}, +{.name = NULL} +}; + +static const vshCmdOptDef opts_migrate_getmaxdowntime[] = { +VIRSH_COMMON_OPT_DOMAIN_FULL, +{.name = NULL} +}; + +static bool +cmdMigrateGetMaxDowntime(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom; +unsigned long long downtime; +bool ret = false; + +if ((dom = virshCommandOptDomain(ctl, cmd, NULL)) != NULL) { +if (virDomainMigrateGetMaxDowntime(dom, , 0) >= 0) { +vshPrint(ctl, "%llu\n", downtime); +ret = true; +} +virshDomainFree(dom); +} + +return ret; +} + /* * "migrate-compcache" command */ @@ -13875,6 +13911,12 @@ const vshCmdDef domManagementCmds[] = { .info = info_migrate_setmaxdowntime, .flags = 0 }, +{.name = "migrate-getmaxdowntime", + .handler = cmdMigrateGetMaxDowntime, + .opts = opts_migrate_getmaxdowntime, + .info = info_migrate_getmaxdowntime, + .flags = 0 +}, {.name = "migrate-compcache", .handler = cmdMigrateCompCache, .opts = opts_migrate_compcache, diff --git a/tools/virsh.pod b/tools/virsh.pod index 43d6f0c..15a4143 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1857,6 +1857,12 @@ Set maximum tolerable downtime for a domain which is being live-migrated to another host. The I is a number of milliseconds the guest is allowed to be down at the end of live migration. +=item B I + +Get the maximum tolerable downtime for a domain which is being live-migrated to +another host. This is the number of milliseconds the guest is allowed +to be down at the end of live migration. + =item B I [I<--size> B] Sets and/or gets size of the cache (in bytes) used for compressing repeatedly -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 0/4] Implement migrate-getmaxdowntime command
Currently, the maximum tolerable downtime for a domain being migrated is write-only. This patch implements a way to query that value nondestructively. I've tried to incorporate the feedback from v3; however, I've left alone a couple of places where the feedback would have diverged from parallelism with the existing migrate-setdowntime help/info. Also, since the main use of this new command is likely to be (as in virt-manager) in combination with migrate-setmaxdowntime, I don't think it's going to really help to add an options to report this in some other unit other than milliseconds. To-do: Ought to revisit setmaxdowntime to use the new preferred qemu interface. Changes from [v3]: * Incorporated suggestions, including adding an error message * Added a patch to the news.xml file [v1} https://www.redhat.com/archives/libvir-list/2017-July/msg00908.html [v2} https://www.redhat.com/archives/libvir-list/2017-July/msg01010.html [v3} https://www.redhat.com/archives/libvir-list/2017-July/msg01301.html Scott Garfinkle (4) Add virDomainMigrateGetMaxDowntime public API qemu: Implement virDomainMigrateGetMaxDowntime virsh: Add support for virDomainMigrateGetMaxDowntime docs: document migrate-getmaxdowntime support --- docs/news.xml| 10 +++ include/libvirt/libvirt-domain.h | 4 +++ src/driver-hypervisor.h | 6 + src/libvirt-domain.c | 41 src/libvirt_public.syms | 4 +++ src/qemu/qemu_driver.c | 58 src/qemu/qemu_monitor.h | 3 +++ src/qemu/qemu_monitor_json.c | 4 +++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 16 ++- src/remote_protocol-structs | 8 ++ tools/virsh-domain.c | 42 + tools/virsh.pod | 6 + 13 files changed, 202 insertions(+), 1 deletion(-) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 1/4] Add virDomainMigrateGetMaxDowntime public API
Add virDomainMigrateGetMaxDowntime to support querying maximum allowable downtime during live migration. --- include/libvirt/libvirt-domain.h | 4 src/driver-hypervisor.h | 6 ++ src/libvirt-domain.c | 41 src/libvirt_public.syms | 4 4 files changed, 55 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index a3bb9cb..fae24ac 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1039,6 +1039,10 @@ int virDomainMigrateToURI3(virDomainPtr domain, unsigned int nparams, unsigned int flags); +int virDomainMigrateGetMaxDowntime(virDomainPtr domain, + unsigned long long *downtime, + unsigned int flags); + int virDomainMigrateSetMaxDowntime (virDomainPtr domain, unsigned long long downtime, unsigned int flags); diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 3053d7a..7b35e9e 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -697,6 +697,11 @@ typedef int (*virDrvDomainAbortJob)(virDomainPtr domain); typedef int +(*virDrvDomainMigrateGetMaxDowntime)(virDomainPtr domain, + unsigned long long *downtime, + unsigned int flags); + +typedef int (*virDrvDomainMigrateSetMaxDowntime)(virDomainPtr domain, unsigned long long downtime, unsigned int flags); @@ -1412,6 +1417,7 @@ struct _virHypervisorDriver { virDrvDomainGetJobInfo domainGetJobInfo; virDrvDomainGetJobStats domainGetJobStats; virDrvDomainAbortJob domainAbortJob; +virDrvDomainMigrateGetMaxDowntime domainMigrateGetMaxDowntime; virDrvDomainMigrateSetMaxDowntime domainMigrateSetMaxDowntime; virDrvDomainMigrateGetCompressionCache domainMigrateGetCompressionCache; virDrvDomainMigrateSetCompressionCache domainMigrateSetCompressionCache; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 87fca29..4d0ac30 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -8777,6 +8777,47 @@ virDomainMigrateSetMaxDowntime(virDomainPtr domain, /** + * virDomainMigrateGetMaxDowntime: + * @domain: a domain object + * @downtime: return value of the maximum tolerable downtime for live + *migration, in milliseconds + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Gets current maximum tolerable time for which the domain may be paused + * at the end of live migration. + * + * Returns 0 in case of success, -1 otherwise. + */ +int +virDomainMigrateGetMaxDowntime(virDomainPtr domain, + unsigned long long *downtime, + unsigned int flags) +{ +virConnectPtr conn; + +VIR_DOMAIN_DEBUG(domain, "downtime = %p, flags=%x", downtime, flags); + +virResetLastError(); + +virCheckDomainReturn(domain, -1); +conn = domain->conn; + +virCheckNonNullArgGoto(downtime, error); + +if (conn->driver->domainMigrateGetMaxDowntime) { +if (conn->driver->domainMigrateGetMaxDowntime(domain, downtime, flags) < 0) +goto error; +return 0; +} + +virReportUnsupportedError(); + error: +virDispatchError(conn); +return -1; +} + + +/** * virDomainMigrateGetCompressionCache: * @domain: a domain object * @cacheSize: return value of current size of the cache (in bytes) diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index fac77fb..b55ca4b 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -768,4 +768,8 @@ LIBVIRT_3.4.0 { virStreamSparseSendAll; } LIBVIRT_3.1.0; +LIBVIRT_3.7.0 { +global: +virDomainMigrateGetMaxDowntime; +} LIBVIRT_3.4.0; # define new API here using predicted next version number -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] Request for review: [PATCH v3 0/3] implement migrate-getmaxdowntime command
I think this may have gotten lost in the 3.6 release. Does someone have the time to review this, please? The patches still apply cleanly (albeit with fuzz) at the current level. -Scott Garfinkle -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 2/3] qemu: Implement virDomainMigrateGetMaxDowntime
From: Scott Garfinkle <s...@us.ibm.com> --- src/qemu/qemu_driver.c | 51 src/qemu/qemu_monitor.h | 3 +++ src/qemu/qemu_monitor_json.c | 4 src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 16 +- src/remote_protocol-structs | 8 +++ 6 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f7b4cc3..8b8ae57 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13147,6 +13147,56 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom, return ret; } + +static int +qemuDomainMigrateGetMaxDowntime(virDomainPtr dom, +unsigned long long *downtime, +unsigned int flags) +{ +virQEMUDriverPtr driver = dom->conn->privateData; +virDomainObjPtr vm; +qemuDomainObjPrivatePtr priv; +qemuMonitorMigrationParams migparams; +int ret = -1; + +virCheckFlags(0, -1); + +if (!(vm = qemuDomObjFromDomain(dom))) +goto cleanup; + +if (virDomainMigrateGetMaxDowntimeEnsureACL(dom->conn, vm->def) < 0) +goto cleanup; + +if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0) +goto cleanup; + +if (!virDomainObjIsActive(vm)) { +virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); +goto endjob; +} + +priv = vm->privateData; +qemuDomainObjEnterMonitor(driver, vm); + +if (!(ret = qemuMonitorGetMigrationParams(priv->mon, ))) { +if (migparams.downtimeLimit_set) +*downtime = migparams.downtimeLimit; +else +ret = -1; +} + +if (qemuDomainObjExitMonitor(driver, vm) < 0) +ret = -1; + + endjob: +qemuDomainObjEndJob(driver, vm); + + cleanup: +virDomainObjEndAPI(); +return ret; +} + static int qemuDomainMigrateGetCompressionCache(virDomainPtr dom, unsigned long long *cacheSize, @@ -20826,6 +20876,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainGetJobInfo = qemuDomainGetJobInfo, /* 0.7.7 */ .domainGetJobStats = qemuDomainGetJobStats, /* 1.0.3 */ .domainAbortJob = qemuDomainAbortJob, /* 0.7.7 */ +.domainMigrateGetMaxDowntime = qemuDomainMigrateGetMaxDowntime, /* 3.6.0 */ .domainMigrateSetMaxDowntime = qemuDomainMigrateSetMaxDowntime, /* 0.8.0 */ .domainMigrateGetCompressionCache = qemuDomainMigrateGetCompressionCache, /* 1.0.3 */ .domainMigrateSetCompressionCache = qemuDomainMigrateSetCompressionCache, /* 1.0.3 */ diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 31f7e97..9805a33 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -627,6 +627,9 @@ struct _qemuMonitorMigrationParams { * whereas, some string value indicates we can support setting/clearing */ char *migrateTLSAlias; char *migrateTLSHostname; + +bool downtimeLimit_set; +unsigned long long downtimeLimit; }; int qemuMonitorGetMigrationParams(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index b8a6815..b7b809d 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2703,6 +2703,10 @@ qemuMonitorJSONGetMigrationParams(qemuMonitorPtr mon, PARSE(cpuThrottleInitial, "cpu-throttle-initial"); PARSE(cpuThrottleIncrement, "cpu-throttle-increment"); +if (virJSONValueObjectGetNumberUlong(result, "downtime-limit", + >downtimeLimit) == 0) +params->downtimeLimit_set = true; + #undef PARSE if ((tlsStr = virJSONValueObjectGetString(result, "tls-creds"))) { diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index a57d25f..aa8d8a1 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8400,6 +8400,7 @@ static virHypervisorDriver hypervisor_driver = { .domainGetJobInfo = remoteDomainGetJobInfo, /* 0.7.7 */ .domainGetJobStats = remoteDomainGetJobStats, /* 1.0.3 */ .domainAbortJob = remoteDomainAbortJob, /* 0.7.7 */ +.domainMigrateGetMaxDowntime = remoteDomainMigrateGetMaxDowntime, /* 3.6.0 */ .domainMigrateSetMaxDowntime = remoteDomainMigrateSetMaxDowntime, /* 0.8.0 */ .domainMigrateGetCompressionCache = remoteDomainMigrateGetCompressionCache, /* 1.0.3 */ .domainMigrateSetCompressionCache = remoteDomainMigrateSetCompressionCache, /* 1.0.3 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index aa0aa38..e1f4e27 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2326,6 +2326,15 @@ struct remote_domain_abort_job_args { }; +struct remote_domain_migrate_get_max_downtime_args { +remote_nonnull_domain dom; +unsigned int flags; +}
[libvirt] [PATCH v3 3/3] virsh: Add support for virDomainMigrateGetMaxDowntime
From: Scott Garfinkle <s...@us.ibm.com> --- tools/virsh-domain.c | 46 ++ tools/virsh.pod | 18 ++ 2 files changed, 64 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 0684979..10fdd0f 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -10720,6 +10720,46 @@ cmdMigrateSetMaxDowntime(vshControl *ctl, const vshCmd *cmd) } /* + * "migrate-getmaxdowntime" command + */ +static const vshCmdInfo info_migrate_getmaxdowntime[] = { +{.name = "help", + .data = N_("get maximum tolerable downtime") +}, +{.name = "desc", + .data = N_("Get maximum tolerable downtime (in milliseconds)for a domain which is being live-migrated to another host.") +}, +{.name = NULL} +}; + +static const vshCmdOptDef opts_migrate_getmaxdowntime[] = { +VIRSH_COMMON_OPT_DOMAIN_FULL, +{.name = NULL} +}; + +static bool +cmdMigrateGetMaxDowntime(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom = NULL; +unsigned long long downtime; +bool ret = false; + +if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) +return false; + +if (virDomainMigrateGetMaxDowntime(dom, , 0)) +goto done; + +vshPrint(ctl, "%llu\n", downtime); + +ret = true; + + done: +virshDomainFree(dom); +return ret; +} + +/* * "migrate-compcache" command */ static const vshCmdInfo info_migrate_compcache[] = { @@ -13845,6 +13885,12 @@ const vshCmdDef domManagementCmds[] = { .info = info_migrate_setmaxdowntime, .flags = 0 }, +{.name = "migrate-getmaxdowntime", + .handler = cmdMigrateGetMaxDowntime, + .opts = opts_migrate_getmaxdowntime, + .info = info_migrate_getmaxdowntime, + .flags = 0 +}, {.name = "migrate-compcache", .handler = cmdMigrateCompCache, .opts = opts_migrate_compcache, diff --git a/tools/virsh.pod b/tools/virsh.pod index 43d6f0c..fc0a46c 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1869,6 +1869,24 @@ is supposed to be used while the domain is being live-migrated as a reaction to migration progress and increasing number of compression cache misses obtained from domjobinfo. +=item B I + +Get the maximum tolerable downtime for a domain which is being live-migrated to +another host. This is the number of milliseconds the guest is allowed +to be down at the end of live migration. + +=item B I [I<--size> B] + +Sets and/or gets size of the cache (in bytes) used for compressing repeatedly +transferred memory pages during live migration. When called without I, +the command just prints current size of the compression cache. When I +is specified, the hypervisor is asked to change compression cache to I +bytes and then the current size is printed (the result may differ from the +requested size due to rounding done by the hypervisor). The I option +is supposed to be used while the domain is being live-migrated as a reaction +to migration progress and increasing number of compression cache misses +obtained from domjobinfo. + =item B I I Set the maximum migration bandwidth (in MiB/s) for a domain which is being -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 0/3] implement migrate-getmaxdowntime command
Currently, the maximum tolerable downtime for a domain being migrated is write-only. This patch implements a way to query that value nondestructively. Changes from [v2]: * Resequenced and renamed patches * Use updated qemuMonitorJSONGetMigrationParams for querying migration parameters. [v1} https://www.redhat.com/archives/libvir-list/2017-July/msg00908.html [v2} https://www.redhat.com/archives/libvir-list/2017-July/msg01010.html Scott Garfinkle (3) Add virDomainMigrateGetMaxDowntime public API qemu: Implement virDomainMigrateGetMaxDowntime virsh: Add support for virDomainMigrateGetMaxDowntime --- include/libvirt/libvirt-domain.h | 4 src/driver-hypervisor.h | 6 ++ src/libvirt-domain.c | 45 src/libvirt_public.syms | 4 src/qemu/qemu_driver.c | 51 src/qemu/qemu_monitor.h | 3 +++ src/qemu/qemu_monitor_json.c | 4 src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 16 +- src/remote_protocol-structs | 8 +++ tools/virsh-domain.c | 46 ++ tools/virsh.pod | 18 ++ 12 files changed, 205 insertions(+), 1 deletion(-) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 1/3] Add virDomainMigrateGetMaxDowntime public API
From: Scott Garfinkle <s...@us.ibm.com> --- include/libvirt/libvirt-domain.h | 4 src/driver-hypervisor.h | 6 ++ src/libvirt-domain.c | 45 src/libvirt_public.syms | 4 4 files changed, 59 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index a3bb9cb..22618b0 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1043,6 +1043,10 @@ int virDomainMigrateSetMaxDowntime (virDomainPtr domain, unsigned long long downtime, unsigned int flags); +int virDomainMigrateGetMaxDowntime (virDomainPtr domain, +unsigned long long *downtime, +unsigned int flags); + int virDomainMigrateGetCompressionCache(virDomainPtr domain, unsigned long long *cacheSize, unsigned int flags); diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 3053d7a..7d32cad 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -702,6 +702,11 @@ typedef int unsigned int flags); typedef int +(*virDrvDomainMigrateGetMaxDowntime)(virDomainPtr domain, + unsigned long long *downtime, + unsigned int flags); + +typedef int (*virDrvDomainMigrateGetCompressionCache)(virDomainPtr domain, unsigned long long *cacheSize, unsigned int flags); @@ -1412,6 +1417,7 @@ struct _virHypervisorDriver { virDrvDomainGetJobInfo domainGetJobInfo; virDrvDomainGetJobStats domainGetJobStats; virDrvDomainAbortJob domainAbortJob; +virDrvDomainMigrateGetMaxDowntime domainMigrateGetMaxDowntime; virDrvDomainMigrateSetMaxDowntime domainMigrateSetMaxDowntime; virDrvDomainMigrateGetCompressionCache domainMigrateGetCompressionCache; virDrvDomainMigrateSetCompressionCache domainMigrateSetCompressionCache; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 4033ae8..b78ea1c 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -8781,6 +8781,51 @@ virDomainMigrateSetMaxDowntime(virDomainPtr domain, /** + * virDomainMigrateGetMaxDowntime: + * @domain: a domain object + * @downtime: return value of the maximum tolerable downtime for live + *migration, in milliseconds + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Gets current maximum tolerable time for which the domain may be paused + * at the end of live migration. It's supposed to be called while the domain is + * being live-migrated as a reaction to migration progress. + * + * Returns 0 in case of success, -1 otherwise. + */ +int +virDomainMigrateGetMaxDowntime(virDomainPtr domain, + unsigned long long *downtime, + unsigned int flags) +{ +virConnectPtr conn; + +VIR_DOMAIN_DEBUG(domain, "downtime = %p, flags=%x", downtime, flags); + +virResetLastError(); + +virCheckDomainReturn(domain, -1); +conn = domain->conn; + +virCheckNonNullArgGoto(downtime, error); + +/* unlike SetMaxDowntime, it's okay for the connection to be readonly */ + +if (conn->driver->domainMigrateGetMaxDowntime) { +if (conn->driver->domainMigrateGetMaxDowntime(domain, + downtime, flags) < 0) +goto error; +return 0; +} + +virReportUnsupportedError(); + error: +virDispatchError(conn); +return -1; +} + + +/** * virDomainMigrateGetCompressionCache: * @domain: a domain object * @cacheSize: return value of current size of the cache (in bytes) diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index fac77fb..da5692a 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -768,4 +768,8 @@ LIBVIRT_3.4.0 { virStreamSparseSendAll; } LIBVIRT_3.1.0; +LIBVIRT_3.6.0 { +global: +virDomainMigrateGetMaxDowntime; +} LIBVIRT_3.4.0; # define new API here using predicted next version number -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2] Generate unique socket file
It's possible to have more than one unnamed virtio-serial unix channel. We need to generate a unique name for each channel. Currently, we use ".../unknown.sock" for all of them. Better practice would be to specify an explicit target path name; however, in the absence of that, we need uniqueness in the names we generate internally. Before the changes we'd get /var/lib/libvirt/qemu/channel/target/unknown.sock for each instance of Now, we get vioser-00-00-01.sock, vioser-00-00-02.sock, etc. Changes from v1: new socket name Signed-off-by: Scott Garfinkle <s...@us.ibm.com> --- src/qemu/qemu_domain.c | 24 +++--- .../qemuxml2argv-channel-virtio-unix.args | 2 +- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 78e75f1..7a9958d 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -7178,18 +7178,28 @@ int qemuDomainPrepareChannel(virDomainChrDefPtr channel, const char *domainChannelTargetDir) { -if (channel->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO && -channel->source->type == VIR_DOMAIN_CHR_TYPE_UNIX && -!channel->source->data.nix.path) { +if (channel->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO || +channel->source->type != VIR_DOMAIN_CHR_TYPE_UNIX || +channel->source->data.nix.path) +return 0; + +if (channel->target.name) { if (virAsprintf(>source->data.nix.path, "%s/%s", domainChannelTargetDir, -channel->target.name ? channel->target.name -: "unknown.sock") < 0) +channel->target.name) < 0) +return -1; +} else {// Generate a unique name +if (virAsprintf(>source->data.nix.path, +"%s/vioser-%02d-%02d-%02d.sock", +domainChannelTargetDir, +channel->info.addr.vioserial.controller, +channel->info.addr.vioserial.bus, +channel->info.addr.vioserial.port) < 0) return -1; - -channel->source->data.nix.listen = true; } +channel->source->data.nix.listen = true; + return 0; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args index 2b72965..8e0452a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args @@ -29,7 +29,7 @@ path=/tmp/channel/domain--1-QEMUGuest1/org.qemu.guest_agent.0,server,nowait \ -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\ id=channel0,name=org.qemu.guest_agent.0 \ -chardev socket,id=charchannel1,\ -path=/tmp/channel/domain--1-QEMUGuest1/unknown.sock,server,nowait \ +path=/tmp/channel/domain--1-QEMUGuest1/vioser-00-00-02.sock,server,nowait \ -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,\ id=channel1 \ -chardev socket,id=charchannel2,path=/tmp/channel/domain--1-QEMUGuest1/ble,\ -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Use unsigned timeout in cmdMigrateSetMaxDowntime
John Ferlan <jfer...@redhat.com> wrote on 07/10/2017 06:41:34 AM: > From: John Ferlan <jfer...@redhat.com> > To: Scott Garfinkle <s...@us.ibm.com>, libvir-list@redhat.com > Date: 07/10/2017 06:41 AM > Subject: Re: [libvirt] [PATCH] Use unsigned timeout in > cmdMigrateSetMaxDowntime > > > > On 06/27/2017 11:19 AM, Scott Garfinkle wrote: > > While looking to implement a migrate-getmaxdowntime command (coming), > > I noticed that the setmaxdowntime is incorrectly looking at its > > parameter as a signed longlong. Not sure how that got past gcc, but > > here's a simple patch to make the command line parsing and the parameter to > > the worker functions all have the correct (unsigned) type. > > > > Signed-off-by: Scott Garfinkle <s...@us.ibm.com> > > --- > > tools/virsh-domain.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > "For some commands" allowing a -1 provides a mechanism to set an almost > infinite time without having to type such a large value. Still in this > case since, the "downtime < 1" check immediately follows it seems that > wouldn't be the case here! Yes, and maybe removing that check would have been a better alternative? Still, thanks. > Looking at QEMU code briefly - I do note the QEMU set downtime (and > speed) commands that end up getting called are listed as "deprecated" in > favor of migrate-set-parameters (downtime-limit and max-bandwidth, since > QEMU 2.8). So while you're at thinking about a getmaxdowntime type > functionality maybe you'd want to give that a go as well (of course > you'd have to add capabilities to detect when it was implemented using > set-parameters)... Thanks for pointing that out. So, I have patches to implement the get-maxdowntime, which would seem to be a separate but related effort. Being a newcomer to the code, I'll what are probably obvious questions: is the concern that qemu will eventually just stop providing that interface? Or, is there something inherently useful about changing the set-* commands? Otherwise, I'm not sure what the value to the code is of changing the already-working set commands. regards, Scott Garfinkle -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Use unsigned timeout in cmdMigrateSetMaxDowntime
While looking to implement a migrate-getmaxdowntime command (coming), I noticed that the setmaxdowntime is incorrectly looking at its parameter as a signed longlong. Not sure how that got past gcc, but here's a simple patch to make the command line parsing and the parameter to the worker functions all have the correct (unsigned) type. Signed-off-by: Scott Garfinkle <s...@us.ibm.com> --- tools/virsh-domain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 5311a57..0d21fe7 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -10696,13 +10696,13 @@ static bool cmdMigrateSetMaxDowntime(vshControl *ctl, const vshCmd *cmd) { virDomainPtr dom = NULL; -long long downtime = 0; +unsigned long long downtime = 0; bool ret = false; if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) return false; -if (vshCommandOptLongLong(ctl, cmd, "downtime", ) < 0) +if (vshCommandOptULongLong(ctl, cmd, "downtime", ) < 0) goto done; if (downtime < 1) { vshError(ctl, "%s", _("migrate: Invalid downtime")); -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list