Fixup handling of HVM boot preference, and include HVM cdrom/floppy in main device list

This commit is contained in:
Daniel P. Berrange 2006-08-11 14:40:04 +00:00
parent f87c6d4734
commit e1ec9651a2
4 changed files with 182 additions and 57 deletions

View File

@ -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
@ -25,9 +42,9 @@ Wed Aug 9 10:17:03 EDT 2006 Daniel Berrange <berrange@redhat.com>
* src/test.c, src/xen_internal.c: Added NULL entry for new
driver method for fetching XML
* src/proxy_internal.c, src/proxy_internal.h, proxy/libvirt_proxy.c:
Added implmentation of virDomainGetXMLDesc driver method which
Added implmentation of virDomainGetXMLDesc driver method which
goes via proxy.
Tue Aug 8 23:24:51 CEST 2006 Daniel Veillard <veillard@redhat.com>
* src/driver.h src/libvirt.c src/proxy_internal.c src/test.c
@ -38,14 +55,14 @@ Tue Aug 8 23:24:51 CEST 2006 Daniel Veillard <veillard@redhat.com>
Mon Aug 7 18:33:45 EDT 2006 Daniel Berrange <berrange@redhat.com>
* src/xend_internal.c: Added details of serial console TTY to XML
* src/xend_internal.c: Added details of serial console TTY to XML
representation of domain. Fetch VNC port from xenstore if it is
available (only in xen 3.0.3 or later).
* src/xs_internal.c, src/xs_internal.h: Added APIs for retrieving
the serial console TTY and VNC server port from xenstore.
* docs/libvir.html: Document 'port' attribute for VNC graphics,
and '<console>' element for serial console.
Mon Aug 7 21:57:41 CEST 2006 Daniel Veillard <veillard@redhat.com>
* TODO: updated with new items
@ -60,7 +77,7 @@ Mon Aug 7 11:06:20 EDT 2006 Daniel Berrange <berrange@redhat.com>
* src/xend_internal.c: Added a 'port' attribute to the '<graphics>'
tag when display type is VNC, providing the port number on which
the VNC server is listening.
Mon Aug 7 18:47:48 CEST 2006 Daniel Veillard <veillard@redhat.com>
* include/libvirt/libvirt.h.in: previous change to libvirt.h should
@ -70,10 +87,10 @@ Fri Aug 4 20:19:23 EDT 2006 Daniel Berrange <berrange@redhat.com>
* src/libvirt.c: Fix off-by-one in validated VCPU number (it is
zero based, not one based).
* include/libvirt/libvirt.h: Add some convenience macros for
* include/libvirt/libvirt.h: Add some convenience macros for
calculating neccessary CPU map lengths & total host CPUs
* src/virsh.c: Add 'vcpuinfo' and 'vcpumap' commands
Fri Aug 4 14:45:25 CEST 2006 Daniel Veillard <veillard@redhat.com>
* python/generator.py: fix the generator when handling long integers

View File

@ -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);
}
/**

View File

@ -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
View File

@ -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);