[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