diff --git a/ChangeLog b/ChangeLog
index af02d845da..ef87988482 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Oct 22 22:27:40 CEST 2007 Daniel Veillard
<interface type='user'/>
<interface type='user'> - <mac address="11:22:33:44:55:66:/> + <mac address="11:22:33:44:55:66"/> </interface>
Provides a means for the administrator to execute an arbitrary script diff --git a/docs/libvir.html b/docs/libvir.html index 22bb1681a2..571b9c1c33 100644 --- a/docs/libvir.html +++ b/docs/libvir.html @@ -964,7 +964,7 @@ support a variety of options:
<interface type='user'/>
<interface type='user'> - <mac address="11:22:33:44:55:66:/> + <mac address="11:22:33:44:55:66"/> </interface>
Provides a means for the administrator to execute an arbitrary script
diff --git a/src/xen_internal.c b/src/xen_internal.c
index 8cc5a5cf80..0bc956e335 100644
--- a/src/xen_internal.c
+++ b/src/xen_internal.c
@@ -3035,24 +3035,27 @@ xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *free
xen_op_v2_sys op_sys;
int i, j, ret;
xenUnifiedPrivatePtr priv;
- static int nbNodeCells = -1;
- virNodeInfo nodeInfo;
+ int nbNodeCells;
-
- if (nbNodeCells == -1) {
- if (xenDaemonNodeGetInfo(conn, &nodeInfo)) {
- virXenErrorFunc (VIR_ERR_XEN_CALL, __FUNCTION__,
- "cannot determine actual number of cells",0);
- return -1;
- }
- nbNodeCells = nodeInfo.nodes;
- }
-
- if ((conn == NULL) || (maxCells < 1) || (startCell >= nbNodeCells)) {
+ if (conn == NULL) {
virXenErrorFunc (VIR_ERR_INVALID_ARG, __FUNCTION__,
"invalid argument", 0);
return -1;
}
+
+ nbNodeCells = xenNbCells(conn);
+ if (nbNodeCells < 0) {
+ virXenErrorFunc (VIR_ERR_XEN_CALL, __FUNCTION__,
+ "cannot determine actual number of cells",0);
+ return(-1);
+ }
+
+ if ((maxCells < 1) || (startCell >= nbNodeCells)) {
+ virXenErrorFunc (VIR_ERR_INVALID_ARG, __FUNCTION__,
+ "invalid argument", 0);
+ return -1;
+ }
+
/*
* Support only sys_interface_version >=4
*/
diff --git a/src/xen_unified.c b/src/xen_unified.c
index b5c27e443c..760ec5282f 100644
--- a/src/xen_unified.c
+++ b/src/xen_unified.c
@@ -37,6 +37,9 @@
#include "xs_internal.h"
#include "xm_internal.h"
+static int
+xenUnifiedNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info);
+
/* The five Xen drivers below us. */
static struct xenUnifiedDriver *drivers[XEN_UNIFIED_NR_DRIVERS] = {
[XEN_UNIFIED_HYPERVISOR_OFFSET] = &xenHypervisorDriver,
@@ -64,6 +67,62 @@ xenUnifiedError (virConnectPtr conn, virErrorNumber error, const char *info)
errmsg, info, NULL, 0, 0, errmsg, info);
}
+/*
+ * Helper functions currently used in the NUMA code
+ * Those variables should not be accessed directly but through helper
+ * functions xenNbCells() and xenNbCpu() available to all Xen backends
+ */
+static int nbNodeCells = -1;
+static int nbNodeCpus = -1;
+
+/**
+ * xenNumaInit:
+ * @conn: pointer to the hypervisor connection
+ *
+ * Initializer for previous variables. We currently assume that
+ * the number of physical CPU and the numebr of NUMA cell is fixed
+ * until reboot which might be false in future Xen implementations.
+ */
+static void
+xenNumaInit(virConnectPtr conn) {
+ virNodeInfo nodeInfo;
+ int ret;
+
+ ret = xenUnifiedNodeGetInfo(conn, &nodeInfo);
+ if (ret < 0)
+ return;
+ nbNodeCells = nodeInfo.nodes;
+ nbNodeCpus = nodeInfo.cpus;
+}
+
+/**
+ * xenNbCells:
+ * @conn: pointer to the hypervisor connection
+ *
+ * Number of NUMa cells present in the actual Node
+ *
+ * Returns the number of NUMA cells available on that Node
+ */
+int xenNbCells(virConnectPtr conn) {
+ if (nbNodeCells < 0)
+ xenNumaInit(conn);
+ return(nbNodeCells);
+}
+
+/**
+ * xenNbCpus:
+ * @conn: pointer to the hypervisor connection
+ *
+ * Number of NUMa cells present in the actual Node
+ *
+ * Returns the number of NUMA cells available on that Node
+ */
+int xenNbCpus(virConnectPtr conn) {
+ if (nbNodeCpus < 0)
+ xenNumaInit(conn);
+ return(nbNodeCpus);
+}
+
/*----- Dispatch functions. -----*/
/* These dispatch functions follow the model used historically
diff --git a/src/xen_unified.h b/src/xen_unified.h
index 0d991bff34..86cc1c0ba5 100644
--- a/src/xen_unified.h
+++ b/src/xen_unified.h
@@ -116,6 +116,9 @@ struct _xenUnifiedPrivate {
typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;
+
+int xenNbCells(virConnectPtr conn);
+int xenNbCpus(virConnectPtr conn);
#ifdef __cplusplus
}
#endif
diff --git a/src/xend_internal.c b/src/xend_internal.c
index 142835fc4d..e407a48805 100644
--- a/src/xend_internal.c
+++ b/src/xend_internal.c
@@ -1895,352 +1895,6 @@ sexpr_to_xend_node_info(struct sexpr *root, virNodeInfoPtr info)
return (0);
}
-/**
- * skipSpaces:
- * @str: pointer to the char pointer used
- *
- * Skip potential blanks, this includes space tabs, line feed,
- * carriage returns and also '\\' which can be erronously emitted
- * by xend
- */
-static void
-skipSpaces(const char **str) {
- const char *cur = *str;
-
- while ((*cur == ' ') || (*cur == '\t') || (*cur == '\n') ||
- (*cur == '\r') || (*cur == '\\')) cur++;
- *str = cur;
-}
-
-/**
- * parseNumber:
- * @str: pointer to the char pointer used
- *
- * Parse a number
- *
- * Returns the CPU number or -1 in case of error. @str will be
- * updated to skip the number.
- */
-static int
-parseNumber(const char **str) {
- int ret = 0;
- const char *cur = *str;
-
- if ((*cur < '0') || (*cur > '9'))
- return(-1);
-
- while ((*cur >= '0') && (*cur <= '9')) {
- ret = ret * 10 + (*cur - '0');
- cur++;
- }
- *str = cur;
- return(ret);
-}
-
-/**
- * parseCpuNumber:
- * @str: pointer to the char pointer used
- * @maxcpu: maximum CPU number allowed
- *
- * Parse a CPU number
- *
- * Returns the CPU number or -1 in case of error. @str will be
- * updated to skip the number.
- */
-static int
-parseCpuNumber(const char **str, int maxcpu) {
- int ret = 0;
- const char *cur = *str;
-
- if ((*cur < '0') || (*cur > '9'))
- return(-1);
-
- while ((*cur >= '0') && (*cur <= '9')) {
- ret = ret * 10 + (*cur - '0');
- if (ret > maxcpu)
- return(-1);
- cur++;
- }
- *str = cur;
- return(ret);
-}
-
-#if 0 /* Not used yet */
-/**
- * saveCpuSet:
- * @conn: connection
- * @cpuset: pointer to a char array for the CPU set
- * @maxcpu: number of elements available in @cpuset
- *
- * Serialize the cpuset to a string
- *
- * Returns the new string NULL in case of error. The string need to be
- * freed by the caller.
- */
-static char *
-saveCpuSet(virConnectPtr conn, char *cpuset, int maxcpu)
-{
- virBufferPtr buf;
- char *ret;
- int start, cur;
- int first = 1;
-
- if ((cpuset == NULL) || (maxcpu <= 0) || (maxcpu >100000))
- return(NULL);
-
- buf = virBufferNew(1000);
- if (buf == NULL) {
- virXendError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"));
- return(NULL);
- }
- cur = 0;
- start = -1;
- while (cur < maxcpu) {
- if (cpuset[cur]) {
- if (start == -1)
- start = cur;
- } else if (start != -1) {
- if (!first)
- virBufferAdd(buf, ",", -1);
- else
- first = 0;
- if (cur == start + 1)
- virBufferVSprintf(buf, "%d", start);
- else if (cur == start + 2)
- virBufferVSprintf(buf, "%d,%d", start, cur - 1);
- else
- virBufferVSprintf(buf, "%d-%d", start, cur - 1);
- start = -1;
- }
- cur++;
- }
- if (start != -1) {
- if (!first)
- virBufferAdd(buf, ",", -1);
- if (maxcpu == start + 1)
- virBufferVSprintf(buf, "%d", start);
- else if (maxcpu == start + 2)
- virBufferVSprintf(buf, "%d,%d", start, maxcpu - 1);
- else
- virBufferVSprintf(buf, "%d-%d", start, maxcpu - 1);
- }
- ret = virBufferContentAndFree(buf);
- return(ret);
-}
-#endif
-
-/**
- * parseCpuSet:
- * @str: pointer to a CPU set string pointer
- * @sep: potential character used to mark the end of string if not 0
- * @cpuset: pointer to a char array for the CPU set
- * @maxcpu: number of elements available in @cpuset
- *
- * Parse the cpu set, it will set the value for enabled CPUs in the @cpuset
- * to 1, and 0 otherwise. The syntax allows coma separated entries each
- * can be either a CPU number, ^N to unset that CPU or N-M for ranges.
- *
- * Returns the number of CPU found in that set, or -1 in case of error.
- * @cpuset is modified accordingly to the value parsed.
- * @str is updated to the end of the part parsed
- */
-static int
-parseCpuSet(virConnectPtr conn, const char **str, char sep, char *cpuset,
- int maxcpu)
-{
- const char *cur;
- int ret = 0;
- int i, start, last;
- int neg = 0;
-
- if ((str == NULL) || (cpuset == NULL) || (maxcpu <= 0) || (maxcpu >100000))
- return(-1);
-
- cur = *str;
- skipSpaces(&cur);
- if (*cur == 0)
- goto parse_error;
-
- /* initialize cpumap to all 0s */
- for (i = 0;i < maxcpu;i++)
- cpuset[i] = 0;
- ret = 0;
-
- while ((*cur != 0) && (*cur != sep)) {
- /*
- * 3 constructs are allowed:
- * - N : a single CPU number
- * - N-M : a range of CPU numbers with N < M
- * - ^N : remove a single CPU number from the current set
- */
- if (*cur == '^') {
- cur++;
- neg = 1;
- }
-
- if ((*cur < '0') || (*cur > '9'))
- goto parse_error;
- start = parseCpuNumber(&cur, maxcpu);
- if (start < 0)
- goto parse_error;
- skipSpaces(&cur);
- if ((*cur == ',') || (*cur == 0) || (*cur == sep)) {
- if (neg) {
- if (cpuset[start] == 1) {
- cpuset[start] = 0;
- ret--;
- }
- } else {
- if (cpuset[start] == 0) {
- cpuset[start] = 1;
- ret++;
- }
- }
- } else if (*cur == '-') {
- if (neg)
- goto parse_error;
- cur++;
- skipSpaces(&cur);
- last = parseCpuNumber(&cur, maxcpu);
- if (last < start)
- goto parse_error;
- for (i = start;i <= last;i++) {
- if (cpuset[i] == 0) {
- cpuset[i] = 1;
- ret++;
- }
- }
- skipSpaces(&cur);
- }
- if (*cur == ',') {
- cur++;
- skipSpaces(&cur);
- neg = 0;
- } else if ((*cur == 0) || (*cur == sep)) {
- break;
- } else
- goto parse_error;
- }
- *str = cur;
- return(ret);
-
-parse_error:
- virXendError(conn, VIR_ERR_XEN_CALL,
- _("topology cpuset syntax error"));
- return(-1);
-}
-
-
-/**
- * parseXenCpuTopology:
- * @xml: XML output buffer
- * @str: the topology string
- * @maxcpu: number of elements available in @cpuset
- *
- * Parse a Xend CPU topology string and build the associated XML
- * format.
- *
- * Returns 0 in case of success, -1 in case of error
- */
-static int
-parseTopology(virConnectPtr conn, virBufferPtr xml, const char *str,
- int maxcpu)
-{
- const char *cur;
- char *cpuset = NULL;
- int cell, cpu, nb_cpus;
- int ret;
-
- if ((str == NULL) || (xml == NULL) || (maxcpu <= 0) || (maxcpu >100000))
- return(-1);
-
- cpuset = malloc(maxcpu * sizeof(char));
- if (cpuset == NULL)
- goto memory_error;
-
- cur = str;
- while (*cur != 0) {
- /*
- * Find the next NUMA cell described in the xend output
- */
- cur = strstr(cur, "node");
- if (cur == NULL)
- break;
- cur += 4;
- cell = parseNumber(&cur);
- if (cell < 0)
- goto parse_error;
- skipSpaces(&cur);
- if (*cur != ':')
- goto parse_error;
- cur++;
- skipSpaces(&cur);
- if (!strncmp (cur, "no cpus", 7)) {
- nb_cpus = 0;
- for (cpu = 0;cpu < maxcpu;cpu++)
- cpuset[cpu] = 0;
- } else {
- nb_cpus = parseCpuSet(conn, &cur, 'n', cpuset, maxcpu);
- if (nb_cpus < 0)
- goto error;
- }
-
- /*
- * add xml for all cpus associated with that cell
- */
- ret = virBufferVSprintf (xml, "\
-