Add a straightforward implementation for using the new APIs. --- tools/virsh-domain.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 10 ++++++ 2 files changed, 103 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index bd6db47..ff2305f 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -6762,6 +6762,93 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd) return ret; } + +/* + * "guestvcpus" command + */ +static const vshCmdInfo info_guestvcpus[] = { + {.name = "help", + .data = N_("query or modify state of vcpu in the guest (via agent)") + }, + {.name = "desc", + .data = N_("Use the guest agent to query or set cpu state from guest's " + "point of view") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_guestvcpus[] = { + VIRSH_COMMON_OPT_DOMAIN_FULL, + {.name = "cpumap", + .type = VSH_OT_STRING, + .help = N_("number of virtual CPUs") + }, + {.name = "enable", + .type = VSH_OT_BOOL, + .help = N_("enable cpus specified by cpumap") + }, + {.name = "disable", + .type = VSH_OT_BOOL, + .help = N_("disable cpus specified by cpumap") + }, + {.name = NULL} +}; + +static bool +cmdGuestvcpus(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + bool enable = vshCommandOptBool(cmd, "enable"); + bool disable = vshCommandOptBool(cmd, "disable"); + virTypedParameterPtr params = NULL; + unsigned int nparams = 0; + const char *cpumap = NULL; + int state = 0; + size_t i; + bool ret = false; + + VSH_EXCLUSIVE_OPTIONS_VAR(enable, disable); + VSH_REQUIRE_OPTION("enable", "cpumap"); + VSH_REQUIRE_OPTION("disable", "cpumap"); + + if (vshCommandOptStringReq(ctl, cmd, "cpumap", &cpumap)) + return false; + + if (cpumap && !(enable | disable)) { + vshError(ctl, _("One of options --enable or --disable is required by " + "option --cpumap")); + return false; + } + + if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (enable) + state = 1; + + if (cpumap) { + if (virDomainSetGuestVcpus(dom, cpumap, state, 0) < 0) + goto cleanup; + } else { + if (virDomainGetGuestVcpus(dom, ¶ms, &nparams, 0) < 0) + goto cleanup; + + for (i = 0; i < nparams; i++) { + char *str = vshGetTypedParamValue(ctl, ¶ms[i]); + vshPrint(ctl, "%-15s: %s\n", params[i].field, str); + VIR_FREE(str); + } + } + + ret = true; + + cleanup: + virTypedParamsFree(params, nparams); + virDomainFree(dom); + return ret; +} + + /* * "iothreadinfo" command */ @@ -13602,5 +13689,11 @@ const vshCmdDef domManagementCmds[] = { .info = info_vncdisplay, .flags = 0 }, + {.name = "guestvcpus", + .handler = cmdGuestvcpus, + .opts = opts_guestvcpus, + .info = info_guestvcpus, + .flags = 0 + }, {.name = NULL} }; diff --git a/tools/virsh.pod b/tools/virsh.pod index 8e3ba69..6af1328 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2501,6 +2501,16 @@ Both I<--live> and I<--config> flags may be given if I<cpulist> is present, but I<--current> is exclusive. If no flag is specified, behavior is different depending on hypervisor. +=item B<guestvcpus> I<domain> [[I<--enable>] | [I<--disable>]] [I<cpumap>] + +Query or change state of vCPUs from guest's point of view using the guest agent. +When invoked without I<cpumap> the guest is queried for available guest vCPUs, +their state and possibility to be offlined. + +If I<cpumap> is provided then one of I<--enable> or I<--disable> must be +provided too. The desired operation is then executed on the domain. + +See B<vcpupin> for I<cpumap> (as I<cpulist>). =item B<vncdisplay> I<domain> -- 2.8.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list