? src/demo.txt Index: src/xen_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xen_internal.c,v retrieving revision 1.90 diff -u -p -r1.90 xen_internal.c --- src/xen_internal.c 30 Jul 2007 10:15:58 -0000 1.90 +++ src/xen_internal.c 9 Aug 2007 22:01:57 -0000 @@ -27,6 +27,7 @@ #include #include #include +#include "xs_internal.h" /* required for dom0_getdomaininfo_t */ #include @@ -229,6 +230,13 @@ typedef union xen_getschedulerid xen_get 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_get 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 xenHypervisorDri NULL, /* domainShutdown */ NULL, /* domainReboot */ xenHypervisorDestroyDomain, /* domainDestroy */ - NULL, /* domainGetOSType */ + xenHypervisorDomainGetOSType, /* domainGetOSType */ xenHypervisorGetMaxMemory, /* domainGetMaxMemory */ xenHypervisorSetMaxMemory, /* domainSetMaxMemory */ NULL, /* domainSetMemory */ @@ -2437,6 +2452,136 @@ xenHypervisorListDomains(virConnectPtr c 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: * Index: src/xen_internal.h =================================================================== RCS file: /data/cvs/libvirt/src/xen_internal.h,v retrieving revision 1.21 diff -u -p -r1.21 xen_internal.h --- src/xen_internal.h 6 Jul 2007 15:11:22 -0000 1.21 +++ src/xen_internal.h 9 Aug 2007 22:01:57 -0000 @@ -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); Index: src/xen_unified.c =================================================================== RCS file: /data/cvs/libvirt/src/xen_unified.c,v retrieving revision 1.17 diff -u -p -r1.17 xen_unified.c --- src/xen_unified.c 12 Jul 2007 08:34:51 -0000 1.17 +++ src/xen_unified.c 9 Aug 2007 22:01:57 -0000 @@ -377,6 +377,13 @@ xenUnifiedDomainLookupByID (virConnectPt */ 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 (virConnect */ 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); Index: src/xs_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xs_internal.c,v retrieving revision 1.46 diff -u -p -r1.46 xs_internal.c --- src/xs_internal.c 6 Jul 2007 15:11:22 -0000 1.46 +++ src/xs_internal.c 9 Aug 2007 22:01:57 -0000 @@ -875,6 +875,22 @@ xenStoreDomainGetNetworkID(virConnectPtr 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: Index: src/xs_internal.h =================================================================== RCS file: /data/cvs/libvirt/src/xs_internal.h,v retrieving revision 1.10 diff -u -p -r1.10 xs_internal.h --- src/xs_internal.h 6 Jul 2007 15:11:22 -0000 1.10 +++ src/xs_internal.h 9 Aug 2007 22:01:57 -0000 @@ -15,6 +15,8 @@ extern "C" { #endif +#include "internal.h" + extern struct xenUnifiedDriver xenStoreDriver; int xenStoreInit (void); @@ -48,6 +50,8 @@ char * xenStoreDomainGetOSTypeID(virCon char * xenStoreDomainGetNetworkID(virConnectPtr conn, int id, const char *mac); +char * xenStoreDomainGetName(virConnectPtr conn, + int id); #ifdef __cplusplus }