mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-31 14:07:16 +00:00
virsh: Add a helper to parse cpulist
The 'virsh vcpupin' and 'virsh emulatorpin' commands use the same code to parse the cpulist. This patch abstracts the same code as a helper. Along with various code style fixes, and error improvement (only error "Physical CPU %d doesn't exist" if the specified CPU exceed the range, no "cpulist: Invalid format", see the following for an example of the error prior to this patch). % virsh vcpupin 4 0 0-8 error: Physical CPU 4 doesn't exist. error: cpulist: Invalid format.
This commit is contained in:
parent
9a80050e52
commit
8893df388e
@ -5460,6 +5460,97 @@ vshPrintPinInfo(unsigned char *cpumaps, size_t cpumaplen,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned char *
|
||||||
|
vshParseCPUList(vshControl *ctl, const char *cpulist,
|
||||||
|
int maxcpu, size_t cpumaplen)
|
||||||
|
{
|
||||||
|
unsigned char *cpumap = NULL;
|
||||||
|
const char *cur;
|
||||||
|
bool unuse = false;
|
||||||
|
int i, cpu, lastcpu;
|
||||||
|
|
||||||
|
cpumap = vshCalloc(ctl, cpumaplen, sizeof(*cpumap));
|
||||||
|
|
||||||
|
/* Parse cpulist */
|
||||||
|
cur = cpulist;
|
||||||
|
if (*cur == 'r') {
|
||||||
|
for (cpu = 0; cpu < maxcpu; cpu++)
|
||||||
|
VIR_USE_CPU(cpumap, cpu);
|
||||||
|
return cpumap;
|
||||||
|
} else if (*cur == 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*cur != 0) {
|
||||||
|
/* The char '^' denotes exclusive */
|
||||||
|
if (*cur == '^') {
|
||||||
|
cur++;
|
||||||
|
unuse = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse physical CPU number */
|
||||||
|
if (!c_isdigit(*cur))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if ((cpu = virParseNumber(&cur)) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (cpu >= maxcpu) {
|
||||||
|
vshError(ctl, _("Physical CPU %d doesn't exist."), cpu);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 error;
|
||||||
|
cur++;
|
||||||
|
virSkipSpaces(&cur);
|
||||||
|
|
||||||
|
/* Parse the end of range */
|
||||||
|
lastcpu = virParseNumber(&cur);
|
||||||
|
|
||||||
|
if (lastcpu < cpu)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (lastcpu >= maxcpu) {
|
||||||
|
vshError(ctl, _("Physical CPU %d doesn't exist."), lastcpu);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cpumap;
|
||||||
|
|
||||||
|
error:
|
||||||
|
vshError(ctl, "%s", _("cpulist: Invalid format."));
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(cpumap);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
|
cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
|
||||||
{
|
{
|
||||||
@ -5467,13 +5558,11 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
|
|||||||
virDomainPtr dom;
|
virDomainPtr dom;
|
||||||
int vcpu = -1;
|
int vcpu = -1;
|
||||||
const char *cpulist = NULL;
|
const char *cpulist = NULL;
|
||||||
bool ret = true;
|
bool ret = false;
|
||||||
unsigned char *cpumap = NULL;
|
unsigned char *cpumap = NULL;
|
||||||
unsigned char *cpumaps = NULL;
|
unsigned char *cpumaps = NULL;
|
||||||
size_t cpumaplen;
|
size_t cpumaplen;
|
||||||
int i, cpu, lastcpu, maxcpu, ncpus;
|
int i, maxcpu, ncpus;
|
||||||
bool unuse = false;
|
|
||||||
const char *cur;
|
|
||||||
bool config = vshCommandOptBool(cmd, "config");
|
bool config = vshCommandOptBool(cmd, "config");
|
||||||
bool live = vshCommandOptBool(cmd, "live");
|
bool live = vshCommandOptBool(cmd, "live");
|
||||||
bool current = vshCommandOptBool(cmd, "current");
|
bool current = vshCommandOptBool(cmd, "current");
|
||||||
@ -5545,7 +5634,6 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
|
|||||||
vshPrint(ctl, "%s %s\n", _("VCPU:"), _("CPU Affinity"));
|
vshPrint(ctl, "%s %s\n", _("VCPU:"), _("CPU Affinity"));
|
||||||
vshPrint(ctl, "----------------------------------\n");
|
vshPrint(ctl, "----------------------------------\n");
|
||||||
for (i = 0; i < ncpus; i++) {
|
for (i = 0; i < ncpus; i++) {
|
||||||
|
|
||||||
if (vcpu != -1 && i != vcpu)
|
if (vcpu != -1 && i != vcpu)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -5556,105 +5644,28 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
ret = false;
|
|
||||||
}
|
}
|
||||||
VIR_FREE(cpumaps);
|
VIR_FREE(cpumaps);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pin mode: pinning specified vcpu to specified physical cpus*/
|
/* Pin mode: pinning specified vcpu to specified physical cpus*/
|
||||||
|
if (!(cpumap = vshParseCPUList(ctl, cpulist, maxcpu, cpumaplen)))
|
||||||
cpumap = vshCalloc(ctl, cpumaplen, sizeof(*cpumap));
|
goto cleanup;
|
||||||
/* 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) {
|
if (flags == -1) {
|
||||||
if (virDomainPinVcpu(dom, vcpu, cpumap, cpumaplen) != 0) {
|
if (virDomainPinVcpu(dom, vcpu, cpumap, cpumaplen) != 0)
|
||||||
ret = false;
|
goto cleanup;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (virDomainPinVcpuFlags(dom, vcpu, cpumap, cpumaplen, flags) != 0) {
|
if (virDomainPinVcpuFlags(dom, vcpu, cpumap, cpumaplen, flags) != 0)
|
||||||
ret = false;
|
goto cleanup;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
cleanup:
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5701,13 +5712,11 @@ cmdEmulatorPin(vshControl *ctl, const vshCmd *cmd)
|
|||||||
{
|
{
|
||||||
virDomainPtr dom;
|
virDomainPtr dom;
|
||||||
const char *cpulist = NULL;
|
const char *cpulist = NULL;
|
||||||
bool ret = true;
|
bool ret = false;
|
||||||
unsigned char *cpumap = NULL;
|
unsigned char *cpumap = NULL;
|
||||||
unsigned char *cpumaps = NULL;
|
unsigned char *cpumaps = NULL;
|
||||||
size_t cpumaplen;
|
size_t cpumaplen;
|
||||||
int i, cpu, lastcpu, maxcpu;
|
int maxcpu;
|
||||||
bool unuse = false;
|
|
||||||
const char *cur;
|
|
||||||
bool config = vshCommandOptBool(cmd, "config");
|
bool config = vshCommandOptBool(cmd, "config");
|
||||||
bool live = vshCommandOptBool(cmd, "live");
|
bool live = vshCommandOptBool(cmd, "live");
|
||||||
bool current = vshCommandOptBool(cmd, "current");
|
bool current = vshCommandOptBool(cmd, "current");
|
||||||
@ -5761,101 +5770,26 @@ cmdEmulatorPin(vshControl *ctl, const vshCmd *cmd)
|
|||||||
vshPrint(ctl, " *: ");
|
vshPrint(ctl, " *: ");
|
||||||
ret = vshPrintPinInfo(cpumaps, cpumaplen, maxcpu, 0);
|
ret = vshPrintPinInfo(cpumaps, cpumaplen, maxcpu, 0);
|
||||||
vshPrint(ctl, "\n");
|
vshPrint(ctl, "\n");
|
||||||
} else {
|
|
||||||
ret = false;
|
|
||||||
}
|
}
|
||||||
VIR_FREE(cpumaps);
|
VIR_FREE(cpumaps);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pin mode: pinning emulator threads to specified physical cpus*/
|
/* Pin mode: pinning emulator threads to specified physical cpus*/
|
||||||
|
if (!(cpumap = vshParseCPUList(ctl, cpulist, maxcpu, cpumaplen)))
|
||||||
cpumap = vshCalloc(ctl, cpumaplen, sizeof(*cpumap));
|
goto cleanup;
|
||||||
/* 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)
|
if (flags == -1)
|
||||||
flags = VIR_DOMAIN_AFFECT_LIVE;
|
flags = VIR_DOMAIN_AFFECT_LIVE;
|
||||||
|
|
||||||
if (virDomainPinEmulator(dom, cpumap, cpumaplen, flags) != 0)
|
if (virDomainPinEmulator(dom, cpumap, cpumaplen, flags) != 0)
|
||||||
ret = false;
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = true;
|
||||||
cleanup:
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user