]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
* src/hash.c src/internal.h: add virGetDomainByID() to speed up
authorDaniel Veillard <veillard@redhat.com>
Mon, 24 Apr 2006 18:21:29 +0000 (18:21 +0000)
committerDaniel Veillard <veillard@redhat.com>
Mon, 24 Apr 2006 18:21:29 +0000 (18:21 +0000)
  some processing but not used yet
* src/libvirt.c src/xen_internal.c src/xen_internal.h: added domain
  listing and number queries entry points based on the hypervisor
  which should speed up some processing as root.
Daniel

ChangeLog
src/hash.c
src/internal.h
src/libvirt.c
src/xen_internal.c
src/xen_internal.h

index bfbb11928e95519741720518e8bbd0cf3b4e21f7..239315ad1cd75e8039c9b2a52ebc74e32fde9093 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Apr 24 18:23:29 EDT 2006 Daniel Veillard <veillard@redhat.com>
+
+       * src/hash.c src/internal.h: add virGetDomainByID() to speed up
+         some processing but not used yet
+       * src/libvirt.c src/xen_internal.c src/xen_internal.h: added domain
+         listing and number queries entry points based on the hypervisor
+         which should speed up some processing as root.
+
 Thu Apr 20 14:31:13 EDT 2006 Daniel Veillard <veillard@redhat.com>
 
        * src/xend_internal.c: fix an uninitialized memory access in error
index 69c070de2a567ef7d83ea7e25fdc89df15b8e955..b231e7c5ed799a09aee611a3c108eb91a4b95a48 100644 (file)
@@ -723,3 +723,47 @@ done:
     return(ret);
 }
 
+/**
+ * virGetDomainByID:
+ * @conn: the hypervisor connection
+ * @id: the ID number for the domain
+ *
+ * Lookup if the domain ID is already registered for that connection,
+ * if yes return a new pointer to it, if no return NULL
+ *
+ * Returns a pointer to the domain, or NULL if not found
+ */
+virDomainPtr
+virGetDomainByID(virConnectPtr conn, int id) {
+    virDomainPtr ret = NULL, cur;
+    virHashEntryPtr iter, next;
+    virHashTablePtr table;
+    int key;
+
+    if ((!VIR_IS_CONNECT(conn)) || (id < 0)) {
+        virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(NULL);
+    }
+    xmlMutexLock(conn->domains_mux);
+
+    table = conn->domains;
+    if ((table == NULL) || (table->nbElems == 0))
+        goto done;
+    for (key = 0;key < table->size;key++) {
+        if (table->table[key].valid == 0)
+           continue;
+       iter = &(table->table[key]);
+       while (iter != NULL) {
+           next = iter->next;
+           cur = (virDomainPtr) iter->payload;
+           if ((cur != NULL) && (cur->handle == id)) {
+               ret = cur;
+               goto done;
+           }
+           iter = next;
+       }
+    }
+done:
+    xmlMutexUnlock(conn->domains_mux);
+    return(ret);
+}
index 3e49b61fd1311ba674797cd0f5e272245a6af99c..a3d81e7a22c83c3f1a7c63b7415e9526724e6ac8 100644 (file)
@@ -172,7 +172,7 @@ const char *__virErrorMsg(virErrorNumber error, const char *info);
 
 /************************************************************************
  *                                                                     *
- *             API for domain/connections (de)allocations              *
+ *     API for domain/connections (de)allocations and lookups          *
  *                                                                     *
  ************************************************************************/
 
@@ -183,6 +183,8 @@ virDomainPtr        virGetDomain    (virConnectPtr conn,
                                 const char *uuid);
 int            virFreeDomain   (virConnectPtr conn,
                                 virDomainPtr domain);
+virDomainPtr   virGetDomainByID(virConnectPtr conn,
+                                int id);
 
 #ifdef __cplusplus
 }
index 6692fb43473c2765a1737029e9687a0fdc330e5d..1b5ee111b9c94bebc07a9b00355383556a90832f 100644 (file)
@@ -407,7 +407,7 @@ int
 virConnectListDomains(virConnectPtr conn, int *ids, int maxids)
 {
     int ret = -1;
-    unsigned int i;
+    int i;
     long id;
     char **idlist = NULL;
 
@@ -421,8 +421,18 @@ virConnectListDomains(virConnectPtr conn, int *ids, int maxids)
         return (-1);
     }
 
