[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 3/8] [libxc] Domain Groups: libxc handlers for group data



libxc:

Augment libxc framework to shuttle group data and commands between xend
and the VMM.




diff -r ecb6cd61a9cf tools/libxc/Makefile
--- a/tools/libxc/Makefile      Tue Feb 20 12:27:03 2007 +0000
+++ b/tools/libxc/Makefile      Tue Feb 20 12:59:11 2007 -0500
@@ -7,6 +7,7 @@ CTRL_SRCS-y       :=
 CTRL_SRCS-y       :=
 CTRL_SRCS-y       += xc_core.c
 CTRL_SRCS-y       += xc_domain.c
+CTRL_SRCS-y       += xc_domain_group.c
 CTRL_SRCS-y       += xc_evtchn.c
 CTRL_SRCS-y       += xc_misc.c
 CTRL_SRCS-y       += xc_acm.c   
diff -r ecb6cd61a9cf tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   Tue Feb 20 12:27:03 2007 +0000
+++ b/tools/libxc/xc_domain.c   Tue Feb 20 12:59:11 2007 -0500
@@ -191,6 +191,7 @@ int xc_domain_getinfo(int xc_handle,
             info->crashed  = 1;
         }
 
+        info->grpid = domctl.u.getdomaininfo.group;
         info->ssidref  = domctl.u.getdomaininfo.ssidref;
         info->nr_pages = domctl.u.getdomaininfo.tot_pages;
         info->max_memkb = domctl.u.getdomaininfo.max_pages << (PAGE_SHIFT-10);
