]> xenbits.xensource.com Git - libvirt.git/commitdiff
Fixup handling of HVM boot preference, and include HVM cdrom/floppy in main device...
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 11 Aug 2006 14:40:04 +0000 (14:40 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 11 Aug 2006 14:40:04 +0000 (14:40 +0000)
ChangeLog
src/libvirt.c
src/xend_internal.c
src/xml.c

index 7986349aaf432a92237d07523812eff5ddfe093d..fcd5014a33c5569cc6126441eaf1692dbb221268 100644 (file)
--- a/ChangeLog
+++ b/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
@@ -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
index 47b32679024a7a9ec1d6a13023b8d2685cc8db4c..4c4a997afd6ca0e7f030df2e47758ded1d626713 100644 (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);
 }
 
 /**
index bfe8f226361fbc8085a76d0c5ea8396b4b7fccbd..810162a01c114c558c609b7864815a0c7475d83e 100644 (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);
index 619f5127e63079ca8687adbe7659f910324a2dce..255a64241788c3a4a2a5e3693a6d2449cf09c79c 100644 (file)
--- a/src/xml.c
+++ b/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;
     }
-    /* 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);
@@ -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);