+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
/**
* 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;
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
- */
};
/**
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 */
/**
const char * virConnectGetType (virConnectPtr conn);
int virConnectGetVersion (virConnectPtr conn,
unsigned long *hvVer);
+int virNodeGetInfo (virConnectPtr conn,
+ virNodeInfoPtr info);
/*
* Gather list of running domains
/**
* 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;
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
- */
};
/**
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 */
/**
const char * virConnectGetType (virConnectPtr conn);
int virConnectGetVersion (virConnectPtr conn,
unsigned long *hvVer);
+int virNodeGetInfo (virConnectPtr conn,
+ virNodeInfoPtr info);
/*
* Gather list of running domains
/**
* 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;
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
- */
};
/**
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 */
/**
const char * virConnectGetType (virConnectPtr conn);
int virConnectGetVersion (virConnectPtr conn,
unsigned long *hvVer);
+int virNodeGetInfo (virConnectPtr conn,
+ virNodeInfoPtr info);
/*
* Gather list of running domains
/**
* 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;
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
- */
};
/**
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 */
/**
const char * virConnectGetType (virConnectPtr conn);
int virConnectGetVersion (virConnectPtr conn,
unsigned long *hvVer);
+int virNodeGetInfo (virConnectPtr conn,
+ virNodeInfoPtr info);
/*
* Gather list of running domains
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;
/**
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;
/**
skip_impl = (
'virConnectListDomainsID',
'virDomainGetInfo',
+ 'virNodeGetInfo',
'virDomainGetUUID',
'virDomainLookupByUUID',
)
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:]
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;
{(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},
<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'/>
typedef int
(*virDrvGetVersion) (virConnectPtr conn,
unsigned long *hvVer);
+typedef int
+ (*virDrvNodeGetInfo) (virConnectPtr conn,
+ virNodeInfoPtr info);
typedef int
(*virDrvListDomains) (virConnectPtr conn,
int *ids,
virDrvClose close;
virDrvGetType type;
virDrvGetVersion version;
+ virDrvNodeGetInfo nodeGetInfo;
virDrvListDomains listDomains;
virDrvNumOfDomains numOfDomains;
virDrvDomainCreateLinux domainCreateLinux;
#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
*/
*/
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 */
* - memory wrappers for malloc/free ?
*/
-#define MAX_DRIVERS 5
static virDriverPtr virDriverTab[MAX_DRIVERS];
static int initialized = 0;
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");
}
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)
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);
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");
}
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);
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);
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);
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");
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);
+}
virConnCopyLastError;
virConnResetLastError;
virDefaultErrorFunc;
+ virNodeGetInfo;
local: *;
};
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);
}
xenHypervisorClose, /* close */
NULL, /* type */
xenHypervisorGetVersion, /* version */
+ NULL, /* nodeGetInfo */
NULL, /* listDomains */
NULL, /* numOfDomains */
NULL, /* domainCreateLinux */
#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 */
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
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);
+}
xenStoreClose, /* close */
NULL, /* type */
NULL, /* version */
+ NULL, /* nodeGetInfo */
xenStoreListDomains, /* listDomains */
NULL, /* numOfDomains */
NULL, /* domainCreateLinux */