Speed up impl of lookupbyid/uuid and getostype for Xen by using HV where available

This commit is contained in:
Daniel P. Berrange 2007-08-10 18:25:15 +00:00
parent 46b433f069
commit 9112a139df
6 changed files with 197 additions and 1 deletions

View File

@ -1,3 +1,11 @@
Fri Aug 10 14:25:00 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* src/xen_internal.c, src/xen_internal.h, src/xen_unified.c:
Add impls of the DomainGetOSType, DomainLookupByID and
DomainLookupByName drivers using the HV for speed
* src/xs_internal.c, src/xs_internal.h: Add helper method to
lookup a domain name based on its ID
Thu Aug 9 14:27:00 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* src/libvirt.c, src/openvz_conf.c, src/qemu_conf.c,

View File

@ -27,6 +27,7 @@
#include <regex.h>
#include <errno.h>
#include <sys/utsname.h>
#include "xs_internal.h"
/* required for dom0_getdomaininfo_t */
#include <xen/dom0_ops.h>
@ -229,6 +230,13 @@ typedef union xen_getschedulerid xen_getschedulerid;
domlist.v2[n].domain : \
domlist.v2d5[n].domain))
#define XEN_GETDOMAININFOLIST_UUID(domlist, n) \
(hypervisor_version < 2 ? \
domlist.v0[n].handle : \
(dom_interface_version < 5 ? \
domlist.v2[n].handle : \
domlist.v2d5[n].handle))
#define XEN_GETDOMAININFOLIST_DATA(domlist) \
(hypervisor_version < 2 ? \
(void*)(domlist->v0) : \
@ -299,6 +307,13 @@ typedef union xen_getschedulerid xen_getschedulerid;
dominfo.v2.max_pages : \
dominfo.v2d5.max_pages))
#define XEN_GETDOMAININFO_UUID(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.handle : \
(dom_interface_version < 5 ? \
dominfo.v2.handle : \
dominfo.v2d5.handle))
struct xen_v0_getdomaininfolistop {
@ -626,7 +641,7 @@ struct xenUnifiedDriver xenHypervisorDriver = {
NULL, /* domainShutdown */
NULL, /* domainReboot */
xenHypervisorDestroyDomain, /* domainDestroy */
NULL, /* domainGetOSType */
xenHypervisorDomainGetOSType, /* domainGetOSType */
xenHypervisorGetMaxMemory, /* domainGetMaxMemory */
xenHypervisorSetMaxMemory, /* domainSetMaxMemory */
NULL, /* domainSetMemory */
@ -2437,6 +2452,136 @@ xenHypervisorListDomains(virConnectPtr conn, int *ids, int maxids)
return (nbids);
}
#ifndef PROXY
char *
xenHypervisorDomainGetOSType (virDomainPtr dom)
{
xenUnifiedPrivatePtr priv;
xen_getdomaininfo dominfo;
priv = (xenUnifiedPrivatePtr) dom->conn->privateData;
if (priv->handle < 0)
return (NULL);
/* HV's earlier than 3.1.0 don't include the HVM flags in guests status*/
if (hypervisor_version < 2 ||
dom_interface_version < 4)
return (NULL);
XEN_GETDOMAININFO_CLEAR(dominfo);
if (virXen_getdomaininfo(priv->handle, dom->id, &dominfo) < 0)
return (NULL);
if (XEN_GETDOMAININFO_DOMAIN(dominfo) != dom->id)
return (NULL);
if (XEN_GETDOMAININFO_FLAGS(dominfo) & DOMFLAGS_HVM)
return strdup("hvm");
return strdup("linux");
}
virDomainPtr
xenHypervisorLookupDomainByID(virConnectPtr conn,
int id)
{
xenUnifiedPrivatePtr priv;
xen_getdomaininfo dominfo;
virDomainPtr ret;
char *name;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->handle < 0)
return (NULL);
XEN_GETDOMAININFO_CLEAR(dominfo);
if (virXen_getdomaininfo(priv->handle, id, &dominfo) < 0)
return (NULL);
if (XEN_GETDOMAININFO_DOMAIN(dominfo) != id)
return (NULL);
if (!(name = xenStoreDomainGetName(conn, id)))
return (NULL);
ret = virGetDomain(conn, name, XEN_GETDOMAININFO_UUID(dominfo));
if (ret)
ret->id = id;
free(name);
return ret;
}
virDomainPtr
xenHypervisorLookupDomainByUUID(virConnectPtr conn,
const unsigned char *uuid)
{
xen_getdomaininfolist dominfos;
xenUnifiedPrivatePtr priv;
virDomainPtr ret;
char *name;
int maxids = 100, nids, i, id;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->handle < 0)
return (NULL);
retry:
if (!(XEN_GETDOMAININFOLIST_ALLOC(dominfos, maxids))) {
virXenError(VIR_ERR_NO_MEMORY, "allocating %d domain info",
maxids);
return(NULL);
}
XEN_GETDOMAININFOLIST_CLEAR(dominfos, maxids);
nids = virXen_getdomaininfolist(priv->handle, 0, maxids, &dominfos);
if (nids < 0) {
XEN_GETDOMAININFOLIST_FREE(dominfos);
return (NULL);
}
/* Can't possibly have more than 65,000 concurrent guests
* so limit how many times we try, to avoid increasing
* without bound & thus allocating all of system memory !
* XXX I'll regret this comment in a few years time ;-)
*/
if (nids == maxids) {
XEN_GETDOMAININFOLIST_FREE(dominfos);
if (maxids < 65000) {
maxids *= 2;
goto retry;
}
return (NULL);
}
id = -1;
for (i = 0 ; i < nids ; i++) {
if (memcmp(XEN_GETDOMAININFOLIST_UUID(dominfos, i), uuid, VIR_UUID_BUFLEN) == 0) {
id = XEN_GETDOMAININFOLIST_DOMAIN(dominfos, i);
break;
}
}
XEN_GETDOMAININFOLIST_FREE(dominfos);
if (id == -1)
return (NULL);
if (!(name = xenStoreDomainGetName(conn, id)))
return (NULL);
ret = virGetDomain(conn, name, uuid);
if (ret)
ret->id = id;
free(name);
return ret;
}
#endif
/**
* xenHypervisorGetMaxVcpus:
*

View File

@ -20,6 +20,15 @@ int xenHypervisorInit (void);
/* The following calls are made directly by the Xen proxy: */
virDomainPtr
xenHypervisorLookupDomainByID (virConnectPtr conn,
int id);
virDomainPtr
xenHypervisorLookupDomainByUUID(virConnectPtr conn,
const unsigned char *uuid);
char *
xenHypervisorDomainGetOSType (virDomainPtr dom);
int xenHypervisorOpen (virConnectPtr conn,
const char *name,
int flags);

