Yes, you read the subject right; add floppy support to xm internal.  Let's just
say I didn't do this by choice.  In any case, there was a cryptic comment in
xenXMParseXMLDisks() that said:

/* Xend (all versions) put the floppy device config
 * under the hvm (image (os)) block
 */

What this actually means is that we shouldn't parse the floppy stuff to put it
in the "disks =" section of the /etc/xen configuration file, since it doesn't
have meaning there.  Instead, floppy disks go at the top-level of a Xen config
file, like:

fda = '/var/lib/xen/images/floppy.img'
fdb = '/var/lib/xen/images/floppy2.img'

That's exactly what this patch does.  In combination with a couple of other
small patches to virt-install (which I will post to the appropriate list), I was
able to use a floppy disk to hold the kickstart for a fully virtualized Xen
guest install.

Signed-off-by: Chris Lalancette <[EMAIL PROTECTED]>
Index: src/xm_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xm_internal.c,v
retrieving revision 1.84
diff -u -r1.84 xm_internal.c
--- src/xm_internal.c	26 Jun 2008 10:56:19 -0000	1.84
+++ src/xm_internal.c	18 Jul 2008 12:04:47 -0000
@@ -1639,6 +1639,67 @@
     return ret;
 }
 
+static int xenXMParseXMLFloppy(xmlNodePtr node, virConfPtr conf)
+{
+    xmlNodePtr cur;
+    xmlChar *source = NULL;
+    xmlChar *target = NULL;
+    xmlChar *type = NULL;
+    int typ = 0;
+    int ret = -1;
+    virConfValuePtr floppy = NULL;
+
+    type = xmlGetProp(node, BAD_CAST "type");
+    if (type != NULL) {
+        if (xmlStrEqual(type, BAD_CAST "file"))
+            typ = 0;
+        else if (xmlStrEqual(type, BAD_CAST "block"))
+            typ = 1;
+        xmlFree(type);
+    }
+
+    cur = node->children;
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE) {
+            if ((source == NULL) &&
+                (xmlStrEqual(cur->name, BAD_CAST "source"))) {
+
+                if (typ == 0)
+                    source = xmlGetProp(cur, BAD_CAST "file");
+                else
+                    source = xmlGetProp(cur, BAD_CAST "dev");
+            } else if ((target == NULL) &&
+                       (xmlStrEqual(cur->name, BAD_CAST "target"))) {
+                target = xmlGetProp(cur, BAD_CAST "dev");
+            }
+        }
+        cur = cur->next;
+    }
+
+    if (source == NULL || target == NULL)
+        goto error;
+
+    if (!STREQ((const char *)target, "fda") && !STREQ((const char *)target, "fdb"))
+        goto error;
+
+    if (VIR_ALLOC(floppy) < 0)
+        goto error;
+
+    floppy->type = VIR_CONF_STRING;
+    floppy->str = strdup((const char *)source);
+
+    if (virConfSetValue(conf, (const char *)target, floppy) < 0)
+        goto error;
+
+    ret = 0;
+
+error:
+    xmlFree(source);
+    xmlFree(target);
+
+    return ret;
+}
+
 static int xenXMParseXMLDisk(xmlNodePtr node, int hvm, int xendConfigVersion, char **disk) {
     xmlNodePtr cur;
     xmlChar *type = NULL;
@@ -1698,16 +1759,6 @@
         return (-1);
     }
 
-    /* Xend (all versions) put the floppy device config
-     * under the hvm (image (os)) block
-     */
-    if (hvm &&
-        device &&
-        STREQ((const char *)device, "floppy")) {
-        ret = 0;
-        goto cleanup;
-    }
-
     /* Xend <= 3.0.2 doesn't include cdrom config here */
     if (hvm &&
         device &&
@@ -2261,22 +2312,32 @@
         for (i = obj->nodesetval->nodeNr -1 ; i >= 0 ; i--) {
             virConfValuePtr thisDisk;
             char *disk = NULL;
-            if (xenXMParseXMLDisk(obj->nodesetval->nodeTab[i], hvm, priv->xendConfigVersion, &disk) < 0) {
-                virConfFreeValue(disks);
-                goto error;
+            xmlChar *device;
+
+            device = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "device");
+            if (hvm && device && STREQ((const char *)device, "floppy")) {
+                if (xenXMParseXMLFloppy(obj->nodesetval->nodeTab[i], conf) < 0)
+                    goto error;
             }
-            if (disk) {
-                if (VIR_ALLOC(thisDisk) < 0) {
-                    VIR_FREE(disk);
+            else {
+                if (xenXMParseXMLDisk(obj->nodesetval->nodeTab[i], hvm, priv->xendConfigVersion, &disk) < 0) {
                     virConfFreeValue(disks);
-                    xenXMError(conn, VIR_ERR_NO_MEMORY, _("config"));
                     goto error;
                 }
-                thisDisk->type = VIR_CONF_STRING;
-                thisDisk->str = disk;
-                thisDisk->next = disks->list;
-                disks->list = thisDisk;
+                if (disk) {
+                    if (VIR_ALLOC(thisDisk) < 0) {
+                        VIR_FREE(disk);
+                        virConfFreeValue(disks);
+                        xenXMError(conn, VIR_ERR_NO_MEMORY, _("config"));
+                        goto error;
+                    }
+                    thisDisk->type = VIR_CONF_STRING;
+                    thisDisk->str = disk;
+                    thisDisk->next = disks->list;
+                    disks->list = thisDisk;
+                }
             }
+            xmlFree(device);
         }
         if (virConfSetValue(conf, "disk", disks) < 0)
             goto error;
--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to