mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-08 12:41:29 +00:00
* include/libvirt/libvirt.h include/libvirt/libvirt.h.in
src/libvirt.c src/libvirt_sym.version src/xen_internal.c src/xen_internal.h src/xend_internal.c src/xend_internal.h: applied patch from Michel Ponceau and Philippe Berthault for virtual CPU and affinity support plus a bit of cleanup. Daniel
This commit is contained in:
parent
417e06a40e
commit
7a8a63380f
@ -1,3 +1,11 @@
|
|||||||
|
Fri Aug 4 11:49:44 CEST 2006 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
|
* include/libvirt/libvirt.h include/libvirt/libvirt.h.in
|
||||||
|
src/libvirt.c src/libvirt_sym.version src/xen_internal.c
|
||||||
|
src/xen_internal.h src/xend_internal.c src/xend_internal.h:
|
||||||
|
applied patch from Michel Ponceau and Philippe Berthault for
|
||||||
|
virtual CPU and affinity support plus a bit of cleanup.
|
||||||
|
|
||||||
Tue Aug 1 16:22:52 CEST 2006 Daniel Veillard <veillard@redhat.com>
|
Tue Aug 1 16:22:52 CEST 2006 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* libvirt.spec.in: xen is now built for ia64, c.f. RH#199685
|
* libvirt.spec.in: xen is now built for ia64, c.f. RH#199685
|
||||||
|
@ -290,6 +290,107 @@ int virConnectListDefinedDomains(virConnectPtr conn,
|
|||||||
int maxnames);
|
int maxnames);
|
||||||
int virDomainCreate (virDomainPtr domain);
|
int virDomainCreate (virDomainPtr domain);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virVcpuInfo: structure for information about a virtual CPU in a domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 */
|
||||||
|
};
|
||||||
|
typedef virVcpuInfo *virVcpuInfoPtr;
|
||||||
|
|
||||||
|
int virDomainSetVcpus (virDomainPtr domain,
|
||||||
|
unsigned int nvcpus);
|
||||||
|
|
||||||
|
int virDomainPinVcpu (virDomainPtr domain,
|
||||||
|
unsigned int vcpu,
|
||||||
|
unsigned char *cpumap,
|
||||||
|
int maplen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_USE_CPU:
|
||||||
|
* @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN/OUT)
|
||||||
|
* @cpu: the physical CPU number
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainPinVcpu() API.
|
||||||
|
* USE_CPU macro set the bit (CPU usable) of the related cpu in cpumap.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VIR_USE_CPU(cpumap,cpu) (cpumap[(cpu)/8] |= (1<<((cpu)%8)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_UNUSE_CPU:
|
||||||
|
* @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN/OUT)
|
||||||
|
* @cpu: the physical CPU number
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainPinVcpu() API.
|
||||||
|
* USE_CPU macro reset the bit (CPU not usable) of the related cpu in cpumap.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VIR_UNUSE_CPU(cpumap,cpu) (cpumap[(cpu)/8] &= ~(1<<((cpu)%8)))
|
||||||
|
|
||||||
|
int virDomainGetVcpus (virDomainPtr domain,
|
||||||
|
virVcpuInfoPtr info,
|
||||||
|
int maxinfo,
|
||||||
|
unsigned char *cpumaps,
|
||||||
|
int maplen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_CPU_USABLE:
|
||||||
|
* @cpumaps: pointer to an array of cpumap (in 8-bit bytes) (IN)
|
||||||
|
* @maplen: the length (in bytes) of one cpumap
|
||||||
|
* @vcpu: the virtual CPU number
|
||||||
|
* @cpu: the physical CPU number
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainGetVcpus() API.
|
||||||
|
* VIR_CPU_USABLE macro returns a non zero value (true) if the cpu
|
||||||
|
* is usable by the vcpu, and 0 otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VIR_CPU_USABLE(cpumaps,maplen,vcpu,cpu) \
|
||||||
|
(cpumaps[((vcpu)*(maplen))+((cpu)/8)] & (1<<((cpu)%8)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_COPY_CPUMAP:
|
||||||
|
* @cpumaps: pointer to an array of cpumap (in 8-bit bytes) (IN)
|
||||||
|
* @maplen: the length (in bytes) of one cpumap
|
||||||
|
* @vcpu: the virtual CPU number
|
||||||
|
* @cpumap: pointer to a cpumap (in 8-bit bytes) (OUT)
|
||||||
|
* This cpumap must be previously allocated by the caller
|
||||||
|
* (ie: malloc(maplen))
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainGetVcpus() and
|
||||||
|
* virDomainPinVcpu() APIs. VIR_COPY_CPUMAP macro extract the cpumap of
|
||||||
|
* the specified vcpu from cpumaps array and copy it into cpumap to be used
|
||||||
|
* later by virDomainPinVcpu() API.
|
||||||
|
*/
|
||||||
|
#define VIR_COPY_CPUMAP(cpumaps,maplen,vcpu,cpumap) \
|
||||||
|
memcpy(cpumap, &(cpumaps[(vcpu)*(maplen)]), (maplen))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_GET_CPUMAP:
|
||||||
|
* @cpumaps: pointer to an array of cpumap (in 8-bit bytes) (IN)
|
||||||
|
* @maplen: the length (in bytes) of one cpumap
|
||||||
|
* @vcpu: the virtual CPU number
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainGetVcpus() and
|
||||||
|
* virDomainPinVcpu() APIs. VIR_GET_CPUMAP macro returns a pointer to the
|
||||||
|
* cpumap of the specified vcpu from cpumaps array.
|
||||||
|
*/
|
||||||
|
#define VIR_GET_CPUMAP(cpumaps,maplen,vcpu) &(cpumaps[(vcpu)*(maplen)])
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -290,6 +290,107 @@ int virConnectListDefinedDomains(virConnectPtr conn,
|
|||||||
int maxnames);
|
int maxnames);
|
||||||
int virDomainCreate (virDomainPtr domain);
|
int virDomainCreate (virDomainPtr domain);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virVcpuInfo: structure for information about a virtual CPU in a domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 */
|
||||||
|
};
|
||||||
|
typedef virVcpuInfo *virVcpuInfoPtr;
|
||||||
|
|
||||||
|
int virDomainSetVcpus (virDomainPtr domain,
|
||||||
|
unsigned int nvcpus);
|
||||||
|
|
||||||
|
int virDomainPinVcpu (virDomainPtr domain,
|
||||||
|
unsigned int vcpu,
|
||||||
|
unsigned char *cpumap,
|
||||||
|
int maplen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_USE_CPU:
|
||||||
|
* @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN/OUT)
|
||||||
|
* @cpu: the physical CPU number
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainPinVcpu() API.
|
||||||
|
* USE_CPU macro set the bit (CPU usable) of the related cpu in cpumap.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VIR_USE_CPU(cpumap,cpu) (cpumap[(cpu)/8] |= (1<<((cpu)%8)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_UNUSE_CPU:
|
||||||
|
* @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN/OUT)
|
||||||
|
* @cpu: the physical CPU number
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainPinVcpu() API.
|
||||||
|
* USE_CPU macro reset the bit (CPU not usable) of the related cpu in cpumap.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VIR_UNUSE_CPU(cpumap,cpu) (cpumap[(cpu)/8] &= ~(1<<((cpu)%8)))
|
||||||
|
|
||||||
|
int virDomainGetVcpus (virDomainPtr domain,
|
||||||
|
virVcpuInfoPtr info,
|
||||||
|
int maxinfo,
|
||||||
|
unsigned char *cpumaps,
|
||||||
|
int maplen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_CPU_USABLE:
|
||||||
|
* @cpumaps: pointer to an array of cpumap (in 8-bit bytes) (IN)
|
||||||
|
* @maplen: the length (in bytes) of one cpumap
|
||||||
|
* @vcpu: the virtual CPU number
|
||||||
|
* @cpu: the physical CPU number
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainGetVcpus() API.
|
||||||
|
* VIR_CPU_USABLE macro returns a non zero value (true) if the cpu
|
||||||
|
* is usable by the vcpu, and 0 otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VIR_CPU_USABLE(cpumaps,maplen,vcpu,cpu) \
|
||||||
|
(cpumaps[((vcpu)*(maplen))+((cpu)/8)] & (1<<((cpu)%8)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_COPY_CPUMAP:
|
||||||
|
* @cpumaps: pointer to an array of cpumap (in 8-bit bytes) (IN)
|
||||||
|
* @maplen: the length (in bytes) of one cpumap
|
||||||
|
* @vcpu: the virtual CPU number
|
||||||
|
* @cpumap: pointer to a cpumap (in 8-bit bytes) (OUT)
|
||||||
|
* This cpumap must be previously allocated by the caller
|
||||||
|
* (ie: malloc(maplen))
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainGetVcpus() and
|
||||||
|
* virDomainPinVcpu() APIs. VIR_COPY_CPUMAP macro extract the cpumap of
|
||||||
|
* the specified vcpu from cpumaps array and copy it into cpumap to be used
|
||||||
|
* later by virDomainPinVcpu() API.
|
||||||
|
*/
|
||||||
|
#define VIR_COPY_CPUMAP(cpumaps,maplen,vcpu,cpumap) \
|
||||||
|
memcpy(cpumap, &(cpumaps[(vcpu)*(maplen)]), (maplen))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_GET_CPUMAP:
|
||||||
|
* @cpumaps: pointer to an array of cpumap (in 8-bit bytes) (IN)
|
||||||
|
* @maplen: the length (in bytes) of one cpumap
|
||||||
|
* @vcpu: the virtual CPU number
|
||||||
|
*
|
||||||
|
* This macro is to be used in conjonction with virDomainGetVcpus() and
|
||||||
|
* virDomainPinVcpu() APIs. VIR_GET_CPUMAP macro returns a pointer to the
|
||||||
|
* cpumap of the specified vcpu from cpumaps array.
|
||||||
|
*/
|
||||||
|
#define VIR_GET_CPUMAP(cpumaps,maplen,vcpu) &(cpumaps[(vcpu)*(maplen)])
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
129
src/libvirt.c
129
src/libvirt.c
@ -1649,3 +1649,132 @@ virDomainCreate(virDomainPtr domain) {
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
if (domain == NULL) {
|
||||||
|
TODO
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||||
|
virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (domain->conn->flags & VIR_CONNECT_RO)
|
||||||
|
return (-1);
|
||||||
|
if (nvcpus < 1) {
|
||||||
|
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
/* TODO: access though the driver API not directly */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (xenHypervisorSetVcpus(domain, nvcpus) == 0)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
return xenDaemonDomainSetVcpus(domain, nvcpus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainPinVcpu:
|
||||||
|
* @domain: pointer to domain object, or NULL for Domain0
|
||||||
|
* @vcpu: virtual CPU number
|
||||||
|
* @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
|
||||||
|
* 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.
|
||||||
|
* @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
|
||||||
|
* underlying virtualization system (Xen...).
|
||||||
|
* If maplen < size, missing bytes are set to zero.
|
||||||
|
* If maplen > size, failure code is returned.
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
if (domain == NULL) {
|
||||||
|
TODO
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||||
|
virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (domain->conn->flags & VIR_CONNECT_RO)
|
||||||
|
return (-1);
|
||||||
|
if ((vcpu < 1) || (cpumap == NULL) || (maplen < 1)) {
|
||||||
|
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
/* TODO: access though the driver API not directly */
|
||||||
|
if (xenHypervisorPinVcpu(domain, vcpu, cpumap, maplen) == 0)
|
||||||
|
return 0;
|
||||||
|
return (-1); //xenDaemonDomainPinVcpu(domain, vcpu, cpumap, maplen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainGetVcpus:
|
||||||
|
* @domain: pointer to domain object, or NULL for Domain0
|
||||||
|
* @info: pointer to an array of virVcpuInfo structures (OUT)
|
||||||
|
* @maxinfo: number of structures in info array
|
||||||
|
* @cpumaps: pointer to an bit map of real CPUs for all vcpus of this
|
||||||
|
* domain (in 8-bit bytes) (OUT)
|
||||||
|
* If cpumaps is NULL, then no cupmap information is returned by the API.
|
||||||
|
* It's assumed there is <maxinfo> cpumap in cpumaps array.
|
||||||
|
* The memory allocated to cpumaps must be (maxinfo * maplen) bytes
|
||||||
|
* (ie: calloc(maxinfo, maplen)).
|
||||||
|
* One cpumap inside cpumaps has the format described in
|
||||||
|
* virDomainPinVcpu() API.
|
||||||
|
* @maplen: number of bytes in one cpumap, from 1 up to size of CPU map in
|
||||||
|
* underlying virtualization system (Xen...).
|
||||||
|
*
|
||||||
|
* Extract information about virtual CPUs of domain, store it in info array
|
||||||
|
* and also in cpumaps if this pointer is'nt NULL.
|
||||||
|
*
|
||||||
|
* Returns the number of info filled in case of success, -1 in case of failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
|
||||||
|
unsigned char *cpumaps, int maplen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (domain == NULL) {
|
||||||
|
TODO
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||||
|
virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if ((info == NULL) || (maxinfo < 1)) {
|
||||||
|
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (cpumaps != NULL && maplen < 1) {
|
||||||
|
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
/* TODO: access though the driver API not directly */
|
||||||
|
ret = xenHypervisorGetVcpus(domain, info, maxinfo, cpumaps, maplen);
|
||||||
|
if (ret != -1) return ret;
|
||||||
|
return xenDaemonDomainGetVcpus(domain, info, maxinfo, cpumaps, maplen);
|
||||||
|
}
|
||||||
|
@ -47,5 +47,9 @@
|
|||||||
virConnResetLastError;
|
virConnResetLastError;
|
||||||
virDefaultErrorFunc;
|
virDefaultErrorFunc;
|
||||||
virNodeGetInfo;
|
virNodeGetInfo;
|
||||||
|
|
||||||
|
virDomainSetVcpus;
|
||||||
|
virDomainPinVcpu;
|
||||||
|
virDomainGetVcpus;
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* required for dom0_getdomaininfo_t */
|
/* required for dom0_getdomaininfo_t */
|
||||||
@ -845,3 +845,136 @@ xenHypervisorCheckID(virConnectPtr conn, int id)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xenHypervisorSetVcpus:
|
||||||
|
* @domain: pointer to domain object
|
||||||
|
* @nvcpus: the new number of virtual CPUs for this domain
|
||||||
|
*
|
||||||
|
* Dynamically change the number of virtual CPUs used by the domain.
|
||||||
|
*
|
||||||
|
* Returns 0 in case of success, -1 in case of failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
xenHypervisorSetVcpus(virDomainPtr domain, unsigned int nvcpus)
|
||||||
|
{
|
||||||
|
dom0_op_t op;
|
||||||
|
|
||||||
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->conn->handle < 0)
|
||||||
|
|| (nvcpus < 1))
|
||||||
|
return (-1);
|
||||||
|
op.cmd = DOM0_MAX_VCPUS;
|
||||||
|
op.u.max_vcpus.domain = (domid_t) domain->handle;
|
||||||
|
op.u.max_vcpus.max = nvcpus;
|
||||||
|
if (xenHypervisorDoOp(domain->conn->handle, &op) < 0)
|
||||||
|
return (-1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xenHypervisorPinVcpu:
|
||||||
|
* @domain: pointer to domain object
|
||||||
|
* @vcpu: virtual CPU number
|
||||||
|
* @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes)
|
||||||
|
* @maplen: length of cpumap in bytes
|
||||||
|
*
|
||||||
|
* Dynamically change the real CPUs which can be allocated to a virtual CPU.
|
||||||
|
*
|
||||||
|
* Returns 0 in case of success, -1 in case of failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
xenHypervisorPinVcpu(virDomainPtr domain, unsigned int vcpu,
|
||||||
|
unsigned char *cpumap, int maplen)
|
||||||
|
{
|
||||||
|
dom0_op_t op;
|
||||||
|
uint64_t *pm = (uint64_t *)&op.u.setvcpuaffinity.cpumap;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->conn->handle < 0)
|
||||||
|
|| (cpumap == NULL) || (maplen < 1) || (maplen > (int)sizeof(cpumap_t))
|
||||||
|
|| (sizeof(cpumap_t) & 7))
|
||||||
|
return (-1);
|
||||||
|
op.cmd = DOM0_SETVCPUAFFINITY;
|
||||||
|
op.u.setvcpuaffinity.domain = (domid_t) domain->handle;
|
||||||
|
op.u.setvcpuaffinity.vcpu = vcpu;
|
||||||
|
memset(pm, 0, sizeof(cpumap_t));
|
||||||
|
for (j = 0; j < maplen; j++)
|
||||||
|
*(pm + (j / 8)) |= cpumap[j] << (8 * (j & 7));
|
||||||
|
if (xenHypervisorDoOp(domain->conn->handle, &op) < 0)
|
||||||
|
return (-1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainGetVcpus:
|
||||||
|
* @domain: pointer to domain object, or NULL for Domain0
|
||||||
|
* @info: pointer to an array of virVcpuInfo structures (OUT)
|
||||||
|
* @maxinfo: number of structures in info array
|
||||||
|
* @cpumaps: pointer to an bit map of real CPUs for all vcpus of this domain (in 8-bit bytes) (OUT)
|
||||||
|
* If cpumaps is NULL, then no cupmap information is returned by the API.
|
||||||
|
* It's assumed there is <maxinfo> cpumap in cpumaps array.
|
||||||
|
* The memory allocated to cpumaps must be (maxinfo * maplen) bytes
|
||||||
|
* (ie: calloc(maxinfo, maplen)).
|
||||||
|
* One cpumap inside cpumaps has the format described in virDomainPinVcpu() API.
|
||||||
|
* @maplen: number of bytes in one cpumap, from 1 up to size of CPU map in
|
||||||
|
* underlying virtualization system (Xen...).
|
||||||
|
*
|
||||||
|
* Extract information about virtual CPUs of domain, store it in info array
|
||||||
|
* and also in cpumaps if this pointer is'nt NULL.
|
||||||
|
*
|
||||||
|
* Returns the number of info filled in case of success, -1 in case of failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xenHypervisorGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
|
||||||
|
unsigned char *cpumaps, int maplen)
|
||||||
|
{
|
||||||
|
dom0_op_t op;
|
||||||
|
uint64_t *pm = (uint64_t *)&op.u.getvcpuinfo.cpumap;
|
||||||
|
virVcpuInfoPtr ipt;
|
||||||
|
int nbinfo, mapl, i;
|
||||||
|
unsigned char *cpumap;
|
||||||
|
int vcpu, cpu;
|
||||||
|
|
||||||
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->conn->handle < 0)
|
||||||
|
|| (info == NULL) || (maxinfo < 1)
|
||||||
|
|| (sizeof(cpumap_t) & 7))
|
||||||
|
return (-1);
|
||||||
|
if (cpumaps != NULL && maplen < 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* first get the number of virtual CPUs in this domain */
|
||||||
|
op.cmd = DOM0_GETDOMAININFO;
|
||||||
|
op.u.getdomaininfo.domain = (domid_t) domain->handle;
|
||||||
|
if (xenHypervisorDoOp(domain->conn->handle, &op) < 0)
|
||||||
|
return (-1);
|
||||||
|
nbinfo = (int)op.u.getdomaininfo.max_vcpu_id + 1;
|
||||||
|
if (nbinfo > maxinfo) nbinfo = maxinfo;
|
||||||
|
|
||||||
|
if (cpumaps != NULL)
|
||||||
|
memset(cpumaps, 0, maxinfo * maplen);
|
||||||
|
|
||||||
|
op.cmd = DOM0_GETVCPUINFO;
|
||||||
|
for (i=0, ipt=info; i < nbinfo; i++, ipt++) {
|
||||||
|
vcpu = op.u.getvcpuinfo.vcpu = i;
|
||||||
|
if (xenHypervisorDoOp(domain->conn->handle, &op) < 0)
|
||||||
|
return (-1);
|
||||||
|
ipt->number = i;
|
||||||
|
if (op.u.getvcpuinfo.online) {
|
||||||
|
if (op.u.getvcpuinfo.running) ipt->state = VIR_VCPU_RUNNING;
|
||||||
|
if (op.u.getvcpuinfo.blocked) ipt->state = VIR_VCPU_BLOCKED;
|
||||||
|
}
|
||||||
|
else ipt->state = VIR_VCPU_OFFLINE;
|
||||||
|
ipt->cpuTime = op.u.getvcpuinfo.cpu_time;
|
||||||
|
ipt->cpu = op.u.getvcpuinfo.online ? (int)op.u.getvcpuinfo.cpu : -1;
|
||||||
|
if (cpumaps != NULL && vcpu >= 0 && vcpu < maxinfo) {
|
||||||
|
cpumap = (unsigned char *)VIR_GET_CPUMAP(cpumaps, maplen, vcpu);
|
||||||
|
mapl = (maplen > (int)sizeof(cpumap_t)) ? (int)sizeof(cpumap_t) : maplen;
|
||||||
|
for (cpu = 0; cpu < (mapl * CHAR_BIT); cpu++) {
|
||||||
|
if (*pm & ((uint64_t)1<<cpu))
|
||||||
|
VIR_USE_CPU(cpumap, cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nbinfo;
|
||||||
|
}
|
||||||
|
@ -44,6 +44,18 @@ int xenHypervisorSetMaxMemory (virDomainPtr domain,
|
|||||||
unsigned long memory);
|
unsigned long memory);
|
||||||
int xenHypervisorCheckID (virConnectPtr conn,
|
int xenHypervisorCheckID (virConnectPtr conn,
|
||||||
int id);
|
int id);
|
||||||
|
int xenHypervisorSetVcpus (virDomainPtr domain,
|
||||||
|
unsigned int nvcpus);
|
||||||
|
int xenHypervisorPinVcpu (virDomainPtr domain,
|
||||||
|
unsigned int vcpu,
|
||||||
|
unsigned char *cpumap,
|
||||||
|
int maplen);
|
||||||
|
int xenHypervisorGetVcpus (virDomainPtr domain,
|
||||||
|
virVcpuInfoPtr info,
|
||||||
|
int maxinfo,
|
||||||
|
unsigned char *cpumaps,
|
||||||
|
int maplen);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1392,14 +1392,18 @@ xend_parse_sexp_desc_os(struct sexpr *node, virBufferPtr buf, int hvm)
|
|||||||
virBufferVSprintf(buf, " <loader>%s</loader>\n", tmp);
|
virBufferVSprintf(buf, " <loader>%s</loader>\n", tmp);
|
||||||
tmp = sexpr_node(node, "domain/image/hvm/boot");
|
tmp = sexpr_node(node, "domain/image/hvm/boot");
|
||||||
if ((tmp != NULL) && (tmp[0] != 0)) {
|
if ((tmp != NULL) && (tmp[0] != 0)) {
|
||||||
// FIXME:
|
/*
|
||||||
// Figure out how to map the 'a', 'b', 'c' nonsense to a
|
* FIXME:
|
||||||
// device.
|
* Figure out how to map the 'a', 'b', 'c' nonsense to a
|
||||||
|
* device.
|
||||||
|
*/
|
||||||
if (tmp[0] == 'a')
|
if (tmp[0] == 'a')
|
||||||
virBufferAdd(buf, " <boot dev='/dev/fd0'/>\n", 25 );
|
virBufferAdd(buf, " <boot dev='/dev/fd0'/>\n", 25 );
|
||||||
else if (tmp[0] == 'c')
|
else if (tmp[0] == 'c')
|
||||||
// Don't know what to put here. Say the vm has been given 3
|
/*
|
||||||
// disks - hda, hdb, hdc. How does one identify the boot disk?
|
* Don't know what to put here. Say the vm has been given 3
|
||||||
|
* disks - hda, hdb, hdc. How does one identify the boot disk?
|
||||||
|
*/
|
||||||
virBufferAdd(buf, " <boot dev='hda'/>\n", 22 );
|
virBufferAdd(buf, " <boot dev='hda'/>\n", 22 );
|
||||||
else if (strcmp(tmp, "d") == 0)
|
else if (strcmp(tmp, "d") == 0)
|
||||||
virBufferAdd(buf, " <boot dev='/dev/cdrom'/>\n", 24 );
|
virBufferAdd(buf, " <boot dev='/dev/cdrom'/>\n", 24 );
|
||||||
@ -2434,6 +2438,158 @@ xenDaemonLookupByID(virConnectPtr conn, int id) {
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xenDaemonDomainSetVcpus:
|
||||||
|
* @domain: pointer to domain object
|
||||||
|
* @nvcpus: the new number of virtual CPUs for this domain
|
||||||
|
*
|
||||||
|
* Dynamically change the number of virtual CPUs used by the domain.
|
||||||
|
*
|
||||||
|
* Returns 0 for success; -1 (with errno) on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xenDaemonDomainSetVcpus(virDomainPtr domain, int vcpus)
|
||||||
|
{
|
||||||
|
char buf[16];
|
||||||
|
|
||||||
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
|
||||||
|
|| (vcpus < 1)) {
|
||||||
|
virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
|
||||||
|
__FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf), "%d", vcpus);
|
||||||
|
return(xend_op(domain->conn, domain->name, "op", "set_vcpus", "vcpus",
|
||||||
|
buf, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xenDaemonDomainPinCpu:
|
||||||
|
* @domain: pointer to domain object
|
||||||
|
* @vcpu: virtual CPU number
|
||||||
|
* @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes)
|
||||||
|
* @maplen: length of cpumap in bytes
|
||||||
|
*
|
||||||
|
* Dynamically change the real CPUs which can be allocated to a virtual CPU.
|
||||||
|
*
|
||||||
|
* Returns 0 for success; -1 (with errno) on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xenDaemonDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
|
||||||
|
unsigned char *cpumap, int maplen)
|
||||||
|
{
|
||||||
|
char buf[16], mapstr[sizeof(cpumap_t) * 64] = "[";
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
|
||||||
|
|| (cpumap == NULL) || (maplen < 1) || (maplen > (int)sizeof(cpumap_t))) {
|
||||||
|
virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
|
||||||
|
__FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* from bit map, build character string of mapped CPU numbers */
|
||||||
|
for (i = 0; i < maplen; i++) for (j = 0; j < 8; j++)
|
||||||
|
if (cpumap[i] & (1 << j)) {
|
||||||
|
sprintf(buf, "%d,", (8 * i) + j);
|
||||||
|
strcat(mapstr, buf);
|
||||||
|
}
|
||||||
|
mapstr[strlen(mapstr) - 1] = ']';
|
||||||
|
snprintf(buf, sizeof(buf), "%d", vcpu);
|
||||||
|
return(xend_op(domain->conn, domain->name, "op", "pincpu", "vcpu", buf,
|
||||||
|
"cpumap", mapstr, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainGetVcpus:
|
||||||
|
* @domain: pointer to domain object, or NULL for Domain0
|
||||||
|
* @info: pointer to an array of virVcpuInfo structures (OUT)
|
||||||
|
* @maxinfo: number of structures in info array
|
||||||
|
* @cpumaps: pointer to an bit map of real CPUs for all vcpus of this domain (in 8-bit bytes) (OUT)
|
||||||
|
* If cpumaps is NULL, then no cupmap information is returned by the API.
|
||||||
|
* It's assumed there is <maxinfo> cpumap in cpumaps array.
|
||||||
|
* The memory allocated to cpumaps must be (maxinfo * maplen) bytes
|
||||||
|
* (ie: calloc(maxinfo, maplen)).
|
||||||
|
* One cpumap inside cpumaps has the format described in virDomainPinVcpu() API.
|
||||||
|
* @maplen: number of bytes in one cpumap, from 1 up to size of CPU map in
|
||||||
|
* underlying virtualization system (Xen...).
|
||||||
|
*
|
||||||
|
* Extract information about virtual CPUs of domain, store it in info array
|
||||||
|
* and also in cpumaps if this pointer is'nt NULL.
|
||||||
|
*
|
||||||
|
* Returns the number of info filled in case of success, -1 in case of failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xenDaemonDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
|
||||||
|
unsigned char *cpumaps, int maplen)
|
||||||
|
{
|
||||||
|
struct sexpr *root, *s, *t;
|
||||||
|
virVcpuInfoPtr ipt = info;
|
||||||
|
int nbinfo = 0, oln;
|
||||||
|
unsigned char *cpumap;
|
||||||
|
int vcpu, cpu;
|
||||||
|
|
||||||
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
|
||||||
|
|| (info == NULL) || (maxinfo < 1)) {
|
||||||
|
virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
|
||||||
|
__FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (cpumaps != NULL && maplen < 1) {
|
||||||
|
virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
|
||||||
|
__FUNCTION__);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
root = sexpr_get(domain->conn, "/xend/domain/%s?op=vcpuinfo", domain->name);
|
||||||
|
if (root == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (cpumaps != NULL)
|
||||||
|
memset(cpumaps, 0, maxinfo * maplen);
|
||||||
|
|
||||||
|
/* scan the sexprs from "(vcpu (number x)...)" and get parameter values */
|
||||||
|
for (s = root; s->kind == SEXPR_CONS; s = s->cdr)
|
||||||
|
if ((s->car->kind == SEXPR_CONS) &&
|
||||||
|
(s->car->car->kind == SEXPR_VALUE) &&
|
||||||
|
!strcmp(s->car->car->value, "vcpu")) {
|
||||||
|
t = s->car;
|
||||||
|
vcpu = ipt->number = sexpr_int(t, "vcpu/number");
|
||||||
|
if (oln = sexpr_int(t, "vcpu/online")) {
|
||||||
|
if (sexpr_int(t, "vcpu/running")) ipt->state = VIR_VCPU_RUNNING;
|
||||||
|
if (sexpr_int(t, "vcpu/blocked")) ipt->state = VIR_VCPU_BLOCKED;
|
||||||
|
}
|
||||||
|
else ipt->state = VIR_VCPU_OFFLINE;
|
||||||
|
ipt->cpuTime = sexpr_float(t, "vcpu/cpu_time") * 1000000000;
|
||||||
|
ipt->cpu = oln ? sexpr_int(t, "vcpu/cpu") : -1;
|
||||||
|
|
||||||
|
if (cpumaps != NULL && vcpu >= 0 && vcpu < maxinfo) {
|
||||||
|
cpumap = (unsigned char *) VIR_GET_CPUMAP(cpumaps, maplen, vcpu);
|
||||||
|
/*
|
||||||
|
* get sexpr from "(cpumap (x y z...))" and convert values
|
||||||
|
* to bitmap
|
||||||
|
*/
|
||||||
|
for (t = t->cdr; t->kind == SEXPR_CONS; t = t->cdr)
|
||||||
|
if ((t->car->kind == SEXPR_CONS) &&
|
||||||
|
(t->car->car->kind == SEXPR_VALUE) &&
|
||||||
|
!strcmp(t->car->car->value, "cpumap") &&
|
||||||
|
(t->car->cdr->kind == SEXPR_CONS)) {
|
||||||
|
for (t = t->car->cdr->car; t->kind == SEXPR_CONS; t = t->cdr)
|
||||||
|
if (t->car->kind == SEXPR_VALUE) {
|
||||||
|
cpu = strtol(t->car->value, NULL, 0);
|
||||||
|
if (cpu >= 0)
|
||||||
|
VIR_USE_CPU(cpumap, cpu);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++nbinfo == maxinfo) break;
|
||||||
|
ipt++;
|
||||||
|
}
|
||||||
|
sexpr_free(root);
|
||||||
|
return(nbinfo);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xenDaemonLookupByUUID:
|
* xenDaemonLookupByUUID:
|
||||||
* @conn: pointer to the hypervisor connection
|
* @conn: pointer to the hypervisor connection
|
||||||
|
@ -631,6 +631,18 @@ virDomainPtr xenDaemonDomainLookupByName(virConnectPtr conn, const char *domname
|
|||||||
unsigned long xenDaemonDomainGetMaxMemory(virDomainPtr domain);
|
unsigned long xenDaemonDomainGetMaxMemory(virDomainPtr domain);
|
||||||
char **xenDaemonListDomainsOld(virConnectPtr xend);
|
char **xenDaemonListDomainsOld(virConnectPtr xend);
|
||||||
|
|
||||||
|
int xenDaemonDomainSetVcpus (virDomainPtr domain,
|
||||||
|
int vcpus);
|
||||||
|
int xenDaemonDomainPinVcpu (virDomainPtr domain,
|
||||||
|
unsigned int vcpu,
|
||||||
|
unsigned char *cpumap,
|
||||||
|
int maplen);
|
||||||
|
int xenDaemonDomainGetVcpus (virDomainPtr domain,
|
||||||
|
virVcpuInfoPtr info,
|
||||||
|
int maxinfo,
|
||||||
|
unsigned char *cpumaps,
|
||||||
|
int maplen);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user