Really, fixed struct for getdomaininfo to work on both 3.0.2 & 3.0.3 on 32-bit archs this time.

This commit is contained in:
Daniel P. Berrange 2006-09-28 23:29:25 +00:00
parent 01ae3678f1
commit 26d1767317
2 changed files with 433 additions and 309 deletions

View File

@ -1,3 +1,12 @@
Thu Sep 21 10:19:02 EDT 2006 Daniel Berrange <berrange@redhat.com>
* src/xen_internal.c: Fork different version of getdomaininfo struct for
Xen 3.0.2, and 3.0.3 because the shared_info_frame field is different
size on between these versions on 32-bit platforms. Make callers use
appropriate struct version matched to hypervisor version, hiding detail
in macros to aid readability. Cleanup whitespace to remove tabs. Disable
xenHypervisorGetVcpus completely in proxy since its not used.
Thu Sep 21 10:19:02 EDT 2006 Daniel Berrange <berrange@redhat.com>
* src/xend_internal.c: Check if the physical CPU will fit in the maplen

View File

@ -99,13 +99,109 @@ struct xen_v0_getdomaininfo {
};
typedef struct xen_v0_getdomaininfo xen_v0_getdomaininfo;
struct xen_v0_getdomaininfolist {
struct xen_v2_getdomaininfo {
domid_t domain; /* the domain number */
uint32_t flags; /* falgs, see before */
uint64_t tot_pages; /* total number of pages used */
uint64_t max_pages; /* maximum number of pages allowed */
uint64_t shared_info_frame; /* MFN of shared_info struct */
uint64_t cpu_time; /* CPU time used */
uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */
uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
uint32_t ssidref;
xen_domain_handle_t handle;
};
typedef struct xen_v2_getdomaininfo xen_v2_getdomaininfo;
union xen_getdomaininfo {
struct xen_v0_getdomaininfo v0;
struct xen_v2_getdomaininfo v2;
};
typedef union xen_getdomaininfo xen_getdomaininfo;
union xen_getdomaininfolist {
struct xen_v0_getdomaininfo *v0;
struct xen_v2_getdomaininfo *v2;
};
typedef union xen_getdomaininfolist xen_getdomaininfolist;
#define XEN_GETDOMAININFOLIST_ALLOC(domlist, size) \
(hypervisor_version < 2 ? \
((domlist.v0 = malloc(sizeof(xen_v0_getdomaininfo)*(size))) != NULL) : \
((domlist.v2 = malloc(sizeof(xen_v2_getdomaininfo)*(size))) != NULL))
#define XEN_GETDOMAININFOLIST_FREE(domlist) \
(hypervisor_version < 2 ? \
free(domlist.v0) : \
free(domlist.v2))
#define XEN_GETDOMAININFOLIST_CLEAR(domlist, size) \
(hypervisor_version < 2 ? \
memset(domlist.v0, 0, sizeof(xen_v0_getdomaininfo) * size) : \
memset(domlist.v2, 0, sizeof(xen_v2_getdomaininfo) * size))
#define XEN_GETDOMAININFOLIST_DOMAIN(domlist, n) \
(hypervisor_version < 2 ? \
domlist.v0[n].domain : \
domlist.v2[n].domain)
#define XEN_GETDOMAININFO_CLEAR(dominfo) \
(hypervisor_version < 2 ? \
memset(&(dominfo.v0), 0, sizeof(xen_v0_getdomaininfo)) : \
memset(&(dominfo.v2), 0, sizeof(xen_v2_getdomaininfo)))
#define XEN_GETDOMAININFO_DOMAIN(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.domain : \
dominfo.v2.domain)
#define XEN_GETDOMAININFO_CPUTIME(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.cpu_time : \
dominfo.v2.cpu_time)
#define XEN_GETDOMAININFO_CPUCOUNT(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.nr_online_vcpus : \
dominfo.v2.nr_online_vcpus)
#define XEN_GETDOMAININFO_FLAGS(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.flags : \
dominfo.v2.flags)
#define XEN_GETDOMAININFO_TOT_PAGES(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.tot_pages : \
dominfo.v2.tot_pages)
#define XEN_GETDOMAININFO_MAX_PAGES(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.max_pages : \
dominfo.v2.max_pages)
struct xen_v0_getdomaininfolistop {
domid_t first_domain;
uint32_t max_domains;
struct xen_v0_getdomaininfo *buffer;
uint32_t num_domains;
};
typedef struct xen_v0_getdomaininfolist xen_v0_getdomaininfolist;
typedef struct xen_v0_getdomaininfolistop xen_v0_getdomaininfolistop;
struct xen_v2_getdomaininfolistop {
domid_t first_domain;
uint32_t max_domains;
struct xen_v2_getdomaininfo *buffer;
uint32_t num_domains;
};
typedef struct xen_v2_getdomaininfolistop xen_v2_getdomaininfolistop;
struct xen_v0_domainop {
domid_t domain;
@ -244,7 +340,7 @@ struct xen_op_v0 {
uint32_t cmd;
uint32_t interface_version;
union {
xen_v0_getdomaininfolist getdomaininfolist;
xen_v0_getdomaininfolistop getdomaininfolist;
xen_v0_domainop domain;
xen_v0_setmaxmem setmaxmem;
xen_v0_setmaxvcpu setmaxvcpu;
@ -261,7 +357,7 @@ struct xen_op_v2_sys {
uint32_t cmd;
uint32_t interface_version;
union {
xen_v0_getdomaininfolist getdomaininfolist;
xen_v2_getdomaininfolistop getdomaininfolist;
uint8_t padding[128];
} u;
};
@ -545,7 +641,7 @@ xenHypervisorDoV2Dom(int handle, xen_op_v2_dom* op)
*/
static int
virXen_getdomaininfolist(int handle, int first_domain, int maxids,
xen_v0_getdomaininfo *dominfos)
xen_getdomaininfolist *dominfos)
{
int ret = -1;
@ -561,7 +657,7 @@ virXen_getdomaininfolist(int handle, int first_domain, int maxids,
op.cmd = XEN_V2_OP_GETDOMAININFOLIST;
op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
op.u.getdomaininfolist.max_domains = maxids;
op.u.getdomaininfolist.buffer = dominfos;
op.u.getdomaininfolist.buffer = dominfos->v2;
op.u.getdomaininfolist.num_domains = maxids;
ret = xenHypervisorDoV2Sys(handle, &op);
if (ret == 0)
@ -573,7 +669,7 @@ virXen_getdomaininfolist(int handle, int first_domain, int maxids,
op.cmd = XEN_V1_OP_GETDOMAININFOLIST;
op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
op.u.getdomaininfolist.max_domains = maxids;
op.u.getdomaininfolist.buffer = dominfos;
op.u.getdomaininfolist.buffer = dominfos->v0;
op.u.getdomaininfolist.num_domains = maxids;
ret = xenHypervisorDoV1Op(handle, &op);
if (ret == 0)
@ -585,7 +681,7 @@ virXen_getdomaininfolist(int handle, int first_domain, int maxids,
op.cmd = XEN_V0_OP_GETDOMAININFOLIST;
op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
op.u.getdomaininfolist.max_domains = maxids;
op.u.getdomaininfolist.buffer = dominfos;
op.u.getdomaininfolist.buffer = dominfos->v0;
op.u.getdomaininfolist.num_domains = maxids;
ret = xenHypervisorDoV0Op(handle, &op);
if (ret == 0)
@ -599,6 +695,21 @@ virXen_getdomaininfolist(int handle, int first_domain, int maxids,
return(ret);
}
static int
virXen_getdomaininfo(int handle, int first_domain,
xen_getdomaininfo *dominfo) {
xen_getdomaininfolist dominfos;
if (hypervisor_version < 2) {
dominfos.v0 = &(dominfo->v0);
} else {
dominfos.v2 = &(dominfo->v2);
}
return virXen_getdomaininfolist(handle, first_domain, 1, &dominfos);
}
#ifndef PROXY
/**
* virXen_pausedomain:
@ -998,7 +1109,7 @@ int xenHypervisorInit(void)
int fd, ret, cmd;
hypercall_t hc;
v0_hypercall_t v0_hc;
xen_v0_getdomaininfo info;
xen_getdomaininfo info;
if (initialized) {
if (hypervisor_version == -1)
@ -1063,7 +1174,7 @@ int xenHypervisorInit(void)
in_init = 0;
return(-1);
detect_v2:
detect_v2:
/*
* The hypercalls were refactored into 3 different section in August 2006
* Try to detect if we are running a version post 3.0.2 with the new ones
@ -1073,7 +1184,7 @@ detect_v2:
/* TODO: one probably will need to autodetect thse subversions too */
sys_interface_version = 2; /* XEN_SYSCTL_INTERFACE_VERSION */
dom_interface_version = 3; /* XEN_DOMCTL_INTERFACE_VERSION */
if (virXen_getdomaininfolist(fd, 0, 1, &info) == 1) {
if (virXen_getdomaininfo(fd, 0, &info) == 1) {
#ifdef DEBUG
fprintf(stderr, "Using hypervisor call v2, sys version 2\n");
#endif
@ -1081,7 +1192,7 @@ detect_v2:
}
hypervisor_version = 1;
sys_interface_version = -1;
if (virXen_getdomaininfolist(fd, 0, 1, &info) == 1) {
if (virXen_getdomaininfo(fd, 0, &info) == 1) {
#ifdef DEBUG
fprintf(stderr, "Using hypervisor call v1\n");
#endif
@ -1098,7 +1209,7 @@ detect_v2:
in_init = 0;
return(-1);
done:
done:
close(fd);
in_init = 0;
return(0);
@ -1227,7 +1338,7 @@ xenHypervisorGetVersion(virConnectPtr conn, unsigned long *hvVer)
int
xenHypervisorNumOfDomains(virConnectPtr conn)
{
xen_v0_getdomaininfo *dominfos;
xen_getdomaininfolist dominfos;
int ret, nbids;
static int last_maxids = 2;
int maxids = last_maxids;
@ -1235,19 +1346,18 @@ xenHypervisorNumOfDomains(virConnectPtr conn)
if ((conn == NULL) || (conn->handle < 0))
return (-1);
retry:
dominfos = malloc(maxids * sizeof(xen_v0_getdomaininfo));
if (dominfos == NULL) {
retry:
if (!(XEN_GETDOMAININFOLIST_ALLOC(dominfos, maxids))) {
virXenError(VIR_ERR_NO_MEMORY, _("allocating %d domain info"),
maxids);
return(-1);
}
memset(dominfos, 0, sizeof(xen_v0_getdomaininfo) * maxids);
XEN_GETDOMAININFOLIST_CLEAR(dominfos, maxids);
ret = virXen_getdomaininfolist(conn->handle, 0, maxids, dominfos);
ret = virXen_getdomaininfolist(conn->handle, 0, maxids, &dominfos);
free(dominfos);
XEN_GETDOMAININFOLIST_FREE(dominfos);
if (ret < 0)
return (-1);
@ -1276,41 +1386,40 @@ retry:
int
xenHypervisorListDomains(virConnectPtr conn, int *ids, int maxids)
{
xen_v0_getdomaininfo *dominfos;
xen_getdomaininfolist dominfos;
int ret, nbids, i;
if ((conn == NULL) || (conn->handle < 0) ||
(ids == NULL) || (maxids < 1))
return (-1);
dominfos = malloc(maxids * sizeof(xen_v0_getdomaininfo));
if (dominfos == NULL) {
if (!(XEN_GETDOMAININFOLIST_ALLOC(dominfos, maxids))) {
virXenError(VIR_ERR_NO_MEMORY, "allocating %d domain info",
maxids);
return(-1);
}
memset(dominfos, 0, sizeof(xen_v0_getdomaininfo) * maxids);
XEN_GETDOMAININFOLIST_CLEAR(dominfos, maxids);
memset(ids, 0, maxids * sizeof(int));
ret = virXen_getdomaininfolist(conn->handle, 0, maxids, dominfos);
ret = virXen_getdomaininfolist(conn->handle, 0, maxids, &dominfos);
if (ret < 0) {
free(dominfos);
XEN_GETDOMAININFOLIST_FREE(dominfos);
return (-1);
}
nbids = ret;
if ((nbids < 0) || (nbids > maxids)) {
free(dominfos);
XEN_GETDOMAININFOLIST_FREE(dominfos);
return(-1);
}
for (i = 0;i < nbids;i++) {
ids[i] = dominfos[i].domain;
ids[i] = XEN_GETDOMAININFOLIST_DOMAIN(dominfos, i);
}
free(dominfos);
XEN_GETDOMAININFOLIST_FREE(dominfos);
return (nbids);
}
@ -1327,21 +1436,20 @@ xenHypervisorListDomains(virConnectPtr conn, int *ids, int maxids)
unsigned long
xenHypervisorGetDomMaxMemory(virConnectPtr conn, int id)
{
xen_v0_getdomaininfo dominfo;
xen_getdomaininfo dominfo;
int ret;
if ((conn == NULL) || (conn->handle < 0))
return (0);
memset(&dominfo, 0, sizeof(xen_v0_getdomaininfo));
XEN_GETDOMAININFO_CLEAR(dominfo);
dominfo.domain = id;
ret = virXen_getdomaininfolist(conn->handle, id, 1, &dominfo);
ret = virXen_getdomaininfo(conn->handle, id, &dominfo);
if ((ret < 0) || (dominfo.domain != id))
if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != id))
return (0);
return((unsigned long) dominfo.max_pages * 4);
return((unsigned long) XEN_GETDOMAININFO_MAX_PAGES(dominfo) * 4);
}
#ifndef PROXY
@ -1379,21 +1487,21 @@ xenHypervisorGetMaxMemory(virDomainPtr domain)
int
xenHypervisorGetDomInfo(virConnectPtr conn, int id, virDomainInfoPtr info)
{
xen_v0_getdomaininfo dominfo;
xen_getdomaininfo dominfo;
int ret;
if ((conn == NULL) || (conn->handle < 0) || (info == NULL))
return (-1);
memset(info, 0, sizeof(virDomainInfo));
memset(&dominfo, 0, sizeof(xen_v0_getdomaininfo));
XEN_GETDOMAININFO_CLEAR(dominfo);
ret = virXen_getdomaininfolist(conn->handle, id, 1, &dominfo);
ret = virXen_getdomaininfo(conn->handle, id, &dominfo);
if ((ret < 0) || (dominfo.domain != id))
if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != id))
return (-1);
switch (dominfo.flags & 0xFF) {
switch (XEN_GETDOMAININFO_FLAGS(dominfo) & 0xFF) {
case DOMFLAGS_DYING:
info->state = VIR_DOMAIN_SHUTDOWN;
break;
@ -1418,10 +1526,10 @@ xenHypervisorGetDomInfo(virConnectPtr conn, int id, virDomainInfoPtr info)
* convert to microseconds, same thing convert to
* kilobytes from page counts
*/
info->cpuTime = dominfo.cpu_time;
info->memory = dominfo.tot_pages * 4;
info->maxMem = dominfo.max_pages * 4;
info->nrVirtCpu = dominfo.nr_online_vcpus;
info->cpuTime = XEN_GETDOMAININFO_CPUTIME(dominfo);
info->memory = XEN_GETDOMAININFO_TOT_PAGES(dominfo) * 4;
info->maxMem = XEN_GETDOMAININFO_MAX_PAGES(dominfo) * 4;
info->nrVirtCpu = XEN_GETDOMAININFO_CPUCOUNT(dominfo);
return (0);
}
@ -1615,12 +1723,12 @@ xenHypervisorPinVcpu(virDomainPtr domain, unsigned int vcpu,
*
* Returns the number of info filled in case of success, -1 in case of failure.
*/
#ifndef PROXY
int
xenHypervisorGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
unsigned char *cpumaps, int maplen)
{
#ifndef PROXY
xen_v0_getdomaininfo dominfo;
xen_getdomaininfo dominfo;
int ret;
virVcpuInfoPtr ipt;
@ -1634,13 +1742,13 @@ xenHypervisorGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
return -1;
/* first get the number of virtual CPUs in this domain */
memset(&dominfo, 0, sizeof(xen_v0_getdomaininfo));
ret = virXen_getdomaininfolist(domain->conn->handle, domain->handle,
1, &dominfo);
XEN_GETDOMAININFO_CLEAR(dominfo);
ret = virXen_getdomaininfo(domain->conn->handle, domain->handle,
&dominfo);
if ((ret < 0) || (dominfo.domain != domain->handle))
if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != domain->handle))
return (-1);
nbinfo = dominfo.max_vcpu_id + 1;
nbinfo = XEN_GETDOMAININFO_CPUCOUNT(dominfo) + 1;
if (nbinfo > maxinfo) nbinfo = maxinfo;
if (cpumaps != NULL)
@ -1662,7 +1770,14 @@ xenHypervisorGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
}
}
return nbinfo;
#else
return(-1);
#endif
}
#endif
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/