提交 48605960 编写于 作者: H Hu Tao 提交者: Daniel Veillard

new command emulatorpin

上级 272570df
...@@ -4820,6 +4820,193 @@ parse_error: ...@@ -4820,6 +4820,193 @@ parse_error:
goto cleanup; 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 * "setvcpus" command
*/ */
...@@ -8252,6 +8439,7 @@ const vshCmdDef domManagementCmds[] = { ...@@ -8252,6 +8439,7 @@ const vshCmdDef domManagementCmds[] = {
{"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount, 0}, {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount, 0},
{"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo, 0}, {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo, 0},
{"vcpupin", cmdVcpuPin, opts_vcpupin, info_vcpupin, 0}, {"vcpupin", cmdVcpuPin, opts_vcpupin, info_vcpupin, 0},
{"emulatorpin", cmdEmulatorPin, opts_emulatorpin, info_emulatorpin, 0},
{"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay, 0}, {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay, 0},
{NULL, NULL, NULL, NULL, 0} {NULL, NULL, NULL, NULL, 0}
}; };
...@@ -1614,6 +1614,22 @@ If no flag is specified, behavior is different depending on hypervisor. ...@@ -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 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". 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> =item B<vncdisplay> I<domain>
Output the IP address and port number for the VNC display. If the information Output the IP address and port number for the VNC display. If the information
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册