From: Daniel Veillard Date: Wed, 29 Mar 2006 12:46:03 +0000 (+0000) Subject: * include/libvirt.h[.in] include/virterror.h src/driver.h X-Git-Tag: LIBVIRT_0_1_0~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=212eaea3238774fd7e22a270d6241bd141e07f66;p=thirdparty%2Flibvirt.git * 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 Daniel --- diff --git a/ChangeLog b/ChangeLog index fb67320391..f657eda3df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Wed Mar 29 14:43:56 CEST 2006 Daniel Veillard + + * 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 * python/libvir.c: call the initialize entry point diff --git a/include/libvirt.h b/include/libvirt.h index 507c857e83..364a5894cc 100644 --- a/include/libvirt.h +++ b/include/libvirt.h @@ -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 diff --git a/include/libvirt.h.in b/include/libvirt.h.in index 7c4794c29f..b596712b2b 100644 --- a/include/libvirt.h.in +++ b/include/libvirt.h.in @@ -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 diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index 507c857e83..364a5894cc 100644 --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -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 diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7c4794c29f..b596712b2b 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -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 diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index 69f8b10b2f..1fda6c9b3d 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -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; /** diff --git a/include/virterror.h b/include/virterror.h index 69f8b10b2f..1fda6c9b3d 100644 --- a/include/virterror.h +++ b/include/virterror.h @@ -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; /** diff --git a/python/generator.py b/python/generator.py index af44cae413..497f3b48a0 100755 --- a/python/generator.py +++ b/python/generator.py @@ -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:] diff --git a/python/libvir.c b/python/libvir.c index 1d97037704..ede3949563 100644 --- a/python/libvir.c +++ b/python/libvir.c @@ -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}, diff --git a/python/libvirt-python-api.xml b/python/libvirt-python-api.xml index 3b75525665..302ba023b7 100644 --- a/python/libvirt-python-api.xml +++ b/python/libvirt-python-api.xml @@ -12,12 +12,17 @@ - - 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. + + 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. - + + Extract hardware informations about the Node. + + + + Extract the UUID unique Identifier of a domain. diff --git a/src/driver.h b/src/driver.h index 377af8af1b..fd5af748af 100644 --- a/src/driver.h +++ b/src/driver.h @@ -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; diff --git a/src/internal.h b/src/internal.h index e5436d227f..6cacaa20a1 100644 --- a/src/internal.h +++ b/src/internal.h @@ -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 */ diff --git a/src/libvirt.c b/src/libvirt.c index d5c268bb2e..99ba6e5054 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -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); +} diff --git a/src/libvirt_sym.version b/src/libvirt_sym.version index 0a298f8240..618f42877d 100644 --- a/src/libvirt_sym.version +++ b/src/libvirt_sym.version @@ -39,5 +39,6 @@ virConnCopyLastError; virConnResetLastError; virDefaultErrorFunc; + virNodeGetInfo; local: *; }; diff --git a/src/virterror.c b/src/virterror.c index ba7cd75d8e..e34f5591c7 100644 --- a/src/virterror.c +++ b/src/virterror.c @@ -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); } diff --git a/src/xen_internal.c b/src/xen_internal.c index abda84f2e7..ccfc7cfdf8 100644 --- a/src/xen_internal.c +++ b/src/xen_internal.c @@ -47,6 +47,7 @@ static virDriver xenHypervisorDriver = { xenHypervisorClose, /* close */ NULL, /* type */ xenHypervisorGetVersion, /* version */ + NULL, /* nodeGetInfo */ NULL, /* listDomains */ NULL, /* numOfDomains */ NULL, /* domainCreateLinux */ diff --git a/src/xend_internal.c b/src/xend_internal.c index aa2ff6b6bf..329726d59f 100644 --- a/src/xend_internal.c +++ b/src/xend_internal.c @@ -35,13 +35,17 @@ #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); +} diff --git a/src/xs_internal.c b/src/xs_internal.c index 4bcba392bc..4a24aa9954 100644 --- a/src/xs_internal.c +++ b/src/xs_internal.c @@ -37,6 +37,7 @@ static virDriver xenStoreDriver = { xenStoreClose, /* close */ NULL, /* type */ NULL, /* version */ + NULL, /* nodeGetInfo */ xenStoreListDomains, /* listDomains */ NULL, /* numOfDomains */ NULL, /* domainCreateLinux */