mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 11:35:19 +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>
|
||||
|
||||
* configure.in: updated python detection code from latest libxml2 one
|
||||
|
@ -720,7 +720,7 @@ virDomainLookupByName(virConnectPtr conn, const char *name)
|
||||
int
|
||||
virDomainDestroy(virDomainPtr domain)
|
||||
{
|
||||
int ret = -1, i;
|
||||
int i;
|
||||
virConnectPtr conn;
|
||||
|
||||
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||
@ -743,7 +743,7 @@ virDomainDestroy(virDomainPtr domain)
|
||||
(conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) &&
|
||||
(conn->drivers[i]->domainDestroy != NULL)) {
|
||||
if (conn->drivers[i]->domainDestroy(domain) == 0)
|
||||
ret = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
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]->domainDestroy != NULL)) {
|
||||
if (conn->drivers[i]->domainDestroy(domain) == 0)
|
||||
ret = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -799,7 +795,7 @@ virDomainFree(virDomainPtr domain)
|
||||
int
|
||||
virDomainSuspend(virDomainPtr domain)
|
||||
{
|
||||
int ret = -1, i;
|
||||
int i;
|
||||
virConnectPtr conn;
|
||||
|
||||
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
|
||||
@ -822,7 +818,7 @@ virDomainSuspend(virDomainPtr domain)
|
||||
(conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) &&
|
||||
(conn->drivers[i]->domainSuspend != NULL)) {
|
||||
if (conn->drivers[i]->domainSuspend(domain) == 0)
|
||||
ret = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
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]->domainSuspend != NULL)) {
|
||||
if (conn->drivers[i]->domainSuspend(domain) == 0)
|
||||
ret = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -790,6 +790,18 @@ sexpr_uuid(char **ptr, struct sexpr *node, const char *path)
|
||||
if (r == NULL)
|
||||
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,
|
||||
"%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);
|
||||
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 );
|
||||
/* XXX no way to deal with boot from 2nd floppy */
|
||||
virBufferAdd(buf, " <boot dev='fd'/>\n", 21 );
|
||||
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?
|
||||
* 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)
|
||||
virBufferAdd(buf, " <boot dev='/dev/cdrom'/>\n", 29 );
|
||||
virBufferAdd(buf, " <boot dev='cdrom'/>\n", 24 );
|
||||
}
|
||||
} else {
|
||||
virBufferVSprintf(buf, " <type>linux</type>\n");
|
||||
@ -1482,11 +1492,11 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
||||
/* ERROR */
|
||||
return (NULL);
|
||||
}
|
||||
ret = malloc(1000);
|
||||
ret = malloc(4000);
|
||||
if (ret == NULL)
|
||||
return (NULL);
|
||||
buf.content = ret;
|
||||
buf.size = 1000;
|
||||
buf.size = 4000;
|
||||
buf.use = 0;
|
||||
|
||||
domid = sexpr_int(root, "domain/domid");
|
||||
@ -1552,7 +1562,7 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
||||
continue;
|
||||
if (!memcmp(tmp, "file:", 5)) {
|
||||
tmp += 5;
|
||||
virBufferVSprintf(&buf, " <disk type='file'>\n");
|
||||
virBufferVSprintf(&buf, " <disk type='file' device='disk'>\n");
|
||||
virBufferVSprintf(&buf, " <source file='%s'/>\n",
|
||||
tmp);
|
||||
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");
|
||||
goto error;
|
||||
}
|
||||
if (!strncmp(tmp, "ioemu:", 6))
|
||||
tmp += 6;
|
||||
virBufferVSprintf(&buf, " <target dev='%s'/>\n", tmp);
|
||||
tmp = sexpr_node(node, "device/vbd/mode");
|
||||
if ((tmp != NULL) && (!strcmp(tmp, "r")))
|
||||
@ -1568,7 +1580,7 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
||||
virBufferAdd(&buf, " </disk>\n", 12);
|
||||
} else if (!memcmp(tmp, "phy:", 4)) {
|
||||
tmp += 4;
|
||||
virBufferVSprintf(&buf, " <disk type='block'>\n");
|
||||
virBufferVSprintf(&buf, " <disk type='block' device='disk'>\n");
|
||||
virBufferVSprintf(&buf, " <source dev='%s'/>\n", tmp);
|
||||
tmp = sexpr_node(node, "device/vbd/dev");
|
||||
if (tmp == NULL) {
|
||||
@ -1576,6 +1588,8 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
||||
"domain information incomplete, vbd has no dev");
|
||||
goto error;
|
||||
}
|
||||
if (!strncmp(tmp, "ioemu:", 6))
|
||||
tmp += 6;
|
||||
virBufferVSprintf(&buf, " <target dev='%s'/>\n", tmp);
|
||||
tmp = sexpr_node(node, "device/vbd/mode");
|
||||
if ((tmp != NULL) && (!strcmp(tmp, "r")))
|
||||
@ -1625,6 +1639,30 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
||||
}
|
||||
|
||||
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 */
|
||||
tmp = sexpr_node(root, "domain/image/hvm/vnc");
|
||||
if (tmp != NULL) {
|
||||
@ -1641,11 +1679,6 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root)
|
||||
if (tmp[0] == '1')
|
||||
virBufferAdd(&buf, " <graphics type='sdl'/>\n", 27 );
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* Device for cdrom
|
||||
*/
|
||||
}
|
||||
|
||||
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");
|
||||
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);
|
||||
}
|
||||
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "read-only");
|
||||
@ -286,7 +289,10 @@ virDomainGetXMLDevice(virDomainPtr domain, virBufferPtr buf, long dev)
|
||||
}
|
||||
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "dev");
|
||||
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);
|
||||
}
|
||||
val = virDomainGetXMLDeviceInfo(domain, "vbd", dev, "read-only");
|
||||
@ -635,22 +641,72 @@ virDomainParseXMLOSDescHVM(xmlNodePtr node, virBufferPtr buf, xmlXPathContextPtr
|
||||
obj = NULL;
|
||||
|
||||
if (boot_dev) {
|
||||
/* TODO:
|
||||
* Have to figure out the naming used here.
|
||||
*/
|
||||
if (xmlStrEqual(type, BAD_CAST "hda")) {
|
||||
if (xmlStrEqual(boot_dev, BAD_CAST "fd")) {
|
||||
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);
|
||||
} else {
|
||||
/* Force hd[b|c] if boot_dev specified but not floppy or cdrom? */
|
||||
} else if (xmlStrEqual(boot_dev, BAD_CAST "hd")) {
|
||||
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?
|
||||
* Kind of ugly since it is buried in the devices/diskk node.
|
||||
*/
|
||||
|
||||
obj = xmlXPathEval(BAD_CAST "count(domain/devices/console) > 0", ctxt);
|
||||
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? */
|
||||
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.
|
||||
*/
|
||||
static int
|
||||
virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
||||
virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf, int hvm)
|
||||
{
|
||||
xmlNodePtr cur;
|
||||
xmlChar *type = NULL;
|
||||
xmlChar *device = NULL;
|
||||
xmlChar *source = NULL;
|
||||
xmlChar *target = NULL;
|
||||
int ro = 0;
|
||||
@ -796,6 +853,8 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
||||
typ = 1;
|
||||
xmlFree(type);
|
||||
}
|
||||
device = xmlGetProp(node, BAD_CAST "device");
|
||||
|
||||
cur = node->children;
|
||||
while (cur != NULL) {
|
||||
if (cur->type == XML_ELEMENT_NODE) {
|
||||
@ -829,7 +888,29 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
||||
xmlFree(source);
|
||||
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);
|
||||
/* 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);
|
||||
if (typ == 0)
|
||||
virBufferVSprintf(buf, "(uname 'file:%s')", source);
|
||||
@ -844,6 +925,7 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf)
|
||||
else if (ro == 1)
|
||||
virBufferVSprintf(buf, "(mode 'r')");
|
||||
|
||||
virBufferAdd(buf, ")", 1);
|
||||
virBufferAdd(buf, ")", 1);
|
||||
xmlFree(target);
|
||||
xmlFree(source);
|
||||
@ -912,6 +994,7 @@ virDomainParseXMLIfDesc(xmlNodePtr node, virBufferPtr buf)
|
||||
}
|
||||
if (script != NULL)
|
||||
virBufferVSprintf(buf, "(script '%s')", script);
|
||||
virBufferAdd(buf, "(type ioemu)", 12);
|
||||
|
||||
virBufferAdd(buf, ")", 1);
|
||||
if (mac != NULL)
|
||||
@ -948,6 +1031,7 @@ virDomainParseXMLDesc(const char *xmldesc, char **name)
|
||||
xmlXPathContextPtr ctxt = NULL;
|
||||
int i, res;
|
||||
int bootloader = 0;
|
||||
int hvm = 0;
|
||||
|
||||
if (name != NULL)
|
||||
*name = NULL;
|
||||
@ -1072,6 +1156,7 @@ virDomainParseXMLDesc(const char *xmldesc, char **name)
|
||||
if ((tmpobj == NULL) || !xmlStrEqual(tmpobj->stringval, BAD_CAST "hvm")) {
|
||||
res = virDomainParseXMLOSDescPV(obj->nodesetval->nodeTab[0], &buf);
|
||||
} else {
|
||||
hvm = 1;
|
||||
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) &&
|
||||
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
|
||||
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
||||
virBufferAdd(&buf, "(device ", 8);
|
||||
res = virDomainParseXMLDiskDesc(obj->nodesetval->nodeTab[i], &buf);
|
||||
res = virDomainParseXMLDiskDesc(obj->nodesetval->nodeTab[i], &buf, hvm);
|
||||
if (res != 0) {
|
||||
goto error;
|
||||
}
|
||||
virBufferAdd(&buf, ")", 1);
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(obj);
|
||||
|
Loading…
Reference in New Issue
Block a user