mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 19:11:16 +00:00
Fixup handling of HVM boot preference, and include HVM cdrom/floppy in main device list
This commit is contained in:
parent
f87c6d4734
commit
e1ec9651a2
17
ChangeLog
17
ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
Fri Aug 11 09:37:02 EDT 2006 Daniel Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
* src/libvirt.c: Avoid duplicated attempts to shutdown or
|
||||||
|
pause a domain if the first attempt succeeded.
|
||||||
|
* src/xend_internal.c, src/xml.c: When parsing UUID from
|
||||||
|
SEXPR also allow for format without any embedded '-'. The
|
||||||
|
ioemu: prefix is no longer required for HVM domains. It is
|
||||||
|
added when generating SEXPR, and removing when parsing SEXPR
|
||||||
|
never appearing in XML. CDROM & floppy devices for HVM domains
|
||||||
|
are now included in XML under <devices><disk> tag. The <disk>
|
||||||
|
tag now has a 'device' attribute allowing one of 'floppy',
|
||||||
|
'cdrom', 'disk' to be specified. If the <console> tag is present
|
||||||
|
in XML, HVM domains get a serial console activated. <boot>
|
||||||
|
tag now expects one of 'fd' 'hd' or 'cdrom' when specifying
|
||||||
|
boot device preference. Increased size of XML doc buffer from
|
||||||
|
1k to 4k to deal with large numbers of devices
|
||||||
|
|
||||||
Fri Aug 11 13:08:01 CEST 2006 Daniel Veillard <veillard@redhat.com>
|
Fri Aug 11 13:08:01 CEST 2006 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* configure.in: updated python detection code from latest libxml2 one
|
* configure.in: updated python detection code from latest libxml2 one
|
||||||
|
@ -720,7 +720,7 @@ virDomainLookupByName(virConnectPtr conn, const char *name)
|
|||||||
int
|
int
|
||||||
virDomainDestroy(virDomainPtr domain)
|
virDomainDestroy(virDomainPtr domain)
|
||||||
{
|
{
|
||||||
int ret = -1, i;
|
int i;
|
||||||
virConnectPtr conn;
|
virConnectPtr conn;
|
||||||
|
|
||||||
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||||
@ -743,7 +743,7 @@ virDomainDestroy(virDomainPtr domain)
|
|||||||
(conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) &&
|
(conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) &&
|
||||||
(conn->drivers[i]->domainDestroy != NULL)) {
|
(conn->drivers[i]->domainDestroy != NULL)) {
|
||||||
if (conn->drivers[i]->domainDestroy(domain) == 0)
|
if (conn->drivers[i]->domainDestroy(domain) == 0)
|
||||||
ret = 0;
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0;i < conn->nb_drivers;i++) {
|
for (i = 0;i < conn->nb_drivers;i++) {
|
||||||
@ -751,16 +751,12 @@ virDomainDestroy(virDomainPtr domain)
|
|||||||
(conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) &&
|
(conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) &&
|
||||||
(conn->drivers[i]->domainDestroy != NULL)) {
|
(conn->drivers[i]->domainDestroy != NULL)) {
|
||||||
if (conn->drivers[i]->domainDestroy(domain) == 0)
|
if (conn->drivers[i]->domainDestroy(domain) == 0)
|
||||||
ret = 0;
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
|
virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
|
||||||
return (ret);
|
return (-1);
|
||||||
}
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -799,7 +795,7 @@ virDomainFree(virDomainPtr domain)
|
|||||||
int
|
int
|
||||||
virDomainSuspend(virDomainPtr domain)
|
virDomainSuspend(virDomainPtr domain)
|
||||||
{
|
{
|
||||||
int ret = -1, i;
|
int i;
|
||||||
virConnectPtr conn;
|
virConnectPtr conn;
|
||||||
|
|
||||||
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||||
@ -822,7 +818,7 @@ virDomainSuspend(virDomainPtr domain)
|
|||||||
(conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) &&
|
(conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) &&
|
||||||
(conn->drivers[i]->domainSuspend != NULL)) {
|
(conn->drivers[i]->domainSuspend != NULL)) {
|
||||||
if (conn->drivers[i]->domainSuspend(domain) == 0)
|
if (conn->drivers[i]->domainSuspend(domain) == 0)
|
||||||
ret = 0;
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0;i < conn->nb_drivers;i++) {
|
for (i = 0;i < conn->nb_drivers;i++) {
|
||||||
@ -830,16 +826,12 @@ virDomainSuspend(virDomainPtr domain)
|
|||||||
(conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) &&
|
(conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) &&
|
||||||
(conn->drivers[i]->domainSuspend != NULL)) {
|
(conn->drivers[i]->domainSuspend != NULL)) {
|
||||||
if (conn->drivers[i]->domainSuspend(domain) == 0)
|
if (conn->drivers[i]->domainSuspend(domain) == 0)
|
||||||
ret = 0;
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
|
virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
|
||||||
return (ret);
|
return (-1);
|
||||||
}
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -790,6 +790,18 @@ sexpr_uuid(char **ptr, struct sexpr *node, const char *path)
|
|||||||
if (r == NULL)
|
if (r == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
ret = sscanf(r,
|
||||||
|
"%02x%02x%02x%02x"
|
||||||
|
"%02x%02x%02x%02x"
|
||||||
|
"%02x%02x%02x%02x"
|
||||||
|
"%02x%02x%02x%02x",
|
||||||
|
uuid + 0, uuid + 1, uuid + 2, uuid + 3,
|
||||||
|
uuid + 4, uuid + 5, uuid + 6, uuid + 7,
|
||||||
|
uuid + 8, uuid + 9, uuid + 10, uuid + 11,
|
||||||
|
uuid + 12, uuid + 13, uuid + 14, uuid + 15);
|
||||||
|
if (ret == 16)
|
||||||
|
goto done;
|
||||||
|
|
||||||
ret = sscanf(r,
|
ret = sscanf(r,
|
||||||
"%02x%02x%02x%02x-"
|
"%02x%02x%02x%02x-"
|
||||||
"%02x%02x-"
|
"%02x%02x-"
|
||||||
@ -1416,21 +1428,19 @@ xend_parse_sexp_desc_os(struct sexpr *node, virBufferPtr buf, int hvm)
|
|||||||
virBufferVSprintf(buf, " <loader>%s</loader>\n", tmp);
|
virBufferVSprintf(buf, " <loader>%s</loader>\n", tmp);
|
||||||
tmp = sexpr_node(node, "domain/image/hvm/boot");
|
tmp = sexpr_node(node, "domain/image/hvm/boot");
|
||||||
if ((tmp != NULL) && (tmp[0] != 0)) {
|
if ((tmp != NULL) && (tmp[0] != 0)) {
|
||||||
/*
|
|
||||||
* FIXME:
|
|
||||||
* Figure out how to map the 'a', 'b', 'c' nonsense to a
|
|
||||||
* device.
|
|
||||||
*/
|
|
||||||
if (tmp[0] == 'a')
|
if (tmp[0] == 'a')
|
||||||
virBufferAdd(buf, " <boot dev='/dev/fd0'/>\n", 25 );
|
/* XXX no way to deal with boot from 2nd floppy */
|
||||||
|
virBufferAdd(buf, " <boot dev='fd'/>\n", 21 );
|
||||||
else if (tmp[0] == 'c')
|
else if (tmp[0] == 'c')
|
||||||
/*
|
/*
|
||||||
* Don't know what to put here. Say the vm has been given 3
|
* 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?
|
* disks - hda, hdb, hdc. How does one identify the boot disk?
|
||||||
|
* We're going to assume that first disk is the boot disk since
|
||||||
|
* this is most common practice
|
||||||
*/
|
*/
|
||||||
virBufferAdd(buf, " <boot dev='hda'/>\n", 22 );
|
virBufferAdd(buf, " <boot dev='hd'/>\n", 21 );
|
||||||
else if (strcmp(tmp, "d") == 0)
|
else if (strcmp(tmp, "d") == 0)
|
||||||
virBufferAdd(buf, " <boot dev='/dev/cdrom'/>\n", 29 );
|
virBufferAdd(buf, " <boot dev='cdrom'/>\n", 24 );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
virBufferVSprintf(buf, " <type>linux</type>\n");
|
virBufferVSprintf(buf, " <type>linux</type>\n");
|
||||||
@ -1482,11 +1492,11 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
|||||||
/* ERROR */
|
/* ERROR */
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
ret = malloc(1000);
|
ret = malloc(4000);
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
buf.content = ret;
|
buf.content = ret;
|
||||||
buf.size = 1000;
|
buf.size = 4000;
|
||||||
buf.use = 0;
|
buf.use = 0;
|
||||||
|
|
||||||
domid = sexpr_int(root, "domain/domid");
|
domid = sexpr_int(root, "domain/domid");
|
||||||
@ -1552,7 +1562,7 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
|||||||
continue;
|
continue;
|
||||||
if (!memcmp(tmp, "file:", 5)) {
|
if (!memcmp(tmp, "file:", 5)) {
|
||||||
tmp += 5;
|
tmp += 5;
|
||||||
virBufferVSprintf(&buf, " <disk type='file'>\n");
|
virBufferVSprintf(&buf, " <disk type='file' device='disk'>\n");
|
||||||
virBufferVSprintf(&buf, " <source file='%s'/>\n",
|
virBufferVSprintf(&buf, " <source file='%s'/>\n",
|
||||||
tmp);
|
tmp);
|
||||||
tmp = sexpr_node(node, "device/vbd/dev");
|
tmp = sexpr_node(node, "device/vbd/dev");
|
||||||
@ -1561,6 +1571,8 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
|||||||
"domain information incomplete, vbd has no dev");
|
"domain information incomplete, vbd has no dev");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (!strncmp(tmp, "ioemu:", 6))
|
||||||
|
tmp += 6;
|
||||||
virBufferVSprintf(&buf, " <target dev='%s'/>\n", tmp);
|
virBufferVSprintf(&buf, " <target dev='%s'/>\n", tmp);
|
||||||
tmp = sexpr_node(node, "device/vbd/mode");
|
tmp = sexpr_node(node, "device/vbd/mode");
|
||||||
if ((tmp != NULL) && (!strcmp(tmp, "r")))
|
if ((tmp != NULL) && (!strcmp(tmp, "r")))
|
||||||
@ -1568,7 +1580,7 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
|||||||
virBufferAdd(&buf, " </disk>\n", 12);
|
virBufferAdd(&buf, " </disk>\n", 12);
|
||||||
} else if (!memcmp(tmp, "phy:", 4)) {
|
} else if (!memcmp(tmp, "phy:", 4)) {
|
||||||
tmp += 4;
|
tmp += 4;
|
||||||
virBufferVSprintf(&buf, " <disk type='block'>\n");
|
virBufferVSprintf(&buf, " <disk type='block' device='disk'>\n");
|
||||||
virBufferVSprintf(&buf, " <source dev='%s'/>\n", tmp);
|
virBufferVSprintf(&buf, " <source dev='%s'/>\n", tmp);
|
||||||
tmp = sexpr_node(node, "device/vbd/dev");
|
tmp = sexpr_node(node, "device/vbd/dev");
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
@ -1576,6 +1588,8 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
|||||||
"domain information incomplete, vbd has no dev");
|
"domain information incomplete, vbd has no dev");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (!strncmp(tmp, "ioemu:", 6))
|
||||||
|
tmp += 6;
|
||||||
virBufferVSprintf(&buf, " <target dev='%s'/>\n", tmp);
|
virBufferVSprintf(&buf, " <target dev='%s'/>\n", tmp);
|
||||||
tmp = sexpr_node(node, "device/vbd/mode");
|
tmp = sexpr_node(node, "device/vbd/mode");
|
||||||
if ((tmp != NULL) && (!strcmp(tmp, "r")))
|
if ((tmp != NULL) && (!strcmp(tmp, "r")))
|
||||||
@ -1625,6 +1639,30 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hvm) {
|
if (hvm) {
|
||||||
|
tmp = sexpr_node(root, "domain/image/hvm/fda");
|
||||||
|
if ((tmp != NULL) && (tmp[0] != 0)) {
|
||||||
|
virBufferAdd(&buf, " <disk type='file' device='floppy'>\n", 39);
|
||||||
|
virBufferVSprintf(&buf, " <source file='%s'/>\n", tmp);
|
||||||
|
virBufferAdd(&buf, " <target dev='fda'/>\n", 26);
|
||||||
|
virBufferAdd(&buf, " </disk>\n", 12);
|
||||||
|
}
|
||||||
|
tmp = sexpr_node(root, "domain/image/hvm/fdb");
|
||||||
|
if ((tmp != NULL) && (tmp[0] != 0)) {
|
||||||
|
virBufferAdd(&buf, " <disk type='file' device='floppy'>\n", 39);
|
||||||
|
virBufferVSprintf(&buf, " <source file='%s'/>\n", tmp);
|
||||||
|
virBufferAdd(&buf, " <target dev='fdb'/>\n", 26);
|
||||||
|
virBufferAdd(&buf, " </disk>\n", 12);
|
||||||
|
}
|
||||||
|
/* XXX new (3.0.3) Xend puts cdrom devs in usual (devices) block */
|
||||||
|
tmp = sexpr_node(root, "domain/image/hvm/cdrom");
|
||||||
|
if ((tmp != NULL) && (tmp[0] != 0)) {
|
||||||
|
virBufferAdd(&buf, " <disk type='file' device='cdrom'>\n", 38);
|
||||||
|
virBufferVSprintf(&buf, " <source file='%s'/>\n", tmp);
|
||||||
|
virBufferAdd(&buf, " <target dev='hdc'/>\n", 26);
|
||||||
|
virBufferAdd(&buf, " <readonly/>\n", 18);
|
||||||
|
virBufferAdd(&buf, " </disk>\n", 12);
|
||||||
|
}
|
||||||
|
|
||||||
/* Graphics device */
|
/* Graphics device */
|
||||||
tmp = sexpr_node(root, "domain/image/hvm/vnc");
|
tmp = sexpr_node(root, "domain/image/hvm/vnc");
|
||||||
if (tmp != NULL) {
|
if (tmp != NULL) {
|
||||||
@ -1641,11 +1679,6 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
|||||||
if (tmp[0] == '1')
|
if (tmp[0] == '1')
|
||||||
virBufferAdd(&buf, " <graphics type='sdl'/>\n", 27 );
|
virBufferAdd(&buf, " <graphics type='sdl'/>\n", 27 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO:
|
|
||||||
* Device for cdrom
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tty = xenStoreDomainGetConsolePath(conn, domid);
|
tty = xenStoreDomainGetConsolePath(conn, domid);
|
||||||
|
117
src/xml.c
117
src/xml.c
@ -268,7 +268,10 @@ virDomainGetXMLDevice(virDomainPtr domain, virBufferPtr buf, long dev)
|
|||||||
}
|
}
|
||||||
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "dev");
|
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "dev");
|
||||||
if (val != NULL) {
|
if (val != NULL) {
|
||||||
virBufferVSprintf(buf, " <target dev='%s'/>\n", val);
|
char *tmp = val;
|
||||||
|
if (!strncmp(tmp, "ioemu:", 6))
|
||||||
|
tmp += 6;
|
||||||
|
virBufferVSprintf(buf, " <target dev='%s'/>\n", tmp);
|
||||||
free(val);
|
free(val);
|
||||||
}
|
}
|
||||||
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "read-only");
|
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "read-only");
|
||||||
@ -286,7 +289,10 @@ virDomainGetXMLDevice(virDomainPtr domain, virBufferPtr buf, long dev)
|
|||||||
}
|
}
|
||||||
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "dev");
|
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "dev");
|
||||||
if (val != NULL) {
|
if (val != NULL) {
|
||||||
virBufferVSprintf(buf, " <target dev='%s'/>\n", val);
|
char *tmp = val;
|
||||||
|
if (!strncmp(tmp, "ioemu:", 6))
|
||||||
|
tmp += 6;
|
||||||
|
virBufferVSprintf(buf, " <target dev='%s'/>\n", tmp);
|
||||||
free(val);
|
free(val);
|
||||||
}
|
}
|
||||||
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "read-only");
|
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "read-only");
|
||||||
@ -635,22 +641,72 @@ virDomainParseXMLOSDescHVM(xmlNodePtr node, virBufferPtr buf, xmlXPathContextPtr
|
|||||||
obj = NULL;
|
obj = NULL;
|
||||||
|
|
||||||
if (boot_dev) {
|
if (boot_dev) {
|
||||||
/* TODO:
|
if (xmlStrEqual(boot_dev, BAD_CAST "fd")) {
|
||||||
* Have to figure out the naming used here.
|
|
||||||
*/
|
|
||||||
if (xmlStrEqual(type, BAD_CAST "hda")) {
|
|
||||||
virBufferVSprintf(buf, "(boot a)", (const char *) boot_dev);
|
virBufferVSprintf(buf, "(boot a)", (const char *) boot_dev);
|
||||||
} else if (xmlStrEqual(type, BAD_CAST "hdd")) {
|
} else if (xmlStrEqual(boot_dev, BAD_CAST "cdrom")) {
|
||||||
virBufferVSprintf(buf, "(boot d)", (const char *) boot_dev);
|
virBufferVSprintf(buf, "(boot d)", (const char *) boot_dev);
|
||||||
} else {
|
} else if (xmlStrEqual(boot_dev, BAD_CAST "hd")) {
|
||||||
/* Force hd[b|c] if boot_dev specified but not floppy or cdrom? */
|
|
||||||
virBufferVSprintf(buf, "(boot c)", (const char *) boot_dev);
|
virBufferVSprintf(buf, "(boot c)", (const char *) boot_dev);
|
||||||
|
} else {
|
||||||
|
/* Any other type of boot dev is unsupported right now */
|
||||||
|
virXMLError(VIR_ERR_XML_ERROR, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the 1st floppy device file */
|
||||||
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/disk[@device='floppy' and target/@dev='fda']/source", ctxt);
|
||||||
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
||||||
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
|
||||||
|
cur = obj->nodesetval->nodeTab[0];
|
||||||
|
virBufferVSprintf(buf, "(fda '%s')",
|
||||||
|
(const char *) xmlGetProp(cur, BAD_CAST "file"));
|
||||||
|
cur = NULL;
|
||||||
|
}
|
||||||
|
if (obj) {
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
obj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the 2nd floppy device file */
|
||||||
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/disk[@device='floppy' and target/@dev='fdb']/source", ctxt);
|
||||||
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
||||||
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
|
||||||
|
cur = obj->nodesetval->nodeTab[0];
|
||||||
|
virBufferVSprintf(buf, "(fdb '%s')",
|
||||||
|
(const char *) xmlGetProp(cur, BAD_CAST "file"));
|
||||||
|
cur = NULL;
|
||||||
|
}
|
||||||
|
if (obj) {
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
obj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* get the cdrom device file */
|
||||||
|
/* XXX new (3.0.3) Xend puts cdrom devs in usual (devices) block */
|
||||||
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/disk[@device='cdrom' and target/@dev='hdc']/source", ctxt);
|
||||||
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
||||||
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) {
|
||||||
|
cur = obj->nodesetval->nodeTab[0];
|
||||||
|
virBufferVSprintf(buf, "(cdrom '%s')",
|
||||||
|
(const char *) xmlGetProp(cur, BAD_CAST "file"));
|
||||||
|
cur = NULL;
|
||||||
|
}
|
||||||
|
if (obj) {
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
obj = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* TODO:
|
|
||||||
* Is a cdrom disk device specified?
|
obj = xmlXPathEval(BAD_CAST "count(domain/devices/console) > 0", ctxt);
|
||||||
* Kind of ugly since it is buried in the devices/diskk node.
|
if ((obj == NULL) || (obj->type != XPATH_BOOLEAN)) {
|
||||||
*/
|
virXMLError(VIR_ERR_XML_ERROR, NULL, 0);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (obj->boolval) {
|
||||||
|
virBufferAdd(buf, "(serial pty)", 12);
|
||||||
|
}
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
obj = NULL;
|
||||||
|
|
||||||
/* Is a graphics device specified? */
|
/* Is a graphics device specified? */
|
||||||
obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics[1]", ctxt);
|
obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics[1]", ctxt);
|
||||||
@ -779,10 +835,11 @@ virDomainParseXMLOSDescPV(xmlNodePtr node, virBufferPtr buf)
|
|||||||
* 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
|
||||||
virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf, int hvm)
|
||||||
{
|
{
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
xmlChar *type = NULL;
|
xmlChar *type = NULL;
|
||||||
|
xmlChar *device = NULL;
|
||||||
xmlChar *source = NULL;
|
xmlChar *source = NULL;
|
||||||
xmlChar *target = NULL;
|
xmlChar *target = NULL;
|
||||||
int ro = 0;
|
int ro = 0;
|
||||||
@ -796,6 +853,8 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
|||||||
typ = 1;
|
typ = 1;
|
||||||
xmlFree(type);
|
xmlFree(type);
|
||||||
}
|
}
|
||||||
|
device = xmlGetProp(node, BAD_CAST "device");
|
||||||
|
|
||||||
cur = node->children;
|
cur = node->children;
|
||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
if (cur->type == XML_ELEMENT_NODE) {
|
if (cur->type == XML_ELEMENT_NODE) {
|
||||||
@ -829,7 +888,29 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
|||||||
xmlFree(source);
|
xmlFree(source);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip floppy/cdrom disk used as the boot device
|
||||||
|
* since that's incorporated into the HVM kernel
|
||||||
|
* (image (hvm..)) part of the sexpr, rather than
|
||||||
|
* the (devices...) bit. Odd Xend HVM config :-(
|
||||||
|
* XXX This will have to change in Xen 3.0.3
|
||||||
|
*/
|
||||||
|
if (hvm && device &&
|
||||||
|
(!strcmp((const char *)device, "floppy") ||
|
||||||
|
!strcmp((const char *)device, "cdrom"))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virBufferAdd(buf, "(device ", 8);
|
||||||
virBufferAdd(buf, "(vbd ", 5);
|
virBufferAdd(buf, "(vbd ", 5);
|
||||||
|
/* XXX ioemu prefix is going away in Xen 3.0.3 */
|
||||||
|
if (hvm) {
|
||||||
|
char *tmp = (char *)target;
|
||||||
|
if (!strncmp((const char *) tmp, "ioemu:", 6))
|
||||||
|
tmp += 6;
|
||||||
|
virBufferVSprintf(buf, "(dev 'ioemu:%s')", (const char *) tmp);
|
||||||
|
} else
|
||||||
virBufferVSprintf(buf, "(dev '%s')", (const char *) target);
|
virBufferVSprintf(buf, "(dev '%s')", (const char *) target);
|
||||||
if (typ == 0)
|
if (typ == 0)
|
||||||
virBufferVSprintf(buf, "(uname 'file:%s')", source);
|
virBufferVSprintf(buf, "(uname 'file:%s')", source);
|
||||||
@ -844,6 +925,7 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
|||||||
else if (ro == 1)
|
else if (ro == 1)
|
||||||
virBufferVSprintf(buf, "(mode 'r')");
|
virBufferVSprintf(buf, "(mode 'r')");
|
||||||
|
|
||||||
|
virBufferAdd(buf, ")", 1);
|
||||||
virBufferAdd(buf, ")", 1);
|
virBufferAdd(buf, ")", 1);
|
||||||
xmlFree(target);
|
xmlFree(target);
|
||||||
xmlFree(source);
|
xmlFree(source);
|
||||||
@ -912,6 +994,7 @@ virDomainParseXMLIfDesc(xmlNodePtr node, virBufferPtr buf)
|
|||||||
}
|
}
|
||||||
if (script != NULL)
|
if (script != NULL)
|
||||||
virBufferVSprintf(buf, "(script '%s')", script);
|
virBufferVSprintf(buf, "(script '%s')", script);
|
||||||
|
virBufferAdd(buf, "(type ioemu)", 12);
|
||||||
|
|
||||||
virBufferAdd(buf, ")", 1);
|
virBufferAdd(buf, ")", 1);
|
||||||
if (mac != NULL)
|
if (mac != NULL)
|
||||||
@ -948,6 +1031,7 @@ virDomainParseXMLDesc(const char *xmldesc, char **name)
|
|||||||
xmlXPathContextPtr ctxt = NULL;
|
xmlXPathContextPtr ctxt = NULL;
|
||||||
int i, res;
|
int i, res;
|
||||||
int bootloader = 0;
|
int bootloader = 0;
|
||||||
|
int hvm = 0;
|
||||||
|
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
*name = NULL;
|
*name = NULL;
|
||||||
@ -1072,6 +1156,7 @@ virDomainParseXMLDesc(const char *xmldesc, char **name)
|
|||||||
if ((tmpobj == NULL) || !xmlStrEqual(tmpobj->stringval, BAD_CAST "hvm")) {
|
if ((tmpobj == NULL) || !xmlStrEqual(tmpobj->stringval, BAD_CAST "hvm")) {
|
||||||
res = virDomainParseXMLOSDescPV(obj->nodesetval->nodeTab[0], &buf);
|
res = virDomainParseXMLOSDescPV(obj->nodesetval->nodeTab[0], &buf);
|
||||||
} else {
|
} else {
|
||||||
|
hvm = 1;
|
||||||
res = virDomainParseXMLOSDescHVM(obj->nodesetval->nodeTab[0], &buf, ctxt);
|
res = virDomainParseXMLOSDescHVM(obj->nodesetval->nodeTab[0], &buf, ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1090,12 +1175,10 @@ virDomainParseXMLDesc(const char *xmldesc, char **name)
|
|||||||
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
|
||||||
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
|
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
|
||||||
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
||||||
virBufferAdd(&buf, "(device ", 8);
|
res = virDomainParseXMLDiskDesc(obj->nodesetval->nodeTab[i], &buf, hvm);
|
||||||
res = virDomainParseXMLDiskDesc(obj->nodesetval->nodeTab[i], &buf);
|
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
virBufferAdd(&buf, ")", 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xmlXPathFreeObject(obj);
|
xmlXPathFreeObject(obj);
|
||||||
|
Loading…
Reference in New Issue
Block a user