mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-30 01:43:23 +00:00
* src/xend_internal.c src/xml.c: patches from Jim Fehlig for HVM
guests, plus XML format changes and merge from Mark McLoughlin Daniel
This commit is contained in:
parent
3ffac4a188
commit
3d90a9c86d
@ -1,9 +1,14 @@
|
|||||||
|
Mon Jul 10 12:27:17 CEST 2006 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
|
* src/xend_internal.c src/xml.c: patches from Jim Fehlig for HVM
|
||||||
|
guests, plus XML format changes and merge from Mark McLoughlin
|
||||||
|
|
||||||
Fri Jul 7 09:47:14 EDT 2006 Daniel Berrange <berrange@redhat.com>
|
Fri Jul 7 09:47:14 EDT 2006 Daniel Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
* src/xend_internal.c: changed xenDaemonLookupByID to simply do
|
* src/xend_internal.c: changed xenDaemonLookupByID to simply do
|
||||||
an sexpr GET on /xend/domain/[ID] instead of listing all names
|
an sexpr GET on /xend/domain/[ID] instead of listing all names
|
||||||
and iterating over /xend/domain/[NAME]. Reduces the running time
|
and iterating over /xend/domain/[NAME]. Reduces the running time
|
||||||
and number of GETs from O(n^2) to O(n).
|
and number of GETs from O(n^2) to O(n).
|
||||||
|
|
||||||
* src/xend_internal.c: fixed xenDaemonOpen() to try both unix and
|
* src/xend_internal.c: fixed xenDaemonOpen() to try both unix and
|
||||||
|
|
||||||
Wed Jul 5 17:11:32 IST 2006 Mark McLoughlin <markmc@redhat.com>
|
Wed Jul 5 17:11:32 IST 2006 Mark McLoughlin <markmc@redhat.com>
|
||||||
|
@ -1350,10 +1350,77 @@ xend_log(virConnectPtr xend, char *buffer, size_t n_buffer)
|
|||||||
******
|
******
|
||||||
*****************************************************************/
|
*****************************************************************/
|
||||||
#ifndef XEN_RO
|
#ifndef XEN_RO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xend_parse_sexp_desc_os:
|
||||||
|
* @node: the root of the parsed S-Expression
|
||||||
|
* @buf: output buffer object
|
||||||
|
* @hvm: true or 1 if no contains HVM S-Expression
|
||||||
|
*
|
||||||
|
* Parse the xend sexp for description of os and append it to buf.
|
||||||
|
*
|
||||||
|
* Returns 0 in case of success and -1 in case of error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
xend_parse_sexp_desc_os(struct sexpr *node, virBufferPtr buf, int hvm)
|
||||||
|
{
|
||||||
|
const char *tmp;
|
||||||
|
|
||||||
|
if (node == NULL || buf == NULL) {
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAdd(buf, " <os>\n", 7);
|
||||||
|
if (hvm) {
|
||||||
|
virBufferVSprintf(buf, " <type>hvm</type>\n");
|
||||||
|
tmp = sexpr_node(node, "domain/image/hvm/kernel");
|
||||||
|
if (tmp == NULL) {
|
||||||
|
virXendError(NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"domain informations incomplete, missing kernel");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
virBufferVSprintf(buf, " <loader>%s</loader>\n", tmp);
|
||||||
|
tmp = sexpr_node(node, "domain/image/hvm/boot");
|
||||||
|
if ((tmp != NULL) && (tmp[0] != 0)) {
|
||||||
|
// FIXME:
|
||||||
|
// Figure out how to map the 'a', 'b', 'c' nonsense to a
|
||||||
|
// device.
|
||||||
|
if (tmp[0] == 'a')
|
||||||
|
virBufferAdd(buf, " <boot dev='/dev/fd0'/>\n", 25 );
|
||||||
|
else if (tmp[0] == 'c')
|
||||||
|
// Don't know what to put here. Say the vm has been given 3
|
||||||
|
// disks - hda, hdb, hdc. How does one identify the boot disk?
|
||||||
|
virBufferAdd(buf, " <boot dev='hda'/>\n", 22 );
|
||||||
|
else if (strcmp(tmp, "d") == 0)
|
||||||
|
virBufferAdd(buf, " <boot dev='/dev/cdrom'/>\n", 24 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
virBufferVSprintf(buf, " <type>linux</type>\n");
|
||||||
|
tmp = sexpr_node(node, "domain/image/linux/kernel");
|
||||||
|
if (tmp == NULL) {
|
||||||
|
virXendError(NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"domain informations incomplete, missing kernel");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
virBufferVSprintf(buf, " <kernel>%s</kernel>\n", tmp);
|
||||||
|
tmp = sexpr_node(node, "domain/image/linux/ramdisk");
|
||||||
|
if ((tmp != NULL) && (tmp[0] != 0))
|
||||||
|
virBufferVSprintf(buf, " <initrd>%s</initrd>\n", tmp);
|
||||||
|
tmp = sexpr_node(node, "domain/image/linux/root");
|
||||||
|
if ((tmp != NULL) && (tmp[0] != 0))
|
||||||
|
virBufferVSprintf(buf, " <root>%s</root>\n", tmp);
|
||||||
|
tmp = sexpr_node(node, "domain/image/linux/args");
|
||||||
|
if ((tmp != NULL) && (tmp[0] != 0))
|
||||||
|
virBufferVSprintf(buf, " <cmdline>%s</cmdline>\n", tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAdd(buf, " </os>\n", 8);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xend_parse_sexp_desc:
|
* xend_parse_sexp_desc:
|
||||||
* @root: the root of the parsed S-Expression
|
* @root: the root of the parsed S-Expression
|
||||||
* @name: output name of the domain
|
|
||||||
*
|
*
|
||||||
* Parse the xend sexp description and turn it into the XML format similar
|
* Parse the xend sexp description and turn it into the XML format similar
|
||||||
* to the one unsed for creation.
|
* to the one unsed for creation.
|
||||||
@ -1368,6 +1435,7 @@ xend_parse_sexp_desc(struct sexpr *root)
|
|||||||
struct sexpr *cur, *node;
|
struct sexpr *cur, *node;
|
||||||
const char *tmp;
|
const char *tmp;
|
||||||
virBuffer buf;
|
virBuffer buf;
|
||||||
|
int hvm;
|
||||||
|
|
||||||
if (root == NULL) {
|
if (root == NULL) {
|
||||||
/* ERROR */
|
/* ERROR */
|
||||||
@ -1407,30 +1475,12 @@ xend_parse_sexp_desc(struct sexpr *root)
|
|||||||
tmp = sexpr_node(root, "domain/bootloader");
|
tmp = sexpr_node(root, "domain/bootloader");
|
||||||
if (tmp != NULL)
|
if (tmp != NULL)
|
||||||
virBufferVSprintf(&buf, " <bootloader>%s</bootloader>\n", tmp);
|
virBufferVSprintf(&buf, " <bootloader>%s</bootloader>\n", tmp);
|
||||||
|
|
||||||
if (sexpr_lookup(root, "domain/image")) {
|
if (sexpr_lookup(root, "domain/image")) {
|
||||||
tmp = sexpr_node(root, "domain/image/linux/kernel");
|
hvm = sexpr_lookup(root, "domain/image/hvm") ? 1 : 0;
|
||||||
if (tmp == NULL) {
|
xend_parse_sexp_desc_os(root, &buf, hvm);
|
||||||
/*
|
|
||||||
* TODO: we will need some fallback here for other guest OSes
|
|
||||||
*/
|
|
||||||
virXendError(NULL, VIR_ERR_INTERNAL_ERROR,
|
|
||||||
"domain informations incomplete, missing kernel");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
virBufferAdd(&buf, " <os>\n", 7);
|
|
||||||
virBufferVSprintf(&buf, " <type>linux</type>\n");
|
|
||||||
virBufferVSprintf(&buf, " <kernel>%s</kernel>\n", tmp);
|
|
||||||
tmp = sexpr_node(root, "domain/image/linux/ramdisk");
|
|
||||||
if ((tmp != NULL) && (tmp[0] != 0))
|
|
||||||
virBufferVSprintf(&buf, " <initrd>%s</initrd>\n", tmp);
|
|
||||||
tmp = sexpr_node(root, "domain/image/linux/root");
|
|
||||||
if ((tmp != NULL) && (tmp[0] != 0))
|
|
||||||
virBufferVSprintf(&buf, " <root>%s</root>\n", tmp);
|
|
||||||
tmp = sexpr_node(root, "domain/image/linux/args");
|
|
||||||
if ((tmp != NULL) && (tmp[0] != 0))
|
|
||||||
virBufferVSprintf(&buf, " <cmdline>%s</cmdline>\n", tmp);
|
|
||||||
virBufferAdd(&buf, " </os>\n", 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virBufferVSprintf(&buf, " <memory>%d</memory>\n",
|
virBufferVSprintf(&buf, " <memory>%d</memory>\n",
|
||||||
(int) (sexpr_u64(root, "domain/maxmem") << 10));
|
(int) (sexpr_u64(root, "domain/maxmem") << 10));
|
||||||
virBufferVSprintf(&buf, " <vcpu>%d</vcpu>\n",
|
virBufferVSprintf(&buf, " <vcpu>%d</vcpu>\n",
|
||||||
@ -1446,6 +1496,12 @@ xend_parse_sexp_desc(struct sexpr *root)
|
|||||||
virBufferVSprintf(&buf, " <on_crash>%s</on_crash>\n", tmp);
|
virBufferVSprintf(&buf, " <on_crash>%s</on_crash>\n", tmp);
|
||||||
|
|
||||||
virBufferAdd(&buf, " <devices>\n", 12);
|
virBufferAdd(&buf, " <devices>\n", 12);
|
||||||
|
|
||||||
|
/* in case of HVM we have devices emulation */
|
||||||
|
tmp = sexpr_node(root, "domain/image/hvm/device_model");
|
||||||
|
if ((tmp != NULL) && (tmp[0] != 0))
|
||||||
|
virBufferVSprintf(&buf, " <emulator>%s</emulator>\n", tmp);
|
||||||
|
|
||||||
for (cur = root; cur->kind == SEXPR_CONS; cur = cur->cdr) {
|
for (cur = root; cur->kind == SEXPR_CONS; cur = cur->cdr) {
|
||||||
node = cur->car;
|
node = cur->car;
|
||||||
if (sexpr_lookup(node, "device/vbd")) {
|
if (sexpr_lookup(node, "device/vbd")) {
|
||||||
@ -1523,9 +1579,32 @@ xend_parse_sexp_desc(struct sexpr *root)
|
|||||||
virBufferVSprintf(&buf, "<!-- Failed to parse vif: %s -->\n",
|
virBufferVSprintf(&buf, "<!-- Failed to parse vif: %s -->\n",
|
||||||
serial);
|
serial);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hvm) {
|
||||||
|
/* Graphics device */
|
||||||
|
/* TODO:
|
||||||
|
* Support for some additional attributes for graphics device?
|
||||||
|
*/
|
||||||
|
tmp = sexpr_node(root, "domain/image/hvm/vnc");
|
||||||
|
if (tmp != NULL) {
|
||||||
|
if (tmp[0] == '1')
|
||||||
|
virBufferAdd(&buf, " <graphics type='vnc'/>\n", 27 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmp = sexpr_node(root, "domain/image/hvm/sdl");
|
||||||
|
if (tmp != NULL) {
|
||||||
|
if (tmp[0] == '1')
|
||||||
|
virBufferAdd(&buf, " <graphics type='sdl'/>\n", 27 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO:
|
||||||
|
* Device for cdrom
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
virBufferAdd(&buf, " </devices>\n", 13);
|
virBufferAdd(&buf, " </devices>\n", 13);
|
||||||
virBufferAdd(&buf, "</domain>\n", 10);
|
virBufferAdd(&buf, "</domain>\n", 10);
|
||||||
|
|
||||||
|
163
src/xml.c
163
src/xml.c
@ -563,19 +563,141 @@ virDomainGetXMLDesc(virDomainPtr domain, int flags)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virDomainParseXMLOSDesc:
|
* virDomainParseXMLOSDescHVM:
|
||||||
* @xmldesc: string with the XML description
|
* @node: node containing HVM OS description
|
||||||
* @buf: a buffer for the result S-Expr
|
* @buf: a buffer for the result S-Expr
|
||||||
|
* @ctxt: a path context representing the XML description
|
||||||
*
|
*
|
||||||
* Parse the OS part of the XML description and add it to the S-Expr in buf
|
* Parse the OS part of the XML description for an HVM domain and add it to
|
||||||
* This is a temporary interface as the S-Expr interface
|
* the S-Expr in buf. This is a temporary interface as the S-Expr interface
|
||||||
* will be replaced by XML-RPC in the future. However the XML format should
|
* will be replaced by XML-RPC in the future. However the XML format should
|
||||||
* stay valid over time.
|
* stay valid over time.
|
||||||
*
|
*
|
||||||
* Returns 0 in case of success, -1 in case of error.
|
* Returns 0 in case of success, -1 in case of error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
virDomainParseXMLOSDesc(xmlNodePtr node, virBufferPtr buf)
|
virDomainParseXMLOSDescHVM(xmlNodePtr node, virBufferPtr buf, xmlXPathContextPtr ctxt)
|
||||||
|
{
|
||||||
|
xmlXPathObjectPtr obj = NULL;
|
||||||
|
xmlNodePtr cur, txt;
|
||||||
|
const xmlChar *type = NULL;
|
||||||
|
const xmlChar *loader = NULL;
|
||||||
|
const xmlChar *dev_model = NULL;
|
||||||
|
const xmlChar *boot_dev = NULL;
|
||||||
|
xmlChar *graphics_type = NULL;
|
||||||
|
|
||||||
|
cur = node->children;
|
||||||
|
while (cur != NULL) {
|
||||||
|
if (cur->type == XML_ELEMENT_NODE) {
|
||||||
|
if ((type == NULL)
|
||||||
|
&& (xmlStrEqual(cur->name, BAD_CAST "type"))) {
|
||||||
|
txt = cur->children;
|
||||||
|
if ((txt != NULL) && (txt->type == XML_TEXT_NODE) &&
|
||||||
|
(txt->next == NULL))
|
||||||
|
type = txt->content;
|
||||||
|
} else if ((loader == NULL) &&
|
||||||
|
(xmlStrEqual(cur->name, BAD_CAST "loader"))) {
|
||||||
|
txt = cur->children;
|
||||||
|
if ((txt != NULL) && (txt->type == XML_TEXT_NODE) &&
|
||||||
|
(txt->next == NULL))
|
||||||
|
loader = txt->content;
|
||||||
|
} else if ((boot_dev == NULL) &&
|
||||||
|
(xmlStrEqual(cur->name, BAD_CAST "boot"))) {
|
||||||
|
boot_dev = xmlGetProp(cur, BAD_CAST "dev");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
if ((type == NULL) || (!xmlStrEqual(type, BAD_CAST "hvm"))) {
|
||||||
|
/* VIR_ERR_OS_TYPE */
|
||||||
|
virXMLError(VIR_ERR_OS_TYPE, (const char *) type, 0);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
virBufferAdd(buf, "(image (hvm ", 12);
|
||||||
|
if (loader == NULL) {
|
||||||
|
virXMLError(VIR_ERR_NO_KERNEL, NULL, 0);
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
virBufferVSprintf(buf, "(kernel '%s')", (const char *) loader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the device emulation model */
|
||||||
|
obj = xmlXPathEval(BAD_CAST "string(/domain/devices/emulator[1])", ctxt);
|
||||||
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
||||||
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
||||||
|
virXMLError(VIR_ERR_NO_KERNEL, NULL, 0); /* TODO: error */
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
virBufferVSprintf(buf, "(device_model '%s')",
|
||||||
|
(const char *) obj->stringval);
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
obj = NULL;
|
||||||
|
|
||||||
|
if (boot_dev) {
|
||||||
|
/* TODO:
|
||||||
|
* Have to figure out the naming used here.
|
||||||
|
*/
|
||||||
|
if (xmlStrEqual(type, BAD_CAST "hda")) {
|
||||||
|
virBufferVSprintf(buf, "(boot a)", (const char *) boot_dev);
|
||||||
|
} else if (xmlStrEqual(type, BAD_CAST "hdd")) {
|
||||||
|
virBufferVSprintf(buf, "(boot d)", (const char *) boot_dev);
|
||||||
|
} else {
|
||||||
|
/* Force hd[b|c] if boot_dev specified but not floppy or cdrom? */
|
||||||
|
virBufferVSprintf(buf, "(boot c)", (const char *) boot_dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* TODO:
|
||||||
|
* Is a cdrom disk device specified?
|
||||||
|
* Kind of ugly since it is buried in the devices/diskk node.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Is a graphics device specified? */
|
||||||
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics[1]", ctxt);
|
||||||
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
||||||
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr = 0)) {
|
||||||
|
virXMLError(VIR_ERR_NO_OS, "", 0); /* TODO: error */
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics_type = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "type");
|
||||||
|
if (graphics_type != NULL) {
|
||||||
|
if (xmlStrEqual(graphics_type, BAD_CAST "sdl")) {
|
||||||
|
virBufferAdd(buf, "(sdl 1)", 7);
|
||||||
|
// TODO:
|
||||||
|
// Need to understand sdl options
|
||||||
|
//
|
||||||
|
//virBufferAdd(buf, "(display localhost:10.0)", 24);
|
||||||
|
//virBufferAdd(buf, "(xauthority /root/.Xauthority)", 30);
|
||||||
|
}
|
||||||
|
else if (xmlStrEqual(graphics_type, BAD_CAST "vnc"))
|
||||||
|
virBufferAdd(buf, "(vnc 1)", 7);
|
||||||
|
xmlFree(graphics_type);
|
||||||
|
}
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
|
||||||
|
virBufferAdd(buf, "))", 2);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
error:
|
||||||
|
if (obj != NULL)
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainParseXMLOSDescPV:
|
||||||
|
* @node: node containing PV OS description
|
||||||
|
* @buf: a buffer for the result S-Expr
|
||||||
|
*
|
||||||
|
* Parse the OS part of the XML description for a paravirtualized domain
|
||||||
|
* and add it to the S-Expr in buf. This is a temporary interface as the
|
||||||
|
* S-Expr interface will be replaced by XML-RPC in the future. However
|
||||||
|
* the XML format should stay valid over time.
|
||||||
|
*
|
||||||
|
* Returns 0 in case of success, -1 in case of error.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
virDomainParseXMLOSDescPV(xmlNodePtr node, virBufferPtr buf)
|
||||||
{
|
{
|
||||||
xmlNodePtr cur, txt;
|
xmlNodePtr cur, txt;
|
||||||
const xmlChar *type = NULL;
|
const xmlChar *type = NULL;
|
||||||
@ -645,7 +767,7 @@ virDomainParseXMLOSDesc(xmlNodePtr node, virBufferPtr buf)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* virDomainParseXMLDiskDesc:
|
* virDomainParseXMLDiskDesc:
|
||||||
* @xmldesc: string with the XML description
|
* @node: node containing disk description
|
||||||
* @buf: a buffer for the result S-Expr
|
* @buf: a buffer for the result S-Expr
|
||||||
*
|
*
|
||||||
* Parse the one disk in the XML description and add it to the S-Expr in buf
|
* Parse the one disk in the XML description and add it to the S-Expr in buf
|
||||||
@ -707,10 +829,7 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
virBufferAdd(buf, "(vbd ", 5);
|
virBufferAdd(buf, "(vbd ", 5);
|
||||||
if (target[0] == '/')
|
|
||||||
virBufferVSprintf(buf, "(dev '%s')", (const char *) target);
|
virBufferVSprintf(buf, "(dev '%s')", (const char *) target);
|
||||||
else
|
|
||||||
virBufferVSprintf(buf, "(dev '/dev/%s')", (const char *) target);
|
|
||||||
if (typ == 0)
|
if (typ == 0)
|
||||||
virBufferVSprintf(buf, "(uname 'file:%s')", source);
|
virBufferVSprintf(buf, "(uname 'file:%s')", source);
|
||||||
else if (typ == 1) {
|
else if (typ == 1) {
|
||||||
@ -732,7 +851,7 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* virDomainParseXMLIfDesc:
|
* virDomainParseXMLIfDesc:
|
||||||
* @xmldesc: string with the XML description
|
* @node: node containing the interface description
|
||||||
* @buf: a buffer for the result S-Expr
|
* @buf: a buffer for the result S-Expr
|
||||||
*
|
*
|
||||||
* Parse the one interface the XML description and add it to the S-Expr in buf
|
* Parse the one interface the XML description and add it to the S-Expr in buf
|
||||||
@ -824,6 +943,7 @@ virDomainParseXMLDesc(const char *xmldesc, char **name)
|
|||||||
virBuffer buf;
|
virBuffer buf;
|
||||||
xmlChar *prop;
|
xmlChar *prop;
|
||||||
xmlXPathObjectPtr obj = NULL;
|
xmlXPathObjectPtr obj = NULL;
|
||||||
|
xmlXPathObjectPtr tmpobj = NULL;
|
||||||
xmlXPathContextPtr ctxt = NULL;
|
xmlXPathContextPtr ctxt = NULL;
|
||||||
int i, res;
|
int i, res;
|
||||||
int bootloader = 0;
|
int bootloader = 0;
|
||||||
@ -861,7 +981,7 @@ virDomainParseXMLDesc(const char *xmldesc, char **name)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* extract soem of the basics, name, memory, cpus ...
|
* extract some of the basics, name, memory, cpus ...
|
||||||
*/
|
*/
|
||||||
obj = xmlXPathEval(BAD_CAST "string(/domain/name[1])", ctxt);
|
obj = xmlXPathEval(BAD_CAST "string(/domain/name[1])", ctxt);
|
||||||
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
||||||
@ -928,14 +1048,29 @@ virDomainParseXMLDesc(const char *xmldesc, char **name)
|
|||||||
}
|
}
|
||||||
xmlXPathFreeObject(obj);
|
xmlXPathFreeObject(obj);
|
||||||
|
|
||||||
/* analyze of the os description */
|
|
||||||
obj = xmlXPathEval(BAD_CAST "/domain/os[1]", ctxt);
|
obj = xmlXPathEval(BAD_CAST "/domain/os[1]", ctxt);
|
||||||
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
||||||
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
|
||||||
res = virDomainParseXMLOSDesc(obj->nodesetval->nodeTab[0], &buf);
|
/* Analyze of the os description, based on HVM or PV. */
|
||||||
if (res != 0) {
|
tmpobj = xmlXPathEval(BAD_CAST "string(/domain/os/type[1])", ctxt);
|
||||||
|
if ((tmpobj != NULL) &&
|
||||||
|
((tmpobj->type != XPATH_STRING) || (tmpobj->stringval == NULL) ||
|
||||||
|
(tmpobj->stringval[0] == 0))) {
|
||||||
|
xmlXPathFreeObject(tmpobj);
|
||||||
|
virXMLError(VIR_ERR_OS_TYPE, nam, 0);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((tmpobj == NULL) || !xmlStrEqual(tmpobj->stringval, BAD_CAST "hvm")) {
|
||||||
|
res = virDomainParseXMLOSDescPV(obj->nodesetval->nodeTab[0], &buf);
|
||||||
|
} else {
|
||||||
|
res = virDomainParseXMLOSDescHVM(obj->nodesetval->nodeTab[0], &buf, ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlXPathFreeObject(tmpobj);
|
||||||
|
|
||||||
|
if (res != 0)
|
||||||
|
goto error;
|
||||||
} else if (bootloader == 0) {
|
} else if (bootloader == 0) {
|
||||||
virXMLError(VIR_ERR_NO_OS, nam, 0);
|
virXMLError(VIR_ERR_NO_OS, nam, 0);
|
||||||
goto error;
|
goto error;
|
||||||
|
Loading…
Reference in New Issue
Block a user