]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
* include/libvirt.h[.in] include/virterror.h src/driver.h
authorDaniel Veillard <veillard@redhat.com>
Wed, 29 Mar 2006 12:46:03 +0000 (12:46 +0000)
committerDaniel Veillard <veillard@redhat.com>
Wed, 29 Mar 2006 12:46:03 +0000 (12:46 +0000)
  src/internal.h src/libvirt_sym.version src/xen_internal.c
  src/xs_internal.c: added a new entry point to get node hardware
  informations virGetNodeInfo, and associated driver hook.
* src/xend_internal.c: implemented the node and version information
  hooks for the Xen Daemon
* python/libvir.c python/libvirt-python-api.xml python/generator.py:
  also added Python bindings for the new call
Daniel

18 files changed:
ChangeLog
include/libvirt.h
include/libvirt.h.in
include/libvirt/libvirt.h
include/libvirt/libvirt.h.in
include/libvirt/virterror.h
include/virterror.h
python/generator.py
python/libvir.c
python/libvirt-python-api.xml
src/driver.h
src/internal.h
src/libvirt.c
src/libvirt_sym.version
src/virterror.c
src/xen_internal.c
src/xend_internal.c
src/xs_internal.c

index fb6732039169324e863556d455d5fb43c2c13aa8..f657eda3df053b967da211cab7641f9b8717d0be 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Wed Mar 29 14:43:56 CEST 2006 Daniel Veillard <veillard@redhat.com>
+
+       * include/libvirt.h[.in] include/virterror.h src/driver.h
+         src/internal.h src/libvirt_sym.version src/xen_internal.c
+         src/xs_internal.c: added a new entry point to get node hardware
+         informations virGetNodeInfo, and associated driver hook.
+       * src/xend_internal.c: implemented the node and version information
+         hooks for the Xen Daemon
+       * python/libvir.c python/libvirt-python-api.xml python/generator.py:
+         also added Python bindings for the new call
+
 Tue Mar 28 16:40:08 CEST 2006 Daniel Veillard <veillard@redhat.com>
 
        * python/libvir.c: call the initialize entry point
