mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-03 07:33:50 +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>
|
||||
|
||||
* src/xend_internal.c: changed xenDaemonLookupByID to simply do
|
||||
an sexpr GET on /xend/domain/[ID] instead of listing all names
|
||||
and iterating over /xend/domain/[NAME]. Reduces the running time
|
||||
and number of GETs from O(n^2) to O(n).
|
||||
|
||||
* src/xend_internal.c: fixed xenDaemonOpen() to try both unix and
|
||||
|
||||
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
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* @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
|
||||
* to the one unsed for creation.
|
||||
@ -1368,6 +1435,7 @@ xend_parse_sexp_desc(struct sexpr *root)
|
||||
struct sexpr *cur, *node;
|
||||
const char *tmp;
|
||||
virBuffer buf;
|
||||
int hvm;
|
||||
|
||||
if (root == NULL) {
|
||||
/* ERROR */
|
||||
@ -1407,30 +1475,12 @@ xend_parse_sexp_desc(struct sexpr *root)
|
||||
tmp = sexpr_node(root, "domain/bootloader");
|
||||
if (tmp != NULL)
|
||||
virBufferVSprintf(&buf, " <bootloader>%s</bootloader>\n", tmp);
|
||||
|
||||
if (sexpr_lookup(root, "domain/image")) {
|
||||
tmp = sexpr_node(root, "domain/image/linux/kernel");
|
||||
if (tmp == NULL) {
|
||||
/*
|
||||
* 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);
|
||||
hvm = sexpr_lookup(root, "domain/image/hvm") ? 1 : 0;
|
||||
xend_parse_sexp_desc_os(root, &buf, hvm);
|
||||
}
|
||||
|
||||
virBufferVSprintf(&buf, " <memory>%d</memory>\n",
|
||||
(int) (sexpr_u64(root, "domain/maxmem") << 10));
|
||||
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);
|
||||
|
||||
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) {
|
||||
node = cur->car;
|
||||
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",
|
||||
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, "</domain>\n", 10);
|
||||
|
||||
|
163
src/xml.c
163
src/xml.c
@ -563,19 +563,141 @@ virDomainGetXMLDesc(virDomainPtr domain, int flags)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* virDomainParseXMLOSDesc:
|
||||
* @xmldesc: string with the XML description
|
||||
* virDomainParseXMLOSDescHVM:
|
||||
* @node: node containing HVM OS description
|
||||
* @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
|
||||
* This is a temporary interface as the S-Expr interface
|
||||
* Parse the OS part of the XML description for an HVM 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
|
||||
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;
|
||||
const xmlChar *type = NULL;
|
||||
@ -645,7 +767,7 @@ virDomainParseXMLOSDesc(xmlNodePtr node, virBufferPtr buf)
|
||||
|
||||
/**
|
||||
* virDomainParseXMLDiskDesc:
|
||||
* @xmldesc: string with the XML description
|
||||
* @node: node containing disk description
|
||||
* @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
|
||||
@ -707,10 +829,7 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
||||
return (-1);
|
||||
}
|
||||
virBufferAdd(buf, "(vbd ", 5);
|
||||
if (target[0] == '/')
|
||||
virBufferVSprintf(buf, "(dev '%s')", (const char *) target);
|
||||
else
|
||||
virBufferVSprintf(buf, "(dev '/dev/%s')", (const char *) target);
|
||||
if (typ == 0)
|
||||
virBufferVSprintf(buf, "(uname 'file:%s')", source);
|
||||
else if (typ == 1) {
|
||||
@ -732,7 +851,7 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
||||
|
||||
/**
|
||||
* virDomainParseXMLIfDesc:
|
||||
* @xmldesc: string with the XML description
|
||||
* @node: node containing the interface description
|
||||
* @buf: a buffer for the result S-Expr
|
||||
*
|
||||
* 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;
|
||||
xmlChar *prop;
|
||||
xmlXPathObjectPtr obj = NULL;
|
||||
xmlXPathObjectPtr tmpobj = NULL;
|
||||
xmlXPathContextPtr ctxt = NULL;
|
||||
int i, res;
|
||||
int bootloader = 0;
|
||||
@ -861,7 +981,7 @@ virDomainParseXMLDesc(const char *xmldesc, char **name)
|
||||
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);
|
||||
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
||||
@ -928,14 +1048,29 @@ virDomainParseXMLDesc(const char *xmldesc, char **name)
|
||||
}
|
||||
xmlXPathFreeObject(obj);
|
||||
|
||||
/* analyze of the os description */
|
||||
obj = xmlXPathEval(BAD_CAST "/domain/os[1]", ctxt);
|
||||
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
||||
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
|
||||
res = virDomainParseXMLOSDesc(obj->nodesetval->nodeTab[0], &buf);
|
||||
if (res != 0) {
|
||||
/* Analyze of the os description, based on HVM or PV. */
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
virXMLError(VIR_ERR_NO_OS, nam, 0);
|
||||
goto error;
|
||||
|
Loading…
x
Reference in New Issue
Block a user