View File

@ -377,6 +377,13 @@ xenUnifiedDomainLookupByID (virConnectPtr conn, int id)
*/
virConnResetLastError (conn);
/* Try hypervisor/xenstore combo. */
if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET]) {
ret = xenHypervisorLookupDomainByID (conn, id);
if (ret || conn->err.code != VIR_ERR_OK)
return ret;
}
/* Try proxy. */
if (priv->opened[XEN_UNIFIED_PROXY_OFFSET]) {
ret = xenProxyLookupByID (conn, id);
@ -408,6 +415,13 @@ xenUnifiedDomainLookupByUUID (virConnectPtr conn,
*/
virConnResetLastError (conn);
/* Try hypervisor/xenstore combo. */
if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET]) {
ret = xenHypervisorLookupDomainByUUID (conn, uuid);
if (ret || conn->err.code != VIR_ERR_OK)
return ret;
}
/* Try proxy. */
if (priv->opened[XEN_UNIFIED_PROXY_OFFSET]) {
ret = xenProxyLookupByUUID (conn, uuid);

View File

@ -875,6 +875,22 @@ xenStoreDomainGetNetworkID(virConnectPtr conn, int id, const char *mac) {
return(ret);
}
char *xenStoreDomainGetName(virConnectPtr conn,
int id) {
char prop[200];
xenUnifiedPrivatePtr priv;
unsigned int len;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->xshandle == NULL)
return(NULL);
snprintf(prop, 199, "/local/domain/%d/name", id);
prop[199] = 0;
return xs_read(priv->xshandle, 0, prop, &len);
}
#endif /* WITH_XEN */
/*
* Local variables:

View File

@ -15,6 +15,8 @@
extern "C" {
#endif
#include "internal.h"
extern struct xenUnifiedDriver xenStoreDriver;
int xenStoreInit (void);
@ -48,6 +50,8 @@ char * xenStoreDomainGetOSTypeID(virConnectPtr conn,
char * xenStoreDomainGetNetworkID(virConnectPtr conn,
int id,
const char *mac);
char * xenStoreDomainGetName(virConnectPtr conn,
int id);
#ifdef __cplusplus
}