[libvirt] [PATCH v2.1 17/21] new command emulatorpin
Daniel Veillard
veillard at redhat.com
Wed Aug 22 08:45:38 UTC 2012
On Tue, Aug 21, 2012 at 05:18:40PM +0800, Hu Tao wrote:
> ---
> tools/virsh-domain.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++
> tools/virsh.pod | 16 +++++
> 2 files changed, 204 insertions(+)
>
> diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
> index 047d374..95015ad 100644
> --- a/tools/virsh-domain.c
> +++ b/tools/virsh-domain.c
> @@ -4769,6 +4769,193 @@ parse_error:
> }
>
> /*
> + * "emulatorpin" command
> + */
> +static const vshCmdInfo info_emulatorpin[] = {
> + {"help", N_("control or query domain emulator affinity")},
> + {"desc", N_("Pin domain emulator threads to host physical CPUs.")},
> + {NULL, NULL}
> +};
> +
> +static const vshCmdOptDef opts_emulatorpin[] = {
> + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
> + {"cpulist", VSH_OT_DATA, VSH_OFLAG_EMPTY_OK,
> + N_("host cpu number(s) to set, or omit option to query")},
> + {"config", VSH_OT_BOOL, 0, N_("affect next boot")},
> + {"live", VSH_OT_BOOL, 0, N_("affect running domain")},
> + {"current", VSH_OT_BOOL, 0, N_("affect current domain")},
> + {NULL, 0, 0, NULL}
> +};
> +
> +static bool
> +cmdEmulatorPin(vshControl *ctl, const vshCmd *cmd)
> +{
> + virDomainPtr dom;
> + virNodeInfo nodeinfo;
> + const char *cpulist = NULL;
> + bool ret = true;
> + unsigned char *cpumap = NULL;
> + unsigned char *cpumaps = NULL;
> + size_t cpumaplen;
> + int i, cpu, lastcpu, maxcpu;
> + bool unuse = false;
> + const char *cur;
> + bool config = vshCommandOptBool(cmd, "config");
> + bool live = vshCommandOptBool(cmd, "live");
> + bool current = vshCommandOptBool(cmd, "current");
> + bool query = false; /* Query mode if no cpulist */
> + unsigned int flags = 0;
> +
> + if (current) {
> + if (live || config) {
> + vshError(ctl, "%s", _("--current must be specified exclusively"));
> + return false;
> + }
> + flags = VIR_DOMAIN_AFFECT_CURRENT;
> + } else {
> + if (config)
> + flags |= VIR_DOMAIN_AFFECT_CONFIG;
> + if (live)
> + flags |= VIR_DOMAIN_AFFECT_LIVE;
> + /* neither option is specified */
> + if (!live && !config)
> + flags = -1;
> + }
> +
> + if (!vshConnectionUsability(ctl, ctl->conn))
> + return false;
> +
> + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
> + return false;
> +
> + if (vshCommandOptString(cmd, "cpulist", &cpulist) < 0) {
> + vshError(ctl, "%s", _("emulatorpin: Missing cpulist."));
> + virDomainFree(dom);
> + return false;
> + }
> + query = !cpulist;
> +
> + if (virNodeGetInfo(ctl->conn, &nodeinfo) != 0) {
> + virDomainFree(dom);
> + return false;
> + }
> +
> + maxcpu = VIR_NODEINFO_MAXCPUS(nodeinfo);
> + cpumaplen = VIR_CPU_MAPLEN(maxcpu);
> +
> + /* Query mode: show CPU affinity information then exit.*/
> + if (query) {
> + /* When query mode and neither "live", "config" nor "current"
> + * is specified, set VIR_DOMAIN_AFFECT_CURRENT as flags */
> + if (flags == -1)
> + flags = VIR_DOMAIN_AFFECT_CURRENT;
> +
> + cpumaps = vshMalloc(ctl, cpumaplen);
> + if (virDomainGetEmulatorPinInfo(dom, cpumaps,
> + cpumaplen, flags) >= 0) {
> + vshPrint(ctl, "%s %s\n", _("emulator:"), _("CPU Affinity"));
> + vshPrint(ctl, "----------------------------------\n");
> + vshPrint(ctl, " *: ");
> + ret = vshPrintPinInfo(cpumaps, cpumaplen, maxcpu, 0);
> + vshPrint(ctl, "\n");
> + } else {
> + ret = false;
> + }
> + VIR_FREE(cpumaps);
> + goto cleanup;
> + }
> +
> + /* Pin mode: pinning emulator threads to specified physical cpus*/
> +
> + cpumap = vshCalloc(ctl, cpumaplen, sizeof(cpumap));
> + /* Parse cpulist */
> + cur = cpulist;
> + if (*cur == 0) {
> + goto parse_error;
> + } else if (*cur == 'r') {
> + for (cpu = 0; cpu < maxcpu; cpu++)
> + VIR_USE_CPU(cpumap, cpu);
> + cur = "";
> + }
> +
> + while (*cur != 0) {
> +
> + /* the char '^' denotes exclusive */
> + if (*cur == '^') {
> + cur++;
> + unuse = true;
> + }
> +
> + /* parse physical CPU number */
> + if (!c_isdigit(*cur))
> + goto parse_error;
That test looks redundant to me as virParseNumber will do that check
and return -1 if it fails. I think we can remove those 2 lines and just
trust virParseNumber() , but since that check is done in cmdVcpuPin()
I will let that as a later cleanup for both
> + cpu = virParseNumber(&cur);
> + if (cpu < 0) {
> + goto parse_error;
> + }
> + if (cpu >= maxcpu) {
> + vshError(ctl, _("Physical CPU %d doesn't exist."), cpu);
> + goto parse_error;
> + }
> + virSkipSpaces(&cur);
> +
> + if (*cur == ',' || *cur == 0) {
> + if (unuse) {
> + VIR_UNUSE_CPU(cpumap, cpu);
> + } else {
> + VIR_USE_CPU(cpumap, cpu);
> + }
> + } else if (*cur == '-') {
> + /* the char '-' denotes range */
> + if (unuse) {
> + goto parse_error;
> + }
> + cur++;
> + virSkipSpaces(&cur);
> + /* parse the end of range */
> + lastcpu = virParseNumber(&cur);
> + if (lastcpu < cpu) {
> + goto parse_error;
> + }
> + if (lastcpu >= maxcpu) {
> + vshError(ctl, _("Physical CPU %d doesn't exist."), maxcpu);
> + goto parse_error;
> + }
> + for (i = cpu; i <= lastcpu; i++) {
> + VIR_USE_CPU(cpumap, i);
> + }
> + virSkipSpaces(&cur);
> + }
> +
> + if (*cur == ',') {
> + cur++;
> + virSkipSpaces(&cur);
> + unuse = false;
> + } else if (*cur == 0) {
> + break;
> + } else {
> + goto parse_error;
> + }
> + }
> +
> + if (flags == -1)
> + flags = VIR_DOMAIN_AFFECT_LIVE;
> +
> + if (virDomainPinEmulator(dom, cpumap, cpumaplen, flags) != 0)
> + ret = false;
> +
> +cleanup:
> + VIR_FREE(cpumap);
> + virDomainFree(dom);
> + return ret;
> +
> +parse_error:
> + vshError(ctl, "%s", _("cpulist: Invalid format."));
> + ret = false;
> + goto cleanup;
> +}
> +
> +/*
> * "setvcpus" command
> */
> static const vshCmdInfo info_setvcpus[] = {
> @@ -8200,6 +8387,7 @@ const vshCmdDef domManagementCmds[] = {
> {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount, 0},
> {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo, 0},
> {"vcpupin", cmdVcpuPin, opts_vcpupin, info_vcpupin, 0},
> + {"emulatorpin", cmdEmulatorPin, opts_emulatorpin, info_emulatorpin, 0},
> {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay, 0},
> {NULL, NULL, NULL, NULL, 0}
> };
> diff --git a/tools/virsh.pod b/tools/virsh.pod
> index 35613c4..ec3c331 100644
> --- a/tools/virsh.pod
> +++ b/tools/virsh.pod
> @@ -1614,6 +1614,22 @@ If no flag is specified, behavior is different depending on hypervisor.
> B<Note>: The expression is sequentially evaluated, so "0-15,^8" is
> identical to "9-14,0-7,15" but not identical to "^8,0-15".
>
> +=item B<emulatorpin> I<domain> [I<cpulist>] [[I<--live>] [I<--config>]
> + | [I<--current>]]
> +
> +Query or change the pinning of domain's emulator threads to host physical
> +CPUs.
> +
> +See B<vcpupin> for I<cpulist>.
> +
> +If I<--live> is specified, affect a running guest.
> +If I<--config> is specified, affect the next boot of a persistent guest.
> +If I<--current> is specified, affect the current guest state.
> +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<vncdisplay> I<domain>
>
> Output the IP address and port number for the VNC display. If the information
ACK, looks fine
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list