mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 05:17:59 +03:00
Added vcpuinfo vcpupin commands to virsh. Fixed off by one bug in virDomainVcpuPin method
This commit is contained in:
parent
d7815361f8
commit
f7e0594f87
@ -1,3 +1,11 @@
|
|||||||
|
Fri Aug 4 20:19:23 EDT 2006 Daniel Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
* src/libvirt.c: Fix off-by-one in validated VCPU number (it is
|
||||||
|
zero based, not one based).
|
||||||
|
* include/libvirt/libvirt.h: Add some convenience macros for
|
||||||
|
calculating neccessary CPU map lengths & total host CPUs
|
||||||
|
* src/virsh.c: Add 'vcpuinfo' and 'vcpumap' commands
|
||||||
|
|
||||||
Fri Aug 4 14:45:25 CEST 2006 Daniel Veillard <veillard@redhat.com>
|
Fri Aug 4 14:45:25 CEST 2006 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* python/generator.py: fix the generator when handling long integers
|
* python/generator.py: fix the generator when handling long integers
|
||||||
|
@ -167,6 +167,18 @@ struct _virNodeInfo {
|
|||||||
unsigned int threads;/* number of threads per core */
|
unsigned int threads;/* number of threads per core */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_NODEINFO_MAXCPUS:
|
||||||
|
* @nodeinfo: virNodeInfo instance
|
||||||
|
*
|
||||||
|
* This macro is to calculate the total number of CPUs supported
|
||||||
|
* but not neccessarily active in the host.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define VIR_NODEINFO_MAXCPUS(nodeinfo) ((nodeinfo).nodes*(nodeinfo).sockets*(nodeinfo).cores*(nodeinfo).threads)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virNodeInfoPtr:
|
* virNodeInfoPtr:
|
||||||
*
|
*
|
||||||
@ -339,6 +351,18 @@ int virDomainPinVcpu (virDomainPtr domain,
|
|||||||
|
|
||||||
#define VIR_UNUSE_CPU(cpumap,cpu) (cpumap[(cpu)/8] &= ~(1<<((cpu)%8)))
|
#define VIR_UNUSE_CPU(cpumap,cpu) (cpumap[(cpu)/8] &= ~(1<<((cpu)%8)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_CPU_MAPLEN
|
||||||
|
* @cpu: number of physical CPUs
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainPinVcpu() API.
|
||||||
|
* It returns the length (in bytes) required to store the complete
|
||||||
|
* CPU map between a single virtual & all physical CPUs of a domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VIR_CPU_MAPLEN(cpu) (((cpu)+7)/8)
|
||||||
|
|
||||||
|
|
||||||
int virDomainGetVcpus (virDomainPtr domain,
|
int virDomainGetVcpus (virDomainPtr domain,
|
||||||
virVcpuInfoPtr info,
|
virVcpuInfoPtr info,
|
||||||
int maxinfo,
|
int maxinfo,
|
||||||
|
@ -1720,7 +1720,7 @@ virDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
|
|||||||
}
|
}
|
||||||
if (domain->conn->flags & VIR_CONNECT_RO)
|
if (domain->conn->flags & VIR_CONNECT_RO)
|
||||||
return (-1);
|
return (-1);
|
||||||
if ((vcpu < 1) || (cpumap == NULL) || (maplen < 1)) {
|
if ((vcpu < 0) || (cpumap == NULL) || (maplen < 1)) {
|
||||||
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
188
src/virsh.c
188
src/virsh.c
@ -207,6 +207,7 @@ static void vshDebug(vshControl * ctl, int level, const char *format, ...);
|
|||||||
#define vshPrint(_ctl, ...) fprintf(stdout, __VA_ARGS__)
|
#define vshPrint(_ctl, ...) fprintf(stdout, __VA_ARGS__)
|
||||||
|
|
||||||
static const char *vshDomainStateToString(int state);
|
static const char *vshDomainStateToString(int state);
|
||||||
|
static const char *vshDomainVcpuStateToString(int state);
|
||||||
static int vshConnectionUsability(vshControl * ctl, virConnectPtr conn,
|
static int vshConnectionUsability(vshControl * ctl, virConnectPtr conn,
|
||||||
int showerror);
|
int showerror);
|
||||||
|
|
||||||
@ -793,6 +794,175 @@ cmdDominfo(vshControl * ctl, vshCmd * cmd)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "vcpuinfo" command
|
||||||
|
*/
|
||||||
|
static vshCmdInfo info_vcpuinfo[] = {
|
||||||
|
{"syntax", "vcpuinfo <domain>"},
|
||||||
|
{"help", "domain vcpu information"},
|
||||||
|
{"desc", "Returns basic information about the domain virtual CPUs."},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static vshCmdOptDef opts_vcpuinfo[] = {
|
||||||
|
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name, id or uuid"},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmdVcpuinfo(vshControl * ctl, vshCmd * cmd)
|
||||||
|
{
|
||||||
|
virDomainInfo info;
|
||||||
|
virDomainPtr dom;
|
||||||
|
virNodeInfo nodeinfo;
|
||||||
|
virVcpuInfoPtr cpuinfo;
|
||||||
|
unsigned char *cpumap;
|
||||||
|
int ncpus;
|
||||||
|
size_t cpumaplen;
|
||||||
|
int ret = TRUE;
|
||||||
|
|
||||||
|
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (virNodeGetInfo(ctl->conn, &nodeinfo) != 0) {
|
||||||
|
virDomainFree(dom);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virDomainGetInfo(dom, &info) != 0) {
|
||||||
|
virDomainFree(dom);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuinfo = malloc(sizeof(virVcpuInfo)*info.nrVirtCpu);
|
||||||
|
cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
|
||||||
|
cpumap = malloc(info.nrVirtCpu * cpumaplen);
|
||||||
|
|
||||||
|
if ((ncpus = virDomainGetVcpus(dom,
|
||||||
|
cpuinfo, info.nrVirtCpu,
|
||||||
|
cpumap, cpumaplen)) >= 0) {
|
||||||
|
int n;
|
||||||
|
for (n = 0 ; n < ncpus ; n++) {
|
||||||
|
unsigned int m;
|
||||||
|
vshPrint(ctl, "%-15s %d\n", "VCPU:", n);
|
||||||
|
vshPrint(ctl, "%-15s %d\n", "CPU:", cpuinfo[n].cpu);
|
||||||
|
vshPrint(ctl, "%-15s %s\n", "State:",
|
||||||
|
vshDomainVcpuStateToString(cpuinfo[n].state));
|
||||||
|
if (cpuinfo[n].cpuTime != 0) {
|
||||||
|
double cpuUsed = cpuinfo[n].cpuTime;
|
||||||
|
|
||||||
|
cpuUsed /= 1000000000.0;
|
||||||
|
|
||||||
|
vshPrint(ctl, "%-15s %.1lfs\n", "CPU time:", cpuUsed);
|
||||||
|
}
|
||||||
|
vshPrint(ctl, "%-15s ", "CPU Affinity:");
|
||||||
|
for (m = 0 ; m < VIR_NODEINFO_MAXCPUS(nodeinfo) ; m++) {
|
||||||
|
vshPrint(ctl, "%c", VIR_CPU_USABLE(cpumap, cpumaplen, n, m) ? 'y' : '-');
|
||||||
|
}
|
||||||
|
vshPrint(ctl, "\n");
|
||||||
|
if (n < (ncpus - 1)) {
|
||||||
|
vshPrint(ctl, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(cpumap);
|
||||||
|
free(cpuinfo);
|
||||||
|
virDomainFree(dom);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "vcpupin" command
|
||||||
|
*/
|
||||||
|
static vshCmdInfo info_vcpupin[] = {
|
||||||
|
{"syntax", "vcpupin <domain>"},
|
||||||
|
{"help", "control domain vcpu affinity"},
|
||||||
|
{"desc", "Pin domain VCPUs to host physical CPUs"},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static vshCmdOptDef opts_vcpupin[] = {
|
||||||
|
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, "domain name, id or uuid"},
|
||||||
|
{"vcpu", VSH_OT_DATA, VSH_OFLAG_REQ, "vcpu number"},
|
||||||
|
{"cpulist", VSH_OT_DATA, VSH_OFLAG_REQ, "host cpu number(s) (comma separated)"},
|
||||||
|
{NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmdVcpupin(vshControl * ctl, vshCmd * cmd)
|
||||||
|
{
|
||||||
|
virDomainInfo info;
|
||||||
|
virDomainPtr dom;
|
||||||
|
virNodeInfo nodeinfo;
|
||||||
|
int vcpu;
|
||||||
|
char *cpulist;
|
||||||
|
int ret = TRUE;
|
||||||
|
int vcpufound = 0;
|
||||||
|
unsigned char *cpumap;
|
||||||
|
int cpumaplen;
|
||||||
|
|
||||||
|
if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
vcpu = vshCommandOptInt(cmd, "vcpu", &vcpufound);
|
||||||
|
if (!vcpufound) {
|
||||||
|
virDomainFree(dom);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cpulist = vshCommandOptString(cmd, "cpulist", NULL))) {
|
||||||
|
virDomainFree(dom);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virNodeGetInfo(ctl->conn, &nodeinfo) != 0) {
|
||||||
|
virDomainFree(dom);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virDomainGetInfo(dom, &info) != 0) {
|
||||||
|
virDomainFree(dom);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vcpu >= info.nrVirtCpu) {
|
||||||
|
virDomainFree(dom);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
|
||||||
|
cpumap = malloc(cpumaplen);
|
||||||
|
memset(cpumap, 0, cpumaplen);
|
||||||
|
|
||||||
|
do {
|
||||||
|
unsigned int cpu = atoi(cpulist);
|
||||||
|
|
||||||
|
if (cpu < VIR_NODEINFO_MAXCPUS(nodeinfo)) {
|
||||||
|
VIR_USE_CPU(cpumap, cpu);
|
||||||
|
}
|
||||||
|
cpulist = index(cpulist, ',');
|
||||||
|
if (cpulist)
|
||||||
|
cpulist++;
|
||||||
|
} while (cpulist);
|
||||||
|
|
||||||
|
if (virDomainPinVcpu(dom, vcpu, cpumap, cpumaplen) != 0) {
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(cpumap);
|
||||||
|
virDomainFree(dom);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "nodeinfo" command
|
* "nodeinfo" command
|
||||||
*/
|
*/
|
||||||
@ -1081,6 +1251,8 @@ static vshCmdDef commands[] = {
|
|||||||
{"save", cmdSave, opts_save, info_save},
|
{"save", cmdSave, opts_save, info_save},
|
||||||
{"shutdown", cmdShutdown, opts_shutdown, info_shutdown},
|
{"shutdown", cmdShutdown, opts_shutdown, info_shutdown},
|
||||||
{"suspend", cmdSuspend, opts_suspend, info_suspend},
|
{"suspend", cmdSuspend, opts_suspend, info_suspend},
|
||||||
|
{"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
|
||||||
|
{"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
|
||||||
{"version", cmdVersion, NULL, info_version},
|
{"version", cmdVersion, NULL, info_version},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
@ -1643,6 +1815,22 @@ vshDomainStateToString(int state)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
vshDomainVcpuStateToString(int state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case VIR_VCPU_OFFLINE:
|
||||||
|
return "offline";
|
||||||
|
case VIR_VCPU_BLOCKED:
|
||||||
|
return "blocked";
|
||||||
|
case VIR_VCPU_RUNNING:
|
||||||
|
return "running";
|
||||||
|
default:
|
||||||
|
return "no state";
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vshConnectionUsability(vshControl * ctl, virConnectPtr conn, int showerror)
|
vshConnectionUsability(vshControl * ctl, virConnectPtr conn, int showerror)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user