@@ -201,6 +202,9 @@ int xc_domain_getinfo(int xc_handle,
 
         memcpy(info->handle, domctl.u.getdomaininfo.handle,
                sizeof(xen_domain_handle_t));
+
+        memcpy(info->dg_handle, domctl.u.getdomaininfo.dg_handle,
+               sizeof(xen_domain_group_handle_t));
 
         next_domid = (uint16_t)domctl.domain + 1;
         info++;
diff -r ecb6cd61a9cf tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h  Tue Feb 20 12:27:03 2007 +0000
+++ b/tools/libxc/xc_private.h  Tue Feb 20 12:59:11 2007 -0500
@@ -23,10 +23,12 @@
 #ifdef VALGRIND
 #define DECLARE_HYPERCALL privcmd_hypercall_t hypercall = { 0 }
 #define DECLARE_DOMCTL struct xen_domctl domctl = { 0 }
+#define DECLARE_DOMGRPCTL struct xen_domgrpctl domgrpctl = { 0 }
 #define DECLARE_SYSCTL struct xen_sysctl sysctl = { 0 }
 #else
 #define DECLARE_HYPERCALL privcmd_hypercall_t hypercall
 #define DECLARE_DOMCTL struct xen_domctl domctl
+#define DECLARE_DOMGRPCTL struct xen_domgrpctl domgrpctl
 #define DECLARE_SYSCTL struct xen_sysctl sysctl
 #endif
 
@@ -118,6 +120,35 @@ static inline int do_domctl(int xc_handl
     return ret;
 }
 
+static inline int do_domgrpctl(int xc_handle, struct xen_domgrpctl *domgrpctl)
+{
+    int ret = -1;
+    DECLARE_HYPERCALL;
+
+    domgrpctl->interface_version = XEN_DOMGRPCTL_INTERFACE_VERSION;
+
+    hypercall.op     = __HYPERVISOR_domgrpctl;
+    hypercall.arg[0] = (unsigned long)domgrpctl;
+
+    if ( mlock(domgrpctl, sizeof(*domgrpctl)) != 0 )
+    {
+        PERROR("Could not lock memory for Xen hypercall");
+        goto out1;
+    }
+
+    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+    {
+        if ( errno == EACCES )
+            DPRINTF("domgrpctl operation failed -- need to"
+                    " rebuild the user-space tool set?\n");
+    }
+
+    safe_munlock(domgrpctl, sizeof(*domgrpctl));
+
+ out1:
+    return ret;
+}
+
 static inline int do_sysctl(int xc_handle, struct xen_sysctl *sysctl)
 {
     int ret = -1;
diff -r ecb6cd61a9cf tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Tue Feb 20 12:27:03 2007 +0000
+++ b/tools/libxc/xenctrl.h     Tue Feb 20 12:59:11 2007 -0500
@@ -18,6 +18,7 @@
 #include <stdint.h>
 #include <xen/xen.h>
 #include <xen/domctl.h>
+#include <xen/domgrpctl.h>
 #include <xen/sysctl.h>
 #include <xen/version.h>
 #include <xen/event_channel.h>
@@ -147,6 +148,7 @@ int xc_waitdomain(
 
 typedef struct xc_dominfo {
     uint32_t      domid;
+    uint32_t      grpid;
     uint32_t      ssidref;
     unsigned int  dying:1, crashed:1, shutdown:1,
                   paused:1, blocked:1, running:1,
@@ -159,7 +161,15 @@ typedef struct xc_dominfo {
     unsigned int  nr_online_vcpus;
     unsigned int  max_vcpu_id;
     xen_domain_handle_t handle;
+    xen_domain_group_handle_t dg_handle;
 } xc_dominfo_t;
+
+typedef struct{
+    dgid_t        dgid;
+    uint16_t      size;
+    domid_t       member_list[MAX_GROUP_SIZE];
+    xen_domain_group_handle_t handle;
+} xc_grpinfo_t;
 
 typedef xen_domctl_getdomaininfo_t xc_domaininfo_t;
 int xc_domain_create(int xc_handle,
@@ -292,6 +302,27 @@ int xc_domain_getinfo(int xc_handle,
                       unsigned int max_doms,
                       xc_dominfo_t *info);
 
+int xc_domain_group_getinfo(int xc_handle,
+                            uint32_t first_dgid,
+                           unsigned int max_grps,
+                           xc_grpinfo_t *info);
+
+int xc_domain_group_create(int xc_handle,
+                           xen_domain_group_handle_t handle,
+                           uint32_t *pdgid);
+
+int xc_domain_group_pause(int xc_handle,
+                          uint32_t dgid);
+
+int xc_domain_group_unpause(int xc_handle,
+                            uint32_t dgid);
+
+int xc_domain_group_destroy(int xc_handle,
+                            uint32_t dgid);
+
+int xc_domain_group_join(int xc_handle,
+                         uint32_t domid,
+                         uint32_t dgid);
 
 /**
  * This function will set the execution context for the specified vcpu.
diff -r ecb6cd61a9cf tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Tue Feb 20 12:27:03 2007 +0000
+++ b/tools/python/xen/lowlevel/xc/xc.c Tue Feb 20 12:59:11 2007 -0500
@@ -36,10 +36,6 @@ typedef struct {
     int xc_handle;
 } XcObject;
 
-
-static PyObject *dom_op(XcObject *self, PyObject *args,
-                        int (*fn)(int, uint32_t));
-
 static PyObject *pyxc_error_to_exception(void)
 {
     PyObject *pyerr;
@@ -59,6 +55,21 @@ static PyObject *pyxc_error_to_exception
     PyErr_SetObject(xc_error_obj, pyerr);
 
     return NULL;
+}
+
+static PyObject *xcop(XcObject *self, PyObject *args,
+                    int (*fn)(int, uint32_t))
+{
+    uint32_t id; /* used for both domid and grpid */
+
+    if (!PyArg_ParseTuple(args, "i", &id))
+        return NULL;
+
+    if (fn(self->xc_handle, id) != 0)
+        return pyxc_error_to_exception();
+
+    Py_INCREF(zero);
+    return zero;
 }
 
 static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
@@ -147,17 +158,17 @@ static PyObject *pyxc_domain_max_vcpus(X
 
 static PyObject *pyxc_domain_pause(XcObject *self, PyObject *args)
 {
-    return dom_op(self, args, xc_domain_pause);
+    return xcop(self, args, xc_domain_pause);
 }
 
 static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
 {
-    return dom_op(self, args, xc_domain_unpause);
+    return xcop(self, args, xc_domain_unpause);
 }
 
 static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
 {
-    return dom_op(self, args, xc_domain_destroy);
+    return xcop(self, args, xc_domain_destroy);
 }
 
 static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args)
@@ -176,7 +187,7 @@ static PyObject *pyxc_domain_shutdown(Xc
 
 static PyObject *pyxc_domain_resume(XcObject *self, PyObject *args)
 {
-    return dom_op(self, args, xc_domain_resume);
+    return xcop(self, args, xc_domain_resume);
 }
 
 static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
@@ -295,11 +306,15 @@ static PyObject *pyxc_domain_getinfo(XcO
     for ( i = 0 ; i < nr_doms; i++ )
     {
         PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
+        PyObject *pydg_handle = PyList_New(sizeof(xen_domain_group_handle_t));
         for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
             PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
+        for ( j = 0; j < sizeof(xen_domain_group_handle_t); j++ )
+            PyList_SetItem(pydg_handle, j, 
PyInt_FromLong(info[i].dg_handle[j]));
         info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
-                                  ",s:l,s:L,s:l,s:i,s:i}",
+                                  ",s:i,s:l,s:L,s:l,s:i,s:i}",
                                   "domid",       info[i].domid,
+                                  "dgid",      info[i].grpid,
                                   "online_vcpus", info[i].nr_online_vcpus,
                                   "max_vcpu_id", info[i].max_vcpu_id,
                                   "hvm",       info[i].hvm,
@@ -315,6 +330,7 @@ static PyObject *pyxc_domain_getinfo(XcO
                                   "ssidref",   info[i].ssidref,
                                   "shutdown_reason", info[i].shutdown_reason);
         PyDict_SetItemString(info_dict, "handle", pyhandle);
+        PyDict_SetItemString(info_dict, "dg_handle", pydg_handle);
         Py_DECREF(pyhandle);
         PyList_SetItem(list, i, info_dict);
     }
@@ -936,21 +952,6 @@ static PyObject *pyxc_domain_set_time_of
     return zero;
 }
 
-static PyObject *dom_op(XcObject *self, PyObject *args,
-                        int (*fn)(int, uint32_t))
-{
-    uint32_t dom;
-
-    if (!PyArg_ParseTuple(args, "i", &dom))
-        return NULL;
-
-    if (fn(self->xc_handle, dom) != 0)
-        return pyxc_error_to_exception();
-
-    Py_INCREF(zero);
-    return zero;
-}
-
 #ifdef __powerpc__
 static PyObject *pyxc_alloc_real_mode_area(XcObject *self,
                                            PyObject *args,
@@ -1013,6 +1014,148 @@ static PyObject *pyxc_prose_build(XcObje
 }
 #endif /* powerpc */
 
+#define EXTRACT_DOM_LIST(list_name, dict)                              \
+        dom_list = PyList_New(0);                                      \
+        for ( j = 0; j < info[i].size; j++ )                           \
+            PyList_Append(dom_list, PyInt_FromLong(info[i].list_name[j]));\
+        PyDict_SetItemString(dict, #list_name, dom_list);              \
+        Py_DECREF(dom_list);
+
+static PyObject *pyxc_domain_group_getinfo(XcObject *self,
+                                     PyObject *args,
+                                     PyObject *kwds)
+{
+    PyObject *list, *info_dict, *dom_list, *pyhandle;
+
+    uint32_t first_grp = 0;
+    /* max_grps is unrealistically large and causes a large heap allocation 
+       for the duration of this function that, in the vast majority of cases, 
+       will be very sparsely populated with information about real groups.  
+
+       Leaving this alone for now to keep an equal limit on max number of 
+       groups in both the VMM and the control stack. 
+
+       Could add a new case to the domain group control hypercall to return 
+       the current number of groups instead of assuming the worst case...
+    */
+    int max_grps = NULL_GROUP_ID+1, nr_grps, i, j;
+    xc_grpinfo_t *info;
+
+    static char *kwd_list[] = { "first_grp", "max_grps", NULL };
+
+    /* pull values from python args */
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
+                                      &first_grp, &max_grps) )
+        return NULL;
+
+    /* alloc space for the group info and ask Xen (via libxc) for the info */
+    if ( (info = malloc(max_grps * sizeof(xc_grpinfo_t))) == NULL )
+        return PyErr_NoMemory();
+    nr_grps = xc_domain_group_getinfo(self->xc_handle, first_grp, max_grps,
+                                      info);
+
+    if (nr_grps < 0) {
+        free(info);
+        return PyErr_SetFromErrno(xc_error_obj);
+    }
+
+    /* iterate over the returned groups and 
+       put the returned values into python objects */
+    list = PyList_New(nr_grps);
+    for ( i = 0 ; i < nr_grps; i++ ) {
+       /* extract group ID and size */
+        info_dict = Py_BuildValue(
+                       "{s:i,s:i}", 
+                       "dgid", info[i].dgid, 
+                       "size", info[i].size);
+
+       EXTRACT_DOM_LIST(member_list, info_dict);
+
+       /* extract the group's handle */        
+        pyhandle = PyList_New(sizeof(xen_domain_group_handle_t));
+        for ( j = 0; j < sizeof(xen_domain_group_handle_t); j++ )
+            PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
+        PyDict_SetItemString(info_dict, "dg_handle", pyhandle);
+        Py_DECREF(pyhandle);
+
+        PyList_SetItem(list, i, info_dict);
+    }
+
+    free(info);
+
+    return list;
+}
+
+static PyObject *pyxc_domain_group_create(XcObject *self,
+                                    PyObject *args,
+                                    PyObject *kwds)
+{
+    uint32_t dgid = 0;
+    int i;
+    PyObject *pyhandle = NULL;
+    xen_domain_group_handle_t handle = {
+        0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
+        0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
+
+    static char *kwd_list[] = { "handle", NULL };
+
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwd_list,
+                                      &pyhandle))
+        return NULL;
+
+    if ( pyhandle != NULL )
+    {
+        if ( !PyList_Check(pyhandle) ||
+             (PyList_Size(pyhandle) != sizeof(xen_domain_group_handle_t)) )
+            goto out_exception;
+
+        for ( i = 0; i < sizeof(xen_domain_group_handle_t); i++ )
+        {
+            PyObject *p = PyList_GetItem(pyhandle, i);
+            if ( !PyInt_Check(p) )
+                goto out_exception;
+            handle[i] = (uint8_t)PyInt_AsLong(p);
+        }
+    } else
+       goto out_exception;
+
+    if ( (xc_domain_group_create(self->xc_handle, handle, &dgid)) < 0 )
+        return PyErr_SetFromErrno(xc_error_obj);
+
+    return PyInt_FromLong(dgid);
+
+out_exception:
+    errno = EINVAL;
+    PyErr_SetFromErrno(xc_error_obj);
+    return NULL;
+}
+
+static PyObject *pyxc_domain_group_pause(XcObject *self, PyObject *args)
+{
+    return xcop(self, args, xc_domain_group_pause);
+}
+
+static PyObject *pyxc_domain_group_unpause(XcObject *self, PyObject *args)
+{
+    return xcop(self, args, xc_domain_group_unpause);
+}
+
+static PyObject *pyxc_domain_group_destroy(XcObject *self, PyObject *args)
+{
+    return xcop(self, args, xc_domain_group_destroy);
+}
+
+static PyObject *pyxc_domain_group_join(XcObject *self, PyObject *args)
+{
+    uint32_t dgid, domid;
+    if (!PyArg_ParseTuple(args, "ii", &domid, &dgid))
+        return NULL;
+    if (xc_domain_group_join(self->xc_handle, domid, dgid) != 0)
+        return PyErr_SetFromErrno(xc_error_obj);
+    Py_INCREF(zero);
+    return zero;
+}
+
 static PyMethodDef pyxc_methods[] = {
     { "handle",
       (PyCFunction)pyxc_handle,
@@ -1027,6 +1170,13 @@ static PyMethodDef pyxc_methods[] = {
       " dom    [int, 0]:        Domain identifier to use (allocated if 
zero).\n"
       "Returns: [int] new domain identifier; -1 on error.\n" },
 
+    { "domain_group_create", 
+      (PyCFunction)pyxc_domain_group_create, 
+      METH_VARARGS | METH_KEYWORDS, "\n"
+      "Create a new domain group.\n"
+      " grp    [int, 0]:        Domain group identifier to use (allocated if 
zero).\n"
+      "Returns: [int] new domain group identifier; -1 on error.\n" },
+
     { "domain_max_vcpus", 
       (PyCFunction)pyxc_domain_max_vcpus,
       METH_VARARGS, "\n"
@@ -1050,6 +1200,13 @@ static PyMethodDef pyxc_methods[] = {
       " dom [int]: Identifier of domain to be paused.\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
+    { "domain_group_pause", 
+      (PyCFunction)pyxc_domain_group_pause, 
+      METH_VARARGS, "\n"
+      "Temporarily pause execution of all domains in a group.\n"
+      " grp [int]: Identifier of domain group to be paused.\n\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+
     { "domain_unpause", 
       (PyCFunction)pyxc_domain_unpause, 
       METH_VARARGS, "\n"
@@ -1057,11 +1214,25 @@ static PyMethodDef pyxc_methods[] = {
       " dom [int]: Identifier of domain to be unpaused.\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
+    { "domain_group_unpause", 
+      (PyCFunction)pyxc_domain_group_unpause, 
+      METH_VARARGS, "\n"
+      "(Re)start execution of all domains in a group.\n"
+      " grp [int]: Identifier of domain group to be unpaused.\n\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+
     { "domain_destroy", 
       (PyCFunction)pyxc_domain_destroy, 
       METH_VARARGS, "\n"
       "Destroy a domain.\n"
       " dom [int]:    Identifier of domain to be destroyed.\n\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+
+    { "domain_group_destroy", 
+      (PyCFunction)pyxc_domain_group_destroy, 
+      METH_VARARGS, "\n"
+      "Destroy an empty domain group.\n"
+      " grp [int]:    Identifier of domain group to be destroyed.\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
     { "domain_resume", 
@@ -1129,6 +1300,20 @@ static PyMethodDef pyxc_methods[] = {
       " shutdown_reason [int]: Numeric code from guest OS, explaining "
       "reason why it shut itself down.\n" },
 
+    { "domain_group_getinfo", 
+      (PyCFunction)pyxc_domain_group_getinfo, 
+      METH_VARARGS | METH_KEYWORDS, "\n"
+      "Get information regarding a set of domain groups.\n"
+      " first_grp [int, 0]:    First domain to retrieve info about.\n"
+      " max_grps  [int, 1024]: Maximum number of domains to retrieve info"
+      " about.\n\n"
+      "Returns:  [list of dicts] if list length is less than 'max_grps'\n"
+      "          parameter then there was an error, or the end of the\n"
+      "          group-id space was reached.\n"
+      " grp               [int]: Id of group to which this info pertains\n"
+      " size              [int]: Number of domains in this group\n"
+      " member_list       [int array]: Unordered list of member Ids\n"},
+
     { "vcpu_getinfo", 
       (PyCFunction)pyxc_vcpu_getinfo, 
       METH_VARARGS | METH_KEYWORDS, "\n"
@@ -1337,6 +1522,14 @@ static PyMethodDef pyxc_methods[] = {
       METH_VARARGS, "\n"
       "Set a domain's time offset to Dom0's localtime\n"
       " dom        [int]: Domain whose time offset is being set.\n"
+      "Returns: [int] 0 on success; -1 on error.\n" },
+
+    { "domain_group_join",
+      (PyCFunction)pyxc_domain_group_join,
+      METH_VARARGS, "\n"
+      "Request that the given domain join the supplied group.\n"
+      " dom [int]: Identifier of domain joining group.\n"
+      " grp [int]: Identifier of group the given domain is joining.\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
 #ifdef __powerpc__
diff -r ecb6cd61a9cf tools/libxc/xc_domain_group.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_domain_group.c     Tue Feb 20 12:59:11 2007 -0500
@@ -0,0 +1,100 @@
+/******************************************************************************
+ * xc_domain_group.c
+ * 
+ * API for manipulating and obtaining information on domain groups.
+ * 
+ * Chris Bookholt (hap10@xxxxxxxxxxxxxx)
+ */
+
+#include "xc_private.h"
+#include <xen/memory.h>
+
+int xc_domain_group_create(int xc_handle, 
+                          xen_domain_group_handle_t handle,
+                          uint32_t *pdgid)
+{
+       int err;
+       DECLARE_DOMGRPCTL;
+       domgrpctl.cmd = XEN_DOMGRPCTL_creategrp;
+       memcpy(domgrpctl.u.create_grp.handle, handle,
+              sizeof(xen_domain_group_handle_t));
+       
+       err = do_domgrpctl(xc_handle, &domgrpctl);
+       if (err) 
+               return err;
+
+       *pdgid = (uint16_t)domgrpctl.u.get_grp_info.dgid;
+       return 0;
+}
+
+int xc_domain_group_pause(int xc_handle, uint32_t dgid)
+{
+       DECLARE_DOMGRPCTL;
+       domgrpctl.cmd = XEN_DOMGRPCTL_pausegrp;
+       domgrpctl.u.pause_grp.dgid = (dgid_t) dgid;
+       return do_domgrpctl(xc_handle, &domgrpctl);
+}
+
+int xc_domain_group_unpause(int xc_handle, uint32_t dgid)
+{
+       DECLARE_DOMGRPCTL;
+       domgrpctl.cmd = XEN_DOMGRPCTL_unpausegrp;
+       domgrpctl.u.unpause_grp.dgid = (dgid_t) dgid;
+       return do_domgrpctl(xc_handle, &domgrpctl);
+}
+
+int xc_domain_group_destroy(int xc_handle, uint32_t dgid)
+{
+       DECLARE_DOMGRPCTL;
+       domgrpctl.cmd = XEN_DOMGRPCTL_destroygrp;
+       domgrpctl.u.destroy_grp.dgid = (dgid_t) dgid;
+       return do_domgrpctl(xc_handle, &domgrpctl);
+}
+
+int xc_domain_group_join(int xc_handle, uint32_t domid, uint32_t dgid)
+{
+       DECLARE_DOMGRPCTL;
+       domgrpctl.cmd = XEN_DOMGRPCTL_joingrp;
+       domgrpctl.u.join_grp.domid = (domid_t) domid;
+       domgrpctl.u.join_grp.dgid = (dgid_t) dgid;
+       return do_domgrpctl(xc_handle, &domgrpctl);
+}
+
+#define TRANSFER_LIST_TO_INFO(list_name)                               \
+       memcpy(info->list_name, domgrpctl.u.get_grp_info.list_name,     \
+               MAX_GROUP_SIZE*sizeof(domid_t));
+
+int xc_domain_group_getinfo(int xc_handle, uint32_t first_dgid,
+                           unsigned int max_grps, xc_grpinfo_t * info)
+{
+       unsigned int nr_grps;
+       uint32_t next_dgid = first_dgid;
+       DECLARE_DOMGRPCTL;
+       int rc = 0;
+
+       memset(info, 0, max_grps * sizeof(xc_grpinfo_t));
+
+       for (nr_grps = 0; nr_grps < max_grps; nr_grps++) {
+               domgrpctl.cmd = XEN_DOMGRPCTL_getgrpinfo;
+               domgrpctl.u.get_grp_info.dgid = (dgid_t) next_dgid;
+
+               rc = do_domgrpctl(xc_handle, &domgrpctl);
+               if (rc < 0)
+                       break;
+
+               info->dgid = (uint16_t) domgrpctl.u.get_grp_info.dgid;
+               info->size = (uint16_t) domgrpctl.u.get_grp_info.size;
+
+               TRANSFER_LIST_TO_INFO(member_list);
+               memcpy(info->handle, domgrpctl.u.get_grp_info.handle,
+                      sizeof(xen_domain_group_handle_t));
+
+               next_dgid = (uint16_t) domgrpctl.u.get_grp_info.dgid + 1;
+               info++;
+       }
+
+       if (!nr_grps)
+               return rc;
+
+       return nr_grps;
+}




_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.