mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
* docs/format.html docs/libvir.html: documentation cleaups
from Jim Paris Daniel
This commit is contained in:
parent
a87420ae59
commit
cfb192ad1e
@ -1,3 +1,8 @@
|
|||||||
|
Mon Oct 22 22:27:40 CEST 2007 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
|
* docs/format.html docs/libvir.html: documentation cleaups
|
||||||
|
from Jim Paris
|
||||||
|
|
||||||
Mon Oct 22 15:05:30 CEST 2007 Daniel Veillard <veillard@redhat.com>
|
Mon Oct 22 15:05:30 CEST 2007 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* src/xend_internal.c: update to cpuset parsing code for NUMA
|
* src/xend_internal.c: update to cpuset parsing code for NUMA
|
||||||
|
@ -230,7 +230,7 @@ support a variety of options:</p><ol><li>Userspace SLIRP stack
|
|||||||
<pre><interface type='user'/></pre>
|
<pre><interface type='user'/></pre>
|
||||||
<pre>
|
<pre>
|
||||||
<interface type='user'>
|
<interface type='user'>
|
||||||
<mac address="11:22:33:44:55:66:/>
|
<mac address="11:22:33:44:55:66"/>
|
||||||
</interface>
|
</interface>
|
||||||
</pre>
|
</pre>
|
||||||
</li>
|
</li>
|
||||||
@ -253,7 +253,7 @@ support a variety of options:</p><ol><li>Userspace SLIRP stack
|
|||||||
<interface type='network'>
|
<interface type='network'>
|
||||||
<source network='default'/>
|
<source network='default'/>
|
||||||
<target dev='vnet7'/>
|
<target dev='vnet7'/>
|
||||||
<mac address="11:22:33:44:55:66:/>
|
<mac address="11:22:33:44:55:66"/>
|
||||||
</interface>
|
</interface>
|
||||||
</pre>
|
</pre>
|
||||||
</li>
|
</li>
|
||||||
@ -273,12 +273,8 @@ support a variety of options:</p><ol><li>Userspace SLIRP stack
|
|||||||
<interface type='bridge'>
|
<interface type='bridge'>
|
||||||
<source dev='br0'/>
|
<source dev='br0'/>
|
||||||
<target dev='vnet7'/>
|
<target dev='vnet7'/>
|
||||||
<mac address="11:22:33:44:55:66:/>
|
<mac address="11:22:33:44:55:66"/>
|
||||||
</interface> <interface type='bridge'>
|
</interface></pre>
|
||||||
<source dev='br0'/>
|
|
||||||
<target dev='vnet7'/>
|
|
||||||
<mac address="11:22:33:44:55:66:/>
|
|
||||||
</interface></pre>
|
|
||||||
</li>
|
</li>
|
||||||
<li>Generic connection to LAN
|
<li>Generic connection to LAN
|
||||||
<p>Provides a means for the administrator to execute an arbitrary script
|
<p>Provides a means for the administrator to execute an arbitrary script
|
||||||
|
@ -964,7 +964,7 @@ support a variety of options:</p>
|
|||||||
<pre><interface type='user'/></pre>
|
<pre><interface type='user'/></pre>
|
||||||
<pre>
|
<pre>
|
||||||
<interface type='user'>
|
<interface type='user'>
|
||||||
<mac address="11:22:33:44:55:66:/>
|
<mac address="11:22:33:44:55:66"/>
|
||||||
</interface>
|
</interface>
|
||||||
</pre>
|
</pre>
|
||||||
</li>
|
</li>
|
||||||
@ -987,7 +987,7 @@ support a variety of options:</p>
|
|||||||
<interface type='network'>
|
<interface type='network'>
|
||||||
<source network='default'/>
|
<source network='default'/>
|
||||||
<target dev='vnet7'/>
|
<target dev='vnet7'/>
|
||||||
<mac address="11:22:33:44:55:66:/>
|
<mac address="11:22:33:44:55:66"/>
|
||||||
</interface>
|
</interface>
|
||||||
</pre>
|
</pre>
|
||||||
</li>
|
</li>
|
||||||
@ -1007,12 +1007,8 @@ support a variety of options:</p>
|
|||||||
<interface type='bridge'>
|
<interface type='bridge'>
|
||||||
<source dev='br0'/>
|
<source dev='br0'/>
|
||||||
<target dev='vnet7'/>
|
<target dev='vnet7'/>
|
||||||
<mac address="11:22:33:44:55:66:/>
|
<mac address="11:22:33:44:55:66"/>
|
||||||
</interface> <interface type='bridge'>
|
</interface></pre>
|
||||||
<source dev='br0'/>
|
|
||||||
<target dev='vnet7'/>
|
|
||||||
<mac address="11:22:33:44:55:66:/>
|
|
||||||
</interface></pre>
|
|
||||||
</li>
|
</li>
|
||||||
<li>Generic connection to LAN
|
<li>Generic connection to LAN
|
||||||
<p>Provides a means for the administrator to execute an arbitrary script
|
<p>Provides a means for the administrator to execute an arbitrary script
|
||||||
|
@ -3035,24 +3035,27 @@ xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *free
|
|||||||
xen_op_v2_sys op_sys;
|
xen_op_v2_sys op_sys;
|
||||||
int i, j, ret;
|
int i, j, ret;
|
||||||
xenUnifiedPrivatePtr priv;
|
xenUnifiedPrivatePtr priv;
|
||||||
static int nbNodeCells = -1;
|
int nbNodeCells;
|
||||||
virNodeInfo nodeInfo;
|
|
||||||
|
|
||||||
|
if (conn == NULL) {
|
||||||
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)) {
|
|
||||||
virXenErrorFunc (VIR_ERR_INVALID_ARG, __FUNCTION__,
|
virXenErrorFunc (VIR_ERR_INVALID_ARG, __FUNCTION__,
|
||||||
"invalid argument", 0);
|
"invalid argument", 0);
|
||||||
return -1;
|
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
|
* Support only sys_interface_version >=4
|
||||||
*/
|
*/
|
||||||
|
@ -37,6 +37,9 @@
|
|||||||
#include "xs_internal.h"
|
#include "xs_internal.h"
|
||||||
#include "xm_internal.h"
|
#include "xm_internal.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
xenUnifiedNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info);
|
||||||
|
|
||||||
/* The five Xen drivers below us. */
|
/* The five Xen drivers below us. */
|
||||||
static struct xenUnifiedDriver *drivers[XEN_UNIFIED_NR_DRIVERS] = {
|
static struct xenUnifiedDriver *drivers[XEN_UNIFIED_NR_DRIVERS] = {
|
||||||
[XEN_UNIFIED_HYPERVISOR_OFFSET] = &xenHypervisorDriver,
|
[XEN_UNIFIED_HYPERVISOR_OFFSET] = &xenHypervisorDriver,
|
||||||
@ -64,6 +67,62 @@ xenUnifiedError (virConnectPtr conn, virErrorNumber error, const char *info)
|
|||||||
errmsg, info, NULL, 0, 0, errmsg, 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. -----*/
|
/*----- Dispatch functions. -----*/
|
||||||
|
|
||||||
/* These dispatch functions follow the model used historically
|
/* These dispatch functions follow the model used historically
|
||||||
|
@ -116,6 +116,9 @@ struct _xenUnifiedPrivate {
|
|||||||
|
|
||||||
typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;
|
typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;
|
||||||
|
|
||||||
|
|
||||||
|
int xenNbCells(virConnectPtr conn);
|
||||||
|
int xenNbCpus(virConnectPtr conn);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1895,352 +1895,6 @@ sexpr_to_xend_node_info(struct sexpr *root, virNodeInfoPtr info)
|
|||||||
return (0);
|
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, "\
|
|
||||||
<cell id='%d'>\n\
|
|
||||||
<cpus num='%d'>\n", cell, nb_cpus);
|
|
||||||
#ifdef STANDALONE
|
|
||||||
{
|
|
||||||
char *dump;
|
|
||||||
|
|
||||||
dump = saveCpuSet(conn, cpuset, maxcpu);
|
|
||||||
if (dump != NULL) {
|
|
||||||
virBufferVSprintf (xml, " <dump>%s</dump>\n", dump);
|
|
||||||
free(dump);
|
|
||||||
} else {
|
|
||||||
virBufferVSprintf (xml, " <error>%s</error>\n",
|
|
||||||
"Failed to dump CPU set");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (ret < 0)
|
|
||||||
goto memory_error;
|
|
||||||
for (cpu = 0;cpu < maxcpu;cpu++) {
|
|
||||||
if (cpuset[cpu] == 1) {
|
|
||||||
ret = virBufferVSprintf (xml, "\
|
|
||||||
<cpu id='%d'/>\n", cpu);
|
|
||||||
if (ret < 0)
|
|
||||||
goto memory_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret = virBufferAdd (xml, "\
|
|
||||||
</cpus>\n\
|
|
||||||
</cell>\n", -1);
|
|
||||||
if (ret < 0)
|
|
||||||
goto memory_error;
|
|
||||||
|
|
||||||
}
|
|
||||||
free(cpuset);
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
parse_error:
|
|
||||||
virXendError(conn, VIR_ERR_XEN_CALL,
|
|
||||||
_("topology syntax error"));
|
|
||||||
error:
|
|
||||||
if (cpuset != NULL)
|
|
||||||
free(cpuset);
|
|
||||||
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
memory_error:
|
|
||||||
if (cpuset != NULL)
|
|
||||||
free(cpuset);
|
|
||||||
virXendError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"));
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sexpr_to_xend_topology_xml:
|
* sexpr_to_xend_topology_xml:
|
||||||
* @root: an S-Expression describing a node
|
* @root: an S-Expression describing a node
|
||||||
@ -2276,7 +1930,7 @@ sexpr_to_xend_topology_xml(virConnectPtr conn, struct sexpr *root, virBufferPtr
|
|||||||
numCells);
|
numCells);
|
||||||
if (r < 0) goto vir_buffer_failed;
|
if (r < 0) goto vir_buffer_failed;
|
||||||
|
|
||||||
r = parseTopology(conn, xml, nodeToCpu, numCpus);
|
r = virParseXenCpuTopology(conn, xml, nodeToCpu, numCpus);
|
||||||
if (r < 0) goto error;
|
if (r < 0) goto error;
|
||||||
|
|
||||||
r = virBufferAdd (xml, "\
|
r = virBufferAdd (xml, "\
|
||||||
|
393
src/xml.c
393
src/xml.c
@ -24,6 +24,7 @@
|
|||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
#include "xs_internal.h" /* for xenStoreDomainGetNetworkID */
|
#include "xs_internal.h" /* for xenStoreDomainGetNetworkID */
|
||||||
|
#include "xen_unified.h"
|
||||||
|
|
||||||
#ifndef PROXY
|
#ifndef PROXY
|
||||||
/**
|
/**
|
||||||
@ -48,6 +49,362 @@ virXMLError(virConnectPtr conn, virErrorNumber error, const char *info, int valu
|
|||||||
errmsg, info, NULL, value, 0, errmsg, info, value);
|
errmsg, info, NULL, value, 0, errmsg, info, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Parser and converter for the CPUset strings used in libvirt *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
virXMLError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"), 1000);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virParseCpuSet:
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virParseCpuSet(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:
|
||||||
|
virXMLError(conn, VIR_ERR_XEN_CALL,
|
||||||
|
_("topology cpuset syntax error"), 0);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virParseXenCpuTopology:
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virParseXenCpuTopology(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 = virParseCpuSet(conn, &cur, 'n', cpuset, maxcpu);
|
||||||
|
if (nb_cpus < 0)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add xml for all cpus associated with that cell
|
||||||
|
*/
|
||||||
|
ret = virBufferVSprintf (xml, "\
|
||||||
|
<cell id='%d'>\n\
|
||||||
|
<cpus num='%d'>\n", cell, nb_cpus);
|
||||||
|
#ifdef STANDALONE
|
||||||
|
{
|
||||||
|
char *dump;
|
||||||
|
|
||||||
|
dump = saveCpuSet(conn, cpuset, maxcpu);
|
||||||
|
if (dump != NULL) {
|
||||||
|
virBufferVSprintf (xml, " <dump>%s</dump>\n", dump);
|
||||||
|
free(dump);
|
||||||
|
} else {
|
||||||
|
virBufferVSprintf (xml, " <error>%s</error>\n",
|
||||||
|
"Failed to dump CPU set");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ret < 0)
|
||||||
|
goto memory_error;
|
||||||
|
for (cpu = 0;cpu < maxcpu;cpu++) {
|
||||||
|
if (cpuset[cpu] == 1) {
|
||||||
|
ret = virBufferVSprintf (xml, "\
|
||||||
|
<cpu id='%d'/>\n", cpu);
|
||||||
|
if (ret < 0)
|
||||||
|
goto memory_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = virBufferAdd (xml, "\
|
||||||
|
</cpus>\n\
|
||||||
|
</cell>\n", -1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto memory_error;
|
||||||
|
|
||||||
|
}
|
||||||
|
free(cpuset);
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
parse_error:
|
||||||
|
virXMLError(conn, VIR_ERR_XEN_CALL,
|
||||||
|
_("topology syntax error"), 0);
|
||||||
|
error:
|
||||||
|
if (cpuset != NULL)
|
||||||
|
free(cpuset);
|
||||||
|
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
memory_error:
|
||||||
|
if (cpuset != NULL)
|
||||||
|
free(cpuset);
|
||||||
|
virXMLError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"), 0);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Wrappers around libxml2 XPath specific functions *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virXPathString:
|
* virXPathString:
|
||||||
* @xpath: the XPath string to evaluate
|
* @xpath: the XPath string to evaluate
|
||||||
@ -271,6 +628,12 @@ virXPathNodeSet(const char *xpath, xmlXPathContextPtr ctxt, xmlNodePtr **list) {
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Converter functions to go from the XML tree to an S-Expr for Xen *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virtDomainParseXMLGraphicsDescImage:
|
* virtDomainParseXMLGraphicsDescImage:
|
||||||
* @conn: pointer to the hypervisor connection
|
* @conn: pointer to the hypervisor connection
|
||||||
@ -1167,6 +1530,36 @@ virDomainParseXMLDesc(virConnectPtr conn, const char *xmldesc, char **name, int
|
|||||||
}
|
}
|
||||||
virBufferVSprintf(&buf, "(vcpus %u)", vcpus);
|
virBufferVSprintf(&buf, "(vcpus %u)", vcpus);
|
||||||
|
|
||||||
|
str = virXPathString("string(/domain/vcpu/@cpuset)", ctxt);
|
||||||
|
if (str != NULL) {
|
||||||
|
int maxcpu = xenNbCpus(conn);
|
||||||
|
char *cpuset = NULL;
|
||||||
|
char *ranges = NULL;
|
||||||
|
const char *cur = str;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the CPUset attribute given in libvirt format and reserialize
|
||||||
|
* it in a range format guaranteed to be understood by Xen.
|
||||||
|
*/
|
||||||
|
if (maxcpu > 0) {
|
||||||
|
cpuset = malloc(maxcpu * sizeof(char));
|
||||||
|
if (cpuset != NULL) {
|
||||||
|
res = virParseCpuSet(conn, &cur, 0, cpuset, maxcpu);
|
||||||
|
if (res > 0) {
|
||||||
|
ranges = saveCpuSet(conn, cpuset, maxcpu);
|
||||||
|
if (ranges != NULL) {
|
||||||
|
virBufferVSprintf(&buf, "(cpus '%s')", ranges);
|
||||||
|
free(ranges);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(cpuset);
|
||||||
|
} else {
|
||||||
|
virXMLError(conn, VIR_ERR_NO_MEMORY, xmldesc, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
|
||||||
str = virXPathString("string(/domain/uuid[1])", ctxt);
|
str = virXPathString("string(/domain/uuid[1])", ctxt);
|
||||||
if (str != NULL) {
|
if (str != NULL) {
|
||||||
virBufferVSprintf(&buf, "(uuid '%s')", str);
|
virBufferVSprintf(&buf, "(uuid '%s')", str);
|
||||||
|
26
src/xml.h
26
src/xml.h
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "libvirt/libvirt.h"
|
#include "libvirt/libvirt.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "buf.h"
|
||||||
|
|
||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
@ -31,9 +32,28 @@ int virXPathNodeSet (const char *xpath,
|
|||||||
xmlXPathContextPtr ctxt,
|
xmlXPathContextPtr ctxt,
|
||||||
xmlNodePtr **list);
|
xmlNodePtr **list);
|
||||||
|
|
||||||
char *virDomainParseXMLDesc(virConnectPtr conn, const char *xmldesc, char **name, int xendConfigVersion);
|
int virParseXenCpuTopology(virConnectPtr conn,
|
||||||
char *virParseXMLDevice(virConnectPtr conn, const char *xmldesc, int hvm, int xendConfigVersion);
|
virBufferPtr xml,
|
||||||
int virDomainXMLDevID(virDomainPtr domain, const char *xmldesc, char *class, char *ref, int ref_len);
|
const char *str,
|
||||||
|
int maxcpu);
|
||||||
|
int virParseCpuSet (virConnectPtr conn,
|
||||||
|
const char **str,
|
||||||
|
char sep,
|
||||||
|
char *cpuset,
|
||||||
|
int maxcpu);
|
||||||
|
char * virDomainParseXMLDesc(virConnectPtr conn,
|
||||||
|
const char *xmldesc,
|
||||||
|
char **name,
|
||||||
|
int xendConfigVersion);
|
||||||
|
char * virParseXMLDevice(virConnectPtr conn,
|
||||||
|
const char *xmldesc,
|
||||||
|
int hvm,
|
||||||
|
int xendConfigVersion);
|
||||||
|
int virDomainXMLDevID(virDomainPtr domain,
|
||||||
|
const char *xmldesc,
|
||||||
|
char *class,
|
||||||
|
char *ref,
|
||||||
|
int ref_len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user