index 507c857e83e858372c2e2f39e843769699c1dadf..364a5894cc9949b3c017c6e630310092bba85a13 100644 (file)
@@ -91,7 +91,8 @@ typedef enum {
 /**
  * virDomainInfoPtr:
  *
- * a virDomainInfo is a structure filled by virDomainGetInfo()
+ * a virDomainInfo is a structure filled by virDomainGetInfo() and extracting
+ * runtime informations for a given active Domain
  */
 
 typedef struct _virDomainInfo virDomainInfo;
@@ -101,19 +102,7 @@ struct _virDomainInfo {
     unsigned long maxMem;      /* the maximum memory in KBytes allowed */
     unsigned long memory;      /* the memory in KBytes used by the domain */
     unsigned short nrVirtCpu;  /* the number of virtual CPUs for the domain */
-
-    /*
-     * Informations below are only available to clients with a connection
-     * with full access to the hypervisor
-     */
     unsigned long long cpuTime;        /* the CPU time used in nanoseconds */
-    
-    /*
-     * TODO:
-     * - check what can be extracted publicly from xenstore
-     *   and what's private limited to the hypervisor call.
-     * - add padding to this structure for ABI long term protection
-     */
 };
 
 /**
@@ -158,6 +147,34 @@ typedef enum {
      VIR_DOMAIN_NONE = 0
 } virDomainCreateFlags;
 
+/**
+ * virNodeInfoPtr:
+ *
+ * a virNodeInfo is a structure filled by virNodeGetInfo() and providing
+ * the informations for the Node. 
+ */
+
+typedef struct _virNodeInfo virNodeInfo;
+
+struct _virNodeInfo {
+    char model[32];    /* string indicating the CPU model */
+    unsigned long memory;/* memory size in megabytes */
+    unsigned int cpus; /* the number of active CPUs */
+    unsigned int mhz;  /* expected CPU frequency */
+    unsigned int nodes;        /* the number of NUMA cell, 1 for uniform mem access */
+    unsigned int sockets;/* number of CPU socket per node */
+    unsigned int cores;        /* number of core per socket */
+    unsigned int threads;/* number of threads per core */
+};
+
+/**
+ * virNodeInfoPtr:
+ *
+ * a virNodeInfoPtr is a pointer to a virNodeInfo structure.
+ */
+
+typedef virNodeInfo *virNodeInfoPtr;
+
 /* library versionning */
 
 /**
@@ -184,6 +201,8 @@ int                 virConnectClose         (virConnectPtr conn);
 const char *           virConnectGetType       (virConnectPtr conn);
 int                    virConnectGetVersion    (virConnectPtr conn,
                                                 unsigned long *hvVer);
+int                    virNodeGetInfo          (virConnectPtr conn,
+                                                virNodeInfoPtr info);
 
 /*
  * Gather list of running domains
index 7c4794c29f7678262775e1987449b397da2f600a..b596712b2b781fa3c3bd0ff2bcf05802c02a8a22 100644 (file)
@@ -91,7 +91,8 @@ typedef enum {
 /**
  * virDomainInfoPtr:
  *
- * a virDomainInfo is a structure filled by virDomainGetInfo()
+ * a virDomainInfo is a structure filled by virDomainGetInfo() and extracting
+ * runtime informations for a given active Domain
  */
 
 typedef struct _virDomainInfo virDomainInfo;
@@ -101,19 +102,7 @@ struct _virDomainInfo {
     unsigned long maxMem;      /* the maximum memory in KBytes allowed */
     unsigned long memory;      /* the memory in KBytes used by the domain */
     unsigned short nrVirtCpu;  /* the number of virtual CPUs for the domain */
-
-    /*
-     * Informations below are only available to clients with a connection
-     * with full access to the hypervisor
-     */
     unsigned long long cpuTime;        /* the CPU time used in nanoseconds */
-    
-    /*
-     * TODO:
-     * - check what can be extracted publicly from xenstore
-     *   and what's private limited to the hypervisor call.
-     * - add padding to this structure for ABI long term protection
-     */
 };
 
 /**
@@ -158,6 +147,34 @@ typedef enum {
      VIR_DOMAIN_NONE = 0
 } virDomainCreateFlags;
 
+/**
+ * virNodeInfoPtr:
+ *
+ * a virNodeInfo is a structure filled by virNodeGetInfo() and providing
+ * the informations for the Node. 
+ */
+
+typedef struct _virNodeInfo virNodeInfo;
+
+struct _virNodeInfo {
+    char model[32];    /* string indicating the CPU model */
+    unsigned long memory;/* memory size in megabytes */
+    unsigned int cpus; /* the number of active CPUs */
+    unsigned int mhz;  /* expected CPU frequency */
+    unsigned int nodes;        /* the number of NUMA cell, 1 for uniform mem access */
+    unsigned int sockets;/* number of CPU socket per node */
+    unsigned int cores;        /* number of core per socket */
+    unsigned int threads;/* number of threads per core */
+};
+
+/**
+ * virNodeInfoPtr:
+ *
+ * a virNodeInfoPtr is a pointer to a virNodeInfo structure.
+ */
+
+typedef virNodeInfo *virNodeInfoPtr;
+
 /* library versionning */
 
 /**
@@ -184,6 +201,8 @@ int                 virConnectClose         (virConnectPtr conn);
 const char *           virConnectGetType       (virConnectPtr conn);
 int                    virConnectGetVersion    (virConnectPtr conn,
                                                 unsigned long *hvVer);
+int                    virNodeGetInfo          (virConnectPtr conn,
+                                                virNodeInfoPtr info);
 
 /*
  * Gather list of running domains
index 507c857e83e858372c2e2f39e843769699c1dadf..364a5894cc9949b3c017c6e630310092bba85a13 100644 (file)
@@ -91,7 +91,8 @@ typedef enum {
 /**
  * virDomainInfoPtr:
  *
- * a virDomainInfo is a structure filled by virDomainGetInfo()
+ * a virDomainInfo is a structure filled by virDomainGetInfo() and extracting
+ * runtime informations for a given active Domain
  */
 
 typedef struct _virDomainInfo virDomainInfo;
@@ -101,19 +102,7 @@ struct _virDomainInfo {
     unsigned long maxMem;      /* the maximum memory in KBytes allowed */
     unsigned long memory;      /* the memory in KBytes used by the domain */
     unsigned short nrVirtCpu;  /* the number of virtual CPUs for the domain */
-
-    /*
-     * Informations below are only available to clients with a connection
-     * with full access to the hypervisor
-     */
     unsigned long long cpuTime;        /* the CPU time used in nanoseconds */
-    
-    /*
-     * TODO:
-     * - check what can be extracted publicly from xenstore
-     *   and what's private limited to the hypervisor call.
-     * - add padding to this structure for ABI long term protection
-     */
 };
 
 /**
@@ -158,6 +147,34 @@ typedef enum {
      VIR_DOMAIN_NONE = 0
 } virDomainCreateFlags;
 
+/**
+ * virNodeInfoPtr:
+ *
+ * a virNodeInfo is a structure filled by virNodeGetInfo() and providing
+ * the informations for the Node. 
+ */
+
+typedef struct _virNodeInfo virNodeInfo;
+
+struct _virNodeInfo {
+    char model[32];    /* string indicating the CPU model */
+    unsigned long memory;/* memory size in megabytes */
+    unsigned int cpus; /* the number of active CPUs */
+    unsigned int mhz;  /* expected CPU frequency */
+    unsigned int nodes;        /* the number of NUMA cell, 1 for uniform mem access */
+    unsigned int sockets;/* number of CPU socket per node */
+    unsigned int cores;        /* number of core per socket */
+    unsigned int threads;/* number of threads per core */
+};
+
+/**
+ * virNodeInfoPtr:
+ *
+ * a virNodeInfoPtr is a pointer to a virNodeInfo structure.
+ */
+
+typedef virNodeInfo *virNodeInfoPtr;
+
 /* library versionning */
 
 /**
@@ -184,6 +201,8 @@ int                 virConnectClose         (virConnectPtr conn);
 const char *           virConnectGetType       (virConnectPtr conn);
 int                    virConnectGetVersion    (virConnectPtr conn,
                                                 unsigned long *hvVer);
+int                    virNodeGetInfo          (virConnectPtr conn,
+                                                virNodeInfoPtr info);
 
 /*
  * Gather list of running domains
index 7c4794c29f7678262775e1987449b397da2f600a..b596712b2b781fa3c3bd0ff2bcf05802c02a8a22 100644 (file)
@@ -91,7 +91,8 @@ typedef enum {
 /**
  * virDomainInfoPtr:
  *
- * a virDomainInfo is a structure filled by virDomainGetInfo()
+ * a virDomainInfo is a structure filled by virDomainGetInfo() and extracting
+ * runtime informations for a given active Domain
  */
 
 typedef struct _virDomainInfo virDomainInfo;
@@ -101,19 +102,7 @@ struct _virDomainInfo {
     unsigned long maxMem;      /* the maximum memory in KBytes allowed */
     unsigned long memory;      /* the memory in KBytes used by the domain */
     unsigned short nrVirtCpu;  /* the number of virtual CPUs for the domain */
-
-    /*
-     * Informations below are only available to clients with a connection
-     * with full access to the hypervisor
-     */
     unsigned long long cpuTime;        /* the CPU time used in nanoseconds */
-    
-    /*
-     * TODO:
-     * - check what can be extracted publicly from xenstore
-     *   and what's private limited to the hypervisor call.
-     * - add padding to this structure for ABI long term protection
-     */
 };
 
 /**
@@ -158,6 +147,34 @@ typedef enum {
      VIR_DOMAIN_NONE = 0
 } virDomainCreateFlags;
 
+/**
+ * virNodeInfoPtr:
+ *
+ * a virNodeInfo is a structure filled by virNodeGetInfo() and providing
+ * the informations for the Node. 
+ */
+
+typedef struct _virNodeInfo virNodeInfo;
+
+struct _virNodeInfo {
+    char model[32];    /* string indicating the CPU model */
+    unsigned long memory;/* memory size in megabytes */
+    unsigned int cpus; /* the number of active CPUs */
+    unsigned int mhz;  /* expected CPU frequency */
+    unsigned int nodes;        /* the number of NUMA cell, 1 for uniform mem access */
+    unsigned int sockets;/* number of CPU socket per node */
+    unsigned int cores;        /* number of core per socket */
+    unsigned int threads;/* number of threads per core */
+};
+
+/**
+ * virNodeInfoPtr:
+ *
+ * a virNodeInfoPtr is a pointer to a virNodeInfo structure.
+ */
+
+typedef virNodeInfo *virNodeInfoPtr;
+
 /* library versionning */
 
 /**
@@ -184,6 +201,8 @@ int                 virConnectClose         (virConnectPtr conn);
 const char *           virConnectGetType       (virConnectPtr conn);
 int                    virConnectGetVersion    (virConnectPtr conn,
                                                 unsigned long *hvVer);
+int                    virNodeGetInfo          (virConnectPtr conn,
+                                                virNodeInfoPtr info);
 
 /*
  * Gather list of running domains
index 69f8b10b2f6e34df97678c18603e45686d0b6d4c..1fda6c9b3d490125c65482d04b02bcd6a32018ed 100644 (file)
@@ -100,7 +100,8 @@ typedef enum {
     VIR_ERR_NO_OS, /* missing domain OS information */
     VIR_ERR_NO_DEVICE, /* missing domain devices information */
     VIR_ERR_NO_XENSTORE,/* could not open Xen Store control */
-    VIR_ERR_DRIVER_FULL /* too many drivers registered */
+    VIR_ERR_DRIVER_FULL, /* too many drivers registered */
+    VIR_ERR_CALL_FAILED /* not supported by the drivers */
 } virErrorNumber;
 
 /**
index 69f8b10b2f6e34df97678c18603e45686d0b6d4c..1fda6c9b3d490125c65482d04b02bcd6a32018ed 100644 (file)
@@ -100,7 +100,8 @@ typedef enum {
     VIR_ERR_NO_OS, /* missing domain OS information */
     VIR_ERR_NO_DEVICE, /* missing domain devices information */
     VIR_ERR_NO_XENSTORE,/* could not open Xen Store control */