+    /* Go though the driver registered entry points */
+    for (i = 0;i < conn->nb_drivers;i++) {
+       if ((conn->drivers[i] != NULL) &&
+           (conn->drivers[i]->listDomains != NULL)) {
+           ret = conn->drivers[i]->listDomains(conn, ids, maxids);
+           if (ret >= 0)
+               return(ret);
+       }
+    }
+
     /*
-     * try first though the Xen Daemon
+     * try then though the Xen Daemon
      */
     idlist = xenDaemonListDomains(conn);
     if (idlist != NULL) {
@@ -454,6 +464,7 @@ int
 virConnectNumOfDomains(virConnectPtr conn)
 {
     int ret = -1;
+    int i;
     char **idlist = NULL;
 
     if (!VIR_IS_CONNECT(conn)) {
@@ -461,9 +472,18 @@ virConnectNumOfDomains(virConnectPtr conn)
         return (-1);
     }
 
-    /* TODO: there must be a way to do that with an hypervisor call too ! */
+    /* Go though the driver registered entry points */
+    for (i = 0;i < conn->nb_drivers;i++) {
+       if ((conn->drivers[i] != NULL) &&
+           (conn->drivers[i]->numOfDomains != NULL)) {
+           ret = conn->drivers[i]->numOfDomains(conn);
+           if (ret >= 0)
+               return(ret);
+       }
+    }
+
     /* 
-     * try first with Xend interface
+     * try then with Xend interface
      */
     idlist = xenDaemonListDomains(conn);
     if (idlist != NULL) {
index 8a99cf6204ff9334042e8c77c14f116d4cd1d318..cfcd2ecb68579af503a60ae44961906ed5da255c 100644 (file)
@@ -48,8 +48,8 @@ static virDriver xenHypervisorDriver = {
     NULL, /* type */
     xenHypervisorGetVersion, /* version */
     NULL, /* nodeGetInfo */
-    NULL, /* listDomains */
-    NULL, /* numOfDomains */
+    xenHypervisorListDomains, /* listDomains */
+    xenHypervisorNumOfDomains, /* numOfDomains */
     NULL, /* domainCreateLinux */
     NULL, /* domainLookupByID */
     NULL, /* domainLookupByUUID */
@@ -131,7 +131,7 @@ xenHypervisorOpen(virConnectPtr conn, const char *name, int flags)
     }
     conn->handle = ret;
 
-    return (ret);
+    return(0);
 }
 
 /**
@@ -233,6 +233,144 @@ xenHypervisorGetVersion(virConnectPtr conn, unsigned long *hvVer)
     return(0);
 }
 
+/**
+ * xenHypervisorNumOfDomains:
+ * @conn: pointer to the connection block
+ *
+ * Provides the number of active domains.
+ *
+ * Returns the number of domain found or -1 in case of error
+ */
+int
+xenHypervisorNumOfDomains(virConnectPtr conn)
+{
+    dom0_op_t op;
+    dom0_getdomaininfo_t *dominfos;
+    int ret, nbids;
+    static int last_maxids = 2;
+    int maxids = last_maxids;
+
+    if ((conn == NULL) || (conn->handle < 0))
+        return (-1);
+
+retry:
+    dominfos = malloc(maxids * sizeof(dom0_getdomaininfo_t));
+    if (dominfos == NULL) {
+        virXenError(VIR_ERR_NO_MEMORY, "failed to allocate %d domain info",
+                   maxids);
+       return(-1);
+    }
+    
+    memset(dominfos, 0, sizeof(dom0_getdomaininfo_t) * maxids);
+
+    if (mlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
+        virXenError(VIR_ERR_XEN_CALL, " locking",
+                    sizeof(dom0_getdomaininfo_t) * maxids);
+       free(dominfos);
+        return (-1);
+    }
+
+    op.cmd = DOM0_GETDOMAININFOLIST;
+    op.u.getdomaininfolist.first_domain = (domid_t) 0;
+    op.u.getdomaininfolist.max_domains = maxids;
+    op.u.getdomaininfolist.buffer = dominfos;
+    op.u.getdomaininfolist.num_domains = maxids;
+
+    ret = xenHypervisorDoOp(conn->handle, &op);
+
+    if (munlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
+        virXenError(VIR_ERR_XEN_CALL, " release",
+                    sizeof(dom0_getdomaininfo_t) * maxids);
+        ret = -1;
+    }
+
+    free(dominfos);
+
+    if (ret < 0)
+        return (-1);
+
+    nbids = op.u.getdomaininfolist.num_domains;
+    if (nbids == maxids) {
+        last_maxids *= 2;
+        maxids *= 2;
+       goto retry;
+    }
+    if ((nbids < 0) || (nbids > maxids))
+        return(-1);
+    return(nbids);
+}
+
+/**
+ * xenHypervisorListDomains:
+ * @conn: pointer to the connection block
+ * @ids: array to collect the list of IDs of active domains
+ * @maxids: size of @ids
+ *
+ * Collect the list of active domains, and store their ID in @maxids
+ *
+ * Returns the number of domain found or -1 in case of error
+ */
+int
+xenHypervisorListDomains(virConnectPtr conn, int *ids, int maxids)
+{
+    dom0_op_t op;
+    dom0_getdomaininfo_t *dominfos;
+    int ret, nbids, i;
+
+    if ((conn == NULL) || (conn->handle < 0) ||
+        (ids == NULL) || (maxids < 1))
+        return (-1);
+
+    dominfos = malloc(maxids * sizeof(dom0_getdomaininfo_t));
+    if (dominfos == NULL) {
+        virXenError(VIR_ERR_NO_MEMORY, "failed to allocate %d domain info",
+                   maxids);
+       return(-1);
+    }
+    
+    memset(dominfos, 0, sizeof(dom0_getdomaininfo_t) * maxids);
+    memset(ids, 0, maxids * sizeof(int));
+
+    if (mlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
+        virXenError(VIR_ERR_XEN_CALL, " locking",
+                    sizeof(dom0_getdomaininfo_t) * maxids);
+       free(dominfos);
+        return (-1);
+    }
+
+    op.cmd = DOM0_GETDOMAININFOLIST;
+    op.u.getdomaininfolist.first_domain = (domid_t) 0;
+    op.u.getdomaininfolist.max_domains = maxids;
+    op.u.getdomaininfolist.buffer = dominfos;
+    op.u.getdomaininfolist.num_domains = maxids;
+
+    ret = xenHypervisorDoOp(conn->handle, &op);
+
+    if (munlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
+        virXenError(VIR_ERR_XEN_CALL, " release",
+                    sizeof(dom0_getdomaininfo_t) * maxids);
+        ret = -1;
+    }
+
+    if (ret < 0) {
+       free(dominfos);
+        return (-1);
+    }
+
+    nbids = op.u.getdomaininfolist.num_domains;
+    if ((nbids < 0) || (nbids > maxids)) {
+       free(dominfos);
+        return(-1);
+    }
+
+    for (i = 0;i < nbids;i++) {
+        ids[i] = dominfos[i].domain;
+    }
+
+    free(dominfos);
+    return (nbids);
+}
+
 /**
  * xenHypervisorGetDomainInfo:
  * @domain: pointer to the domain block
@@ -256,7 +394,7 @@ xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
     memset(info, 0, sizeof(virDomainInfo));
     memset(&dominfo, 0, sizeof(dom0_getdomaininfo_t));
 
-    if (mlock(info, sizeof(dom0_getdomaininfo_t)) < 0) {
+    if (mlock(&dominfo, sizeof(dom0_getdomaininfo_t)) < 0) {
         virXenError(VIR_ERR_XEN_CALL, " locking",
                     sizeof(dom0_getdomaininfo_t));
         return (-1);
@@ -271,7 +409,7 @@ xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
 
     ret = xenHypervisorDoOp(domain->conn->handle, &op);
 
-    if (munlock(info, sizeof(dom0_getdomaininfo_t)) < 0) {
+    if (munlock(&dominfo, sizeof(dom0_getdomaininfo_t)) < 0) {
         virXenError(VIR_ERR_XEN_CALL, " release",
                     sizeof(dom0_getdomaininfo_t));
         ret = -1;
index e47b8c5ab8d0200d847948cc032173f4a18f8129..9870f29542b45ba575ede33a2af9ac8029772fcf 100644 (file)
@@ -25,6 +25,10 @@ int  xenHypervisorOpen               (virConnectPtr conn,
 int    xenHypervisorClose              (virConnectPtr conn);
 int    xenHypervisorGetVersion         (virConnectPtr conn,
                                         unsigned long *hvVer);
+int    xenHypervisorNumOfDomains       (virConnectPtr conn);
+int    xenHypervisorListDomains        (virConnectPtr conn,
+                                        int *ids,
+                                        int maxids);
 int    xenHypervisorDestroyDomain      (virDomainPtr domain);
 int    xenHypervisorResumeDomain       (virDomainPtr domain);
 int    xenHypervisorPauseDomain        (virDomainPtr domain);