new command emulatorpin

This commit is contained in:
Hu Tao 2012-08-21 17:18:40 +08:00 committed by Daniel Veillard
parent 272570dffb
commit 4860596044
2 changed files with 204 additions and 0 deletions

View File

@ -4820,6 +4820,193 @@ parse_error:
goto cleanup;
}
/*
* "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;
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
*/
@ -8252,6 +8439,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}
};

View File

@ -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