+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
* 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
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
* 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
* 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
int
virDomainDestroy(virDomainPtr domain)
{
- int ret = -1, i;
+ int i;
virConnectPtr conn;
if (!VIR_IS_CONNECTED_DOMAIN(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++) {
(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);
}
/**
int
virDomainSuspend(virDomainPtr domain)
{
- int ret = -1, i;
+ int i;
virConnectPtr conn;
if (!VIR_IS_CONNECTED_DOMAIN(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++) {
(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);
}
/**
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-"
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");
/* 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");
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");
"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")))
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) {
"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")))
}
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) {
if (tmp[0] == '1')
virBufferAdd(&buf, " <graphics type='sdl'/>\n", 27 );
}
-
- /*
- * TODO:
- * Device for cdrom
- */
}
tty = xenStoreDomainGetConsolePath(conn, domid);
}
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");
}
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");
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;
}
- /* TODO:
- * Is a cdrom disk device specified?
- * Kind of ugly since it is buried in the devices/diskk node.
- */
+
+ /* 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;
+ }
+ }
+
+ 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);
* 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;
typ = 1;
xmlFree(type);
}
+ device = xmlGetProp(node, BAD_CAST "device");
+
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
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);
else if (ro == 1)
virBufferVSprintf(buf, "(mode 'r')");
+ virBufferAdd(buf, ")", 1);
virBufferAdd(buf, ")", 1);
xmlFree(target);
xmlFree(source);
}
if (script != NULL)
virBufferVSprintf(buf, "(script '%s')", script);
+ virBufferAdd(buf, "(type ioemu)", 12);
virBufferAdd(buf, ")", 1);
if (mac != NULL)
xmlXPathContextPtr ctxt = NULL;
int i, res;
int bootloader = 0;
+ int hvm = 0;
if (name != NULL)
*name = NULL;
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);
}
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);