-    VIR_ERR_DRIVER_FULL /* too many drivers registered */
+    VIR_ERR_DRIVER_FULL, /* too many drivers registered */
+    VIR_ERR_CALL_FAILED /* not supported by the drivers */
 } virErrorNumber;
 
 /**
index af44cae413caf66890c5ac5f66efaba1789b04f9..497f3b48a0c91a7bf567a24b42b57c0b9018d8a4 100755 (executable)
@@ -261,6 +261,7 @@ foreign_encoding_args = (
 skip_impl = (
     'virConnectListDomainsID',
     'virDomainGetInfo',
+    'virNodeGetInfo',
     'virDomainGetUUID',
     'virDomainLookupByUUID',
 )
@@ -562,6 +563,9 @@ def nameFixup(name, classe, type, file):
     elif name[0:9] == "virDomain":
         func = name[9:]
         func = string.lower(func[0:1]) + func[1:]
+    elif name[0:7] == "virNode":
+        func = name[7:]
+        func = string.lower(func[0:1]) + func[1:]
     elif name[0:10] == "virConnect":
         func = name[10:]
         func = string.lower(func[0:1]) + func[1:]
index 1d97037704621cfc419b44aed207737a5c2d0b47..ede394956355adaae51a708c1aac6fb83708b957 100644 (file)
@@ -197,6 +197,35 @@ libvirt_virDomainGetInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
     return(py_retval);
 }
 
+static PyObject *
+libvirt_virNodeGetInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    int c_retval;
+    virConnectPtr conn;
+    PyObject *pyobj_conn;
+    virNodeInfo info;
+
+    if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetInfo", &pyobj_conn))
+        return(NULL);
+    conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
+
+    c_retval = virNodeGetInfo(conn, &info);
+    if (c_retval < 0) {
+        Py_INCREF(Py_None);
+       return(Py_None);
+    }
+    py_retval = PyList_New(8);
+    PyList_SetItem(py_retval, 0, libvirt_charPtrWrap(&info.model[0]));
+    PyList_SetItem(py_retval, 1, libvirt_longWrap((long) info.memory));
+    PyList_SetItem(py_retval, 2, libvirt_intWrap((int) info.cpus));
+    PyList_SetItem(py_retval, 3, libvirt_intWrap((int) info.mhz));
+    PyList_SetItem(py_retval, 4, libvirt_intWrap((int) info.nodes));
+    PyList_SetItem(py_retval, 5, libvirt_intWrap((int) info.sockets));
+    PyList_SetItem(py_retval, 6, libvirt_intWrap((int) info.cores));
+    PyList_SetItem(py_retval, 7, libvirt_intWrap((int) info.threads));
+    return(py_retval);
+}
+
 PyObject *
 libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
     PyObject *py_retval;
@@ -255,6 +284,7 @@ static PyMethodDef libvirtMethods[] = {
     {(char *) "virConnectClose", libvirt_virConnectClose, METH_VARARGS, NULL},
     {(char *) "virConnectListDomainsID", libvirt_virConnectListDomainsID, METH_VARARGS, NULL},
     {(char *) "virDomainGetInfo", libvirt_virDomainGetInfo, METH_VARARGS, NULL},
+    {(char *) "virNodeGetInfo", libvirt_virNodeGetInfo, METH_VARARGS, NULL},
     {(char *) "virDomainGetUUID", libvirt_virDomainGetUUID, METH_VARARGS, NULL},
     {(char *) "virDomainLookupByUUID", libvirt_virDomainLookupByUUID, METH_VARARGS, NULL},
     {(char *) "virRegisterErrorHandler", libvirt_virRegisterErrorHandler, METH_VARARGS, NULL},
index 3b75525665bb9741402edaabf463502ff027ce51..302ba023b73099ff27b52f1fbc063fd794491652 100644 (file)
       <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
       <arg name='uuid' type='const unsigned char *' info='the UUID string for the domain, must be 16 bytes'/>
     </function>
-    <function name='virDomainGetInfo' file='libvir' module='python'>
-      <info>Extract information about a domain. Note that if the connection used to get the domain is limited only a partial set of the informations can be extracted.</info>
+    <function name='virDomainGetInfo' file='python'>
+      <info>Extract informations about a domain. Note that if the connection used to get the domain is limited only a partial set of the informations can be extracted.</info>
       <return type='int *' info='the list of informations or None in case of error'/>
       <arg name='domain' type='virDomainPtr' info='a domain object'/>
     </function>
-    <function name='virDomainGetUUID' file='libvir' module='python'>
+    <function name='virNodeGetInfo' file='python'>
+      <info>Extract hardware informations about the Node.</info>
+      <return type='int *' info='the list of informations or None in case of error'/>
+      <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
+    </function>
+    <function name='virDomainGetUUID' file='python'>
       <info>Extract the UUID unique Identifier of a domain.</info>
       <return type='char *' info='the 16 bytes string or None in case of error'/>
       <arg name='domain' type='virDomainPtr' info='a domain object'/>
index 377af8af1b8037f567a2501cf11567f3be72f830..fd5af748af6ccb63f06011b2575ef3d5e6725bb3 100644 (file)
@@ -31,6 +31,9 @@ typedef const char *
 typedef int
        (*virDrvGetVersion)             (virConnectPtr conn,
                                         unsigned long *hvVer);
+typedef int
+       (*virDrvNodeGetInfo)            (virConnectPtr conn,
+                                        virNodeInfoPtr info);
 typedef int
        (*virDrvListDomains)            (virConnectPtr conn,
                                         int *ids,
@@ -100,6 +103,7 @@ struct _virDriver {
        virDrvClose                     close;
        virDrvGetType                   type;
        virDrvGetVersion                version;
+       virDrvNodeGetInfo               nodeGetInfo;
        virDrvListDomains               listDomains;
        virDrvNumOfDomains              numOfDomains;
        virDrvDomainCreateLinux         domainCreateLinux;
index e5436d227f275c9b8ee4f55f1236d26ef4720a0e..6cacaa20a16fbde95431cbaf51cce4c2531a79e4 100644 (file)
@@ -78,6 +78,8 @@ extern "C" {
 #define VIR_IS_DOMAIN(obj)             ((obj) && (obj)->magic==VIR_DOMAIN_MAGIC)
 #define VIR_IS_CONNECTED_DOMAIN(obj)   (VIR_IS_DOMAIN(obj) && VIR_IS_CONNECT((obj)->conn))
 
+#define MAX_DRIVERS 5
+
 /*
  * Flags for Xen connections
  */
