mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-14 08:35:15 +00:00
vcpupin: improve vcpupin definition of virsh vcpupin
When using vcpupin command, we have to speficy comma-separated list as cpulist, but this is tedious in case the number of phsycal cpus is large. This patch improves this by introducing special markup "-" and "^" which are similar to XML schema of "cpuset" attribute. The example: # virsh vcpupin Guest 0 0-15,^8 is identical to # virsh vcpupin Guest 0 0,1,2,3,4,5,6,7,9,10,11,12,13,14,15 NOTE: The expression is sequentially evaluated, so "0-15,^8" is not identical to "^8,0-15". Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
This commit is contained in:
parent
d967a8bfa4
commit
2903534a30
129
tools/virsh.c
129
tools/virsh.c
@ -2998,8 +2998,9 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
|
|||||||
bool ret = true;
|
bool ret = true;
|
||||||
unsigned char *cpumap;
|
unsigned char *cpumap;
|
||||||
int cpumaplen;
|
int cpumaplen;
|
||||||
int i;
|
int i, cpu, lastcpu, maxcpu;
|
||||||
enum { expect_num, expect_num_or_comma } state;
|
bool unuse = false;
|
||||||
|
char *cur;
|
||||||
int config = vshCommandOptBool(cmd, "config");
|
int config = vshCommandOptBool(cmd, "config");
|
||||||
int live = vshCommandOptBool(cmd, "live");
|
int live = vshCommandOptBool(cmd, "live");
|
||||||
int current = vshCommandOptBool(cmd, "current");
|
int current = vshCommandOptBool(cmd, "current");
|
||||||
@ -3055,66 +3056,74 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the cpulist parameter is a comma-separated list of
|
maxcpu = VIR_NODEINFO_MAXCPUS(nodeinfo);
|
||||||
* numbers and give an intelligent error message if not.
|
cpumaplen = VIR_CPU_MAPLEN(maxcpu);
|
||||||
*/
|
cpumap = vshCalloc(ctl, 0, cpumaplen);
|
||||||
if (cpulist[0] == '\0') {
|
|
||||||
vshError(ctl, "%s", _("cpulist: Invalid format. Empty string."));
|
/* Parse cpulist */
|
||||||
virDomainFree (dom);
|
cur = cpulist;
|
||||||
return false;
|
if (*cur == 0)
|
||||||
|
goto parse_error;
|
||||||
|
|
||||||
|
while (*cur != 0) {
|
||||||
|
|
||||||
|
/* the char '^' denotes exclusive */
|
||||||
|
if (*cur == '^') {
|
||||||
|
cur++;
|
||||||
|
unuse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = expect_num;
|
/* parse physical CPU number */
|
||||||
for (i = 0; cpulist[i]; i++) {
|
if (!c_isdigit(*cur))
|
||||||
switch (state) {
|
goto parse_error;
|
||||||
case expect_num:
|
cpu = virParseNumber(&cur);
|
||||||
if (!c_isdigit (cpulist[i])) {
|
if (cpu < 0) {
|
||||||
vshError(ctl, _("cpulist: %s: Invalid format. Expecting "
|
goto parse_error;
|
||||||
"digit at position %d (near '%c')."),
|
|
||||||
cpulist, i, cpulist[i]);
|
|
||||||
virDomainFree (dom);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
state = expect_num_or_comma;
|
if (cpu >= maxcpu) {
|
||||||
break;
|
|
||||||
case expect_num_or_comma:
|
|
||||||
if (cpulist[i] == ',')
|
|
||||||
state = expect_num;
|
|
||||||
else if (!c_isdigit (cpulist[i])) {
|
|
||||||
vshError(ctl, _("cpulist: %s: Invalid format. Expecting "
|
|
||||||
"digit or comma at position %d (near '%c')."),
|
|
||||||
cpulist, i, cpulist[i]);
|
|
||||||
virDomainFree (dom);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (state == expect_num) {
|
|
||||||
vshError(ctl, _("cpulist: %s: Invalid format. Trailing comma "
|
|
||||||
"at position %d."),
|
|
||||||
cpulist, i);
|
|
||||||
virDomainFree (dom);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
|
|
||||||
cpumap = vshCalloc(ctl, 1, cpumaplen);
|
|
||||||
|
|
||||||
do {
|
|
||||||
unsigned int cpu = atoi(cpulist);
|
|
||||||
|
|
||||||
if (cpu < VIR_NODEINFO_MAXCPUS(nodeinfo)) {
|
|
||||||
VIR_USE_CPU(cpumap, cpu);
|
|
||||||
} else {
|
|
||||||
vshError(ctl, _("Physical CPU %d doesn't exist."), cpu);
|
vshError(ctl, _("Physical CPU %d doesn't exist."), cpu);
|
||||||
VIR_FREE(cpumap);
|
goto parse_error;
|
||||||
virDomainFree(dom);
|
}
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cpulist = strchr(cpulist, ',');
|
|
||||||
if (cpulist)
|
|
||||||
cpulist++;
|
|
||||||
} while (cpulist);
|
|
||||||
|
|
||||||
if (flags == -1) {
|
if (flags == -1) {
|
||||||
if (virDomainPinVcpu(dom, vcpu, cpumap, cpumaplen) != 0) {
|
if (virDomainPinVcpu(dom, vcpu, cpumap, cpumaplen) != 0) {
|
||||||
@ -3126,9 +3135,15 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
VIR_FREE(cpumap);
|
VIR_FREE(cpumap);
|
||||||
virDomainFree(dom);
|
virDomainFree(dom);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
parse_error:
|
||||||
|
vshError(ctl, "%s", _("cpulist: Invalid format."));
|
||||||
|
ret = false;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -833,13 +833,18 @@ vCPUs, the running time, the affinity to physical processors.
|
|||||||
I<--current>
|
I<--current>
|
||||||
|
|
||||||
Pin domain VCPUs to host physical CPUs. The I<vcpu> number must be provided
|
Pin domain VCPUs to host physical CPUs. The I<vcpu> number must be provided
|
||||||
and I<cpulist> is a comma separated list of physical CPU numbers.
|
and I<cpulist> is a list of physical CPU numbers. Its syntax is a comma
|
||||||
|
separated list and a special markup using '-' and '^' (ex. '0-4', '0-3,^2') can
|
||||||
|
also be allowed. The '-' denotes the range and the '^' denotes exclusive.
|
||||||
If I<--live> is specified, affect a running guest.
|
If I<--live> is specified, affect a running guest.
|
||||||
If I<--config> is specified, affect the next boot of a persistent guest.
|
If I<--config> is specified, affect the next boot of a persistent guest.
|
||||||
If I<--current> is specified, affect the current guest state.
|
If I<--current> is specified, affect the current guest state.
|
||||||
Both I<--live> and I<--config> flags may be given, but I<--current> is exclusive.
|
Both I<--live> and I<--config> flags may be given, but I<--current> is exclusive.
|
||||||
If no flag is specified, behavior is different depending on hypervisor.
|
If no flag is specified, behavior is different depending on hypervisor.
|
||||||
|
|
||||||
|
B<Note>: The expression is sequentially evaluated, so "0-15,^8" is not identical
|
||||||
|
to "^8,0-15".
|
||||||
|
|
||||||
=item B<vncdisplay> I<domain-id>
|
=item B<vncdisplay> I<domain-id>
|
||||||
|
|
||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user