For our administration, we need the following actions, while concerned domain is running:
1) Change the number of virtual CPUs.
2) Change the pinning (affinity) of a virtual CPU on real CPUs.
3) Get detailed information for each virtual CPU.
Currently there is no Libvirt function provided for that. We suggest to add the following 3 functions (in libvirt.c):
/**
* virDomainSetVcpus:
* @domain: pointer to domain object, or NULL for Domain0
* @nvcpus: the new number of virtual CPUs for this domain
*
* Dynamically change the number of virtual CPUs used by the domain.
* Note that this call may fail if the underlying virtualization hypervisor
* does not support it or if growing the number is arbitrary limited.
* This function requires priviledged access to the hypervisor.
*
* Returns 0 in case of success, -1 in case of failure.
*/
int virDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
/**
* virDomainPinVcpu:
* @domain: pointer to domain object, or NULL for Domain0
* @vcpu: virtual CPU number
* @cpumap: pointer to a bit map of real CPUs (format in virVcpuInfo)
* @maplen: length of cpumap, in 8-bit bytes
*
* Dynamically change the real CPUs which can be allocated to a virtual CPU.
* This function requires priviledged access to the hypervisor.
*
* Returns 0 in case of success, -1 in case of failure.
*/
int virDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
unsigned char *cpumap, int maplen)
/**
* virDomainGetVcpus:
* @domain: pointer to domain object, or NULL for Domain0
* @info: pointer to an array of virVcpuInfo structures
* @maxinfo: number of structures in info array
*
* Extract information about virtual CPUs of a domain, store it in info array.
*
* Returns the number of info filled in case of success, -1 in case of failure.
*/
int virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo)
with the following structure (in libvirt.h):
/**
* virVcpuInfo: structure for information about a virtual CPU in a domain.
*/
#define VIR_MAX_CPUS 256
typedef enum {
VIR_VCPU_OFFLINE = 0, /* the virtual CPU is offline */
VIR_VCPU_RUNNING = 1, /* the virtual CPU is running */
VIR_VCPU_BLOCKED = 2, /* the virtual CPU is blocked on resource */
} virVcpuState;
typedef struct _virVcpuInfo virVcpuInfo;
struct _virVcpuInfo {
unsigned int number; /* virtual CPU number */
int state; /* value from virVcpuState */
unsigned long long cpuTime; /* CPU time used, in nanoseconds */
int cpu; /* real CPU number, or -1 if offline */
unsigned char cpumap[VIR_MAX_CPUS/8]; /* Bit map of usable real CPUs.
Each bit set to 1 means that corresponding CPU is usable.
Bytes are stored in little-endian order: CPU0-7, 8-15...
In each byte, lowest CPU number is least significant bit */
};
typedef virVcpuInfo *virVcpuInfoPtr;
I have successfully tried those functions via Xen hypervisor, except for the first (SetVcpus) where hypervisor operation DOM0_MAX_VCPUS fails (maybe it is not possible on a running domain ?). That function was successful via Xen daemon.