@@ -90,6 +92,12 @@ extern "C" {
  */
 struct _virConnect {
     unsigned int magic;     /* specific value to check */
+
+    /* the list of available drivers for that connection */
+    virDriverPtr      drivers[MAX_DRIVERS];
+    int               nb_drivers;
+
+    /* extra data needed by drivers */
     int handle;             /* internal handle used for hypercall */
     struct xs_handle *xshandle;     /* handle to talk to the xenstore */
 
index d5c268bb2e6cbc045fa3a973976d6d4efbb59d89..99ba6e505444fad0e614c8312c2c699307128afb 100644 (file)
@@ -37,7 +37,6 @@
  * - memory wrappers for malloc/free ?
  */
 
-#define MAX_DRIVERS 5
 static virDriverPtr virDriverTab[MAX_DRIVERS];
 static int initialized = 0;
 
@@ -216,17 +215,12 @@ virGetVersion(unsigned long *libVer, const char *type,
 virConnectPtr
 virConnectOpen(const char *name)
 {
+    int i, res;
     virConnectPtr ret = NULL;
 
     if (!initialized)
         virInitialize();
 
-    /* we can only talk to the local Xen supervisor ATM */
-    if (name != NULL) {
-        virLibConnError(NULL, VIR_ERR_NO_SUPPORT, name);
-        return (NULL);
-    }
-
     ret = (virConnectPtr) malloc(sizeof(virConnect));
     if (ret == NULL) {
         virLibConnError(NULL, VIR_ERR_NO_MEMORY, "Allocating connection");
@@ -234,16 +228,28 @@ virConnectOpen(const char *name)
     }
     memset(ret, 0, sizeof(virConnect));
     ret->magic = VIR_CONNECT_MAGIC;
+    ret->nb_drivers = 0;
 
-    /*
-     * open connections to the hypervisor, store and daemon
-     */
-    if (xenHypervisorOpen(ret, name, 0) < 0)
-        goto failed;
-    if (xenStoreOpen(ret, name, 0) < 0)
-        goto failed;
-    if (xenDaemonOpen(ret, name, 0) < 0)
-        goto failed;
+    for (i = 0;i < MAX_DRIVERS;i++) {
+        if ((virDriverTab[i] != NULL) && (virDriverTab[i]->open != NULL)) {
+           res = virDriverTab[i]->open(ret, name, 0);
+           /*
+            * For a default connect to Xen make sure we manage to contact
+            * all related drivers.
+            */
+           if ((res < 0) && (name == NULL) &&
+               (!strcmp(virDriverTab[i]->name, "Xen")))
+               goto failed;
+           if (res == 0)
+               ret->drivers[ret->nb_drivers++] = virDriverTab[i];
+       }
+    }
+
+    if (ret->nb_drivers == 0) {
+       /* we failed to find an adequate driver */
+       virLibConnError(NULL, VIR_ERR_NO_SUPPORT, name);
+       goto failed;
+    }
 
     ret->domains = virHashCreate(20);
     if (ret->domains == NULL)
@@ -254,9 +260,10 @@ virConnectOpen(const char *name)
 
 failed:
     if (ret != NULL) {
-       xenHypervisorClose(ret);
-       xenStoreClose(ret);
-       xenDaemonClose(ret);
+       for (i = 0;i < ret->nb_drivers;i++) {
+           if ((ret->drivers[i] != NULL) && (ret->drivers[i]->close != NULL))
+               ret->drivers[i]->close(ret);
+       }
         free(ret);
     }
     return (NULL);
@@ -275,19 +282,12 @@ failed:
 virConnectPtr
 virConnectOpenReadOnly(const char *name)
 {
-    int method = 0;
-    int res;
+    int i, res;
     virConnectPtr ret = NULL;
 
     if (!initialized)
         virInitialize();
 
-    /* we can only talk to the local Xen supervisor ATM */
-    if (name != NULL) {
-        virLibConnError(NULL, VIR_ERR_NO_SUPPORT, name);
-        return (NULL);
-    }
-
     ret = (virConnectPtr) malloc(sizeof(virConnect));
     if (ret == NULL) {
         virLibConnError(NULL, VIR_ERR_NO_MEMORY, "Allocating connection");
@@ -295,22 +295,24 @@ virConnectOpenReadOnly(const char *name)
     }
     memset(ret, 0, sizeof(virConnect));
     ret->magic = VIR_CONNECT_MAGIC;
+    ret->nb_drivers = 0;
 
-    res = xenHypervisorOpen(ret, name, VIR_DRV_OPEN_QUIET | VIR_DRV_OPEN_RO);
-    if (res >= 0)
-        method++;
-
-    res = xenStoreOpen(ret, name, VIR_DRV_OPEN_QUIET | VIR_DRV_OPEN_RO);
-    if (res >= 0)
-        method++;
-
-    if (xenDaemonOpen(ret, name, VIR_DRV_OPEN_QUIET | VIR_DRV_OPEN_RO) == 0)
-        method++;
-
-    if (method == 0) {
-        virLibConnError(NULL, VIR_ERR_NO_CONNECT,
-                        "could not connect to Xen Daemon nor Xen Store");
-        goto failed;
+    for (i = 0;i < MAX_DRIVERS;i++) {
+        if ((virDriverTab[i] != NULL) && (virDriverTab[i]->open != NULL)) {
+           res = virDriverTab[i]->open(ret, name,
+                                       VIR_DRV_OPEN_QUIET | VIR_DRV_OPEN_RO);
+           if (res == 0)
+               ret->drivers[ret->nb_drivers++] = virDriverTab[i];
+       }
+    }
+    if (ret->nb_drivers == 0) {
+       if (name == NULL)
+           virLibConnError(NULL, VIR_ERR_NO_CONNECT,
+                           "could not connect to Xen Daemon nor Xen Store");
+       else
+           /* we failed to find an adequate driver */
+           virLibConnError(NULL, VIR_ERR_NO_SUPPORT, name);
+       goto failed;
     }
 
     ret->domains = virHashCreate(20);
@@ -322,9 +324,10 @@ virConnectOpenReadOnly(const char *name)
 
 failed:
     if (ret != NULL) {
-       xenHypervisorClose(ret);
-       xenStoreClose(ret);
-       xenDaemonClose(ret);
+       for (i = 0;i < ret->nb_drivers;i++) {
+           if ((ret->drivers[i] != NULL) && (ret->drivers[i]->close != NULL))
+               ret->drivers[i]->close(ret);
+       }
         free(ret);
     }
     return (NULL);
@@ -358,14 +361,16 @@ virDomainFreeName(virDomainPtr domain, const char *name ATTRIBUTE_UNUSED)
 int
 virConnectClose(virConnectPtr conn)
 {
-    xenDaemonClose(conn);
+    int i;
+
     if (!VIR_IS_CONNECT(conn))
         return (-1);
     virHashFree(conn->domains, (virHashDeallocator) virDomainFreeName);
     conn->domains = NULL;
-    xenDaemonClose(conn);
-    xenStoreClose(conn);
-    xenHypervisorClose(conn);
+    for (i = 0;i < conn->nb_drivers;i++) {
+       if ((conn->drivers[i] != NULL) && (conn->drivers[i]->close != NULL))
+           conn->drivers[i]->close(conn);
+    }
     conn->magic = -1;
     free(conn);
     return (0);
@@ -383,8 +388,7 @@ const char *
 virConnectGetType(virConnectPtr conn)
 {
     if (!VIR_IS_CONNECT(conn)) {
-        virLibConnError(conn, VIR_ERR_INVALID_CONN,
-                        "in virConnectGetType");
+        virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
     }
     return ("Xen");
@@ -1317,3 +1321,41 @@ virDomainGetXMLDesc(virDomainPtr domain, int flags)
 
     return (xenDaemonDomainDumpXML(domain));
 }
+
+/**
+ * virNodeGetInfo:
+ * @conn: pointer to the hypervisor connection
+ * @info: pointer to a virNodeInfo structure allocated by the user
+ * 
+ * Extract hardware information about the node.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) {
+    int i;
+    int ret = -1;
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+    if (info == NULL) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+
+    for (i = 0;i < conn->nb_drivers;i++) {
+       if ((conn->drivers[i] != NULL) &&
+           (conn->drivers[i]->nodeGetInfo != NULL)) {
+           ret = conn->drivers[i]->nodeGetInfo(conn, info);
+           if (ret == 0)
+               break;
+       }
+    }
+    if (ret != 0) {
+        virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+        return (-1);
+    }
+    return(0);
+}
index 0a298f82402f40c05cfa59aa7a84ded0509d694d..618f42877d6d9960c8d5d1101e7b1834697c28d1 100644 (file)
@@ -39,5 +39,6 @@
        virConnCopyLastError;
        virConnResetLastError;
        virDefaultErrorFunc;
+       virNodeGetInfo;
     local: *;
 };
index ba7cd75d8e1991e7310e6c549dde381e0d3b9982..e34f5591c741307297ef2a0d545a4cdf83debf74 100644 (file)
@@ -497,6 +497,12 @@ __virErrorMsg(virErrorNumber error, const char *info)
             else
                 errmsg = "too many drivers registered in %s";
             break;
+        case VIR_ERR_CALL_FAILED:
+            if (info == NULL)
+                errmsg = "library call failed, possibly not supported";
+            else
+                errmsg = "library call %s failed, possibly not supported";
+            break;
     }
     return (errmsg);
 }
index abda84f2e757b221c65b17c76cceab2f141240c0..ccfc7cfdf80435ebc07506041fc8b3fccd402bcf 100644 (file)
@@ -47,6 +47,7 @@ static virDriver xenHypervisorDriver = {
     xenHypervisorClose, /* close */
     NULL, /* type */
     xenHypervisorGetVersion, /* version */
+    NULL, /* nodeGetInfo */
     NULL, /* listDomains */
     NULL, /* numOfDomains */
     NULL, /* domainCreateLinux */
index aa2ff6b6bfcf20f3780022f62a80ba278279c794..329726d59f949bac69a3ee8d880f3107546c34fc 100644 (file)
 #include "xml.h"
 #include "xend_internal.h"
 
+static int xenDaemonNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
+static int xenDaemonGetVersion(virConnectPtr conn, unsigned long *hvVer);
+
 static virDriver xenDaemonDriver = {
-    "Xen",
+    "XenDaemon",
     NULL, /* init */
     xenDaemonOpen, /* open */
     xenDaemonClose, /* close */
     NULL, /* type */
-    NULL, /* version */
+    xenDaemonGetVersion, /* version */
+    xenDaemonNodeGetInfo, /* nodeGetInfo */
     NULL, /* listDomains */
     NULL, /* numOfDomains */
     NULL, /* domainCreateLinux */
@@ -1518,6 +1522,43 @@ sexpr_to_xend_domain_info(struct sexpr *root, virDomainInfoPtr info)
     return (0);
 }
 
+/**
+ * sexpr_to_xend_node_info:
+ * @root: an S-Expression describing a domain
+ * @info: a info data structure to fill up
+ *
+ * Internal routine filling up the info structure with the values from
+ * the node root provided.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+static int
+sexpr_to_xend_node_info(struct sexpr *root, virNodeInfoPtr info)
+{
+    const char *machine;
+
+
+    if ((root == NULL) || (info == NULL))
+        return (-1);
+
+    machine = sexpr_node(root, "node/machine");
+    if (machine == NULL)
+        info->model[0] = 0;
+    else {
+        snprintf(&info->model[0], sizeof(info->model) - 1, "%s", machine);
+       info->model[sizeof(info->model) - 1] = 0;
+    }
+    info->memory = (unsigned long) sexpr_u64(root, "node/total_memory") << 10;
+
+    info->cpus = sexpr_int(root, "node/nr_cpus");
+    info->mhz = sexpr_int(root, "node/cpu_mhz");
+    info->nodes = sexpr_int(root, "node/nr_nodes");
+    info->sockets = sexpr_int(root, "node/sockets_per_node");
+    info->cores = sexpr_int(root, "node/cores_per_socket");
+    info->threads = sexpr_int(root, "node/threads_per_core");
+    return (0);
+}
+
 /**
  * sexpr_to_domain:
  * @conn: an existing virtual connection block
@@ -1918,3 +1959,84 @@ error:
     return(ret);
 }
 
+/**
+ * xenDaemonNodeGetInfo:
+ * @conn: pointer to the Xen Daemon block
+ * @info: pointer to a virNodeInfo structure allocated by the user
+ * 
+ * Extract hardware information about the node.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+static int
+xenDaemonNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) {
+    int ret = -1;
+    struct sexpr *root;
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virXendError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+    if (info == NULL) {
+        virXendError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+
+    root = sexpr_get(conn, "/xend/node/");
+    if (root == NULL)
+        return (-1);
+
+    ret = sexpr_to_xend_node_info(root, info);
+    sexpr_free(root);
+    return (ret);
+}
+
+/**
+ * xenDaemonGetVersion:
+ * @conn: pointer to the Xen Daemon block
+ * @hvVer: return value for the version of the running hypervisor (OUT)
+ *
+ * Get the version level of the Hypervisor running.
+ *
+ * Returns -1 in case of error, 0 otherwise. if the version can't be
+ *    extracted by lack of capacities returns 0 and @hvVer is 0, otherwise
+ *    @hvVer value is major * 1,000,000 + minor * 1,000 + release
+ */
+static int
+xenDaemonGetVersion(virConnectPtr conn, unsigned long *hvVer)
+{
+    static unsigned long version = 0;
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virXendError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+    if (hvVer == NULL) {
+        virXendError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+    if (version == 0) {
+       struct sexpr *root;
+       const char *extra;
+       int major, minor, release = 0;
+        
+       root = sexpr_get(conn, "/xend/node/");
+       if (root == NULL)
+           return(-1);
+
+       major = sexpr_int(root, "node/xen_major");
+       minor = sexpr_int(root, "node/xen_minor");
+       extra = sexpr_node(root, "node/xen_extra");
+       if (extra != NULL) {
+           while (*extra != 0) {
+               if ((*extra >= '0') && (*extra <= '9'))
+                   release = release * 10 + (*extra - '0');
+               extra++;
+           }
+       }
+       sexpr_free(root);
+       version = major * 1000000 + minor * 1000 + release;
+    }
+    *hvVer = version;
+    return(0);
+}
index 4bcba392bcc85a5c6c1a448d2ccb43ae0e07ca14..4a24aa9954990272405f11388247ee8e48d488f1 100644 (file)
@@ -37,6 +37,7 @@ static virDriver xenStoreDriver = {
     xenStoreClose, /* close */
     NULL, /* type */
     NULL, /* version */
+    NULL, /* nodeGetInfo */
     xenStoreListDomains, /* listDomains */
     NULL, /* numOfDomains */
     NULL, /* domainCreateLinux */