]> xenbits.xensource.com Git - libvirt.git/commitdiff
Switch domain device objects to array instead of linked list
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 10 Oct 2008 16:08:01 +0000 (16:08 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 10 Oct 2008 16:08:01 +0000 (16:08 +0000)
14 files changed:
ChangeLog
src/domain_conf.c
src/domain_conf.h
src/lxc_container.c
src/lxc_controller.c
src/lxc_driver.c
src/openvz_conf.c
src/openvz_driver.c
src/qemu_conf.c
src/qemu_driver.c
src/xend_internal.c
src/xend_internal.h
src/xm_internal.c
tests/sexpr2xmldata/sexpr2xml-fv-v2.xml

index 88a433a42b4f0160f5cd0e113da393c3b6c83acd..c46769e46713d75dba4bf1f4214baf0b5bbd9bf4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Fri Oct 10 17:03:00 BST 2008 Daniel P. Berrange <berrange@redhat.com>
+
+       * src/domain_conf.c, src/domain_conf.h, src/lxc_container.c,
+       src/lxc_controller.c, src/lxc_driver.c, src/openvz_conf.c,
+       src/openvz_driver.c, src/qemu_conf.c, src/qemu_driver.c,
+       src/xend_internal.c, src/xend_internal.h, src/xminternal.c:
+       Switch to using arrays instead of linked lists for devices
+       * tests/sexpr2xmldata/sexpr2xml-fv-v2.xml: Fix device ordering
+
 Fri Oct 10 15:39:00 BST 2008 Daniel P. Berrange <berrange@redhat.com>
 
        * src/storage_conf.c, src/storage_conf.h, src/storage_driver.c,
index d4dfb8b1286b939e4fdffb46ac695975a135368d..f57fb2d14650f574cd79bc0be58451fce20591f6 100644 (file)
@@ -209,7 +209,6 @@ void virDomainInputDefFree(virDomainInputDefPtr def)
     if (!def)
         return;
 
-    virDomainInputDefFree(def->next);
     VIR_FREE(def);
 }
 
@@ -223,7 +222,6 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
     VIR_FREE(def->driverName);
     VIR_FREE(def->driverType);
 
-    virDomainDiskDefFree(def->next);
     VIR_FREE(def);
 }
 
@@ -235,7 +233,6 @@ void virDomainFSDefFree(virDomainFSDefPtr def)
     VIR_FREE(def->src);
     VIR_FREE(def->dst);
 
-    virDomainFSDefFree(def->next);
     VIR_FREE(def);
 }
 
@@ -269,7 +266,6 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
     }
 
     VIR_FREE(def->ifname);
-    virDomainNetDefFree(def->next);
     VIR_FREE(def);
 }
 
@@ -303,7 +299,6 @@ void virDomainChrDefFree(virDomainChrDefPtr def)
         break;
     }
 
-    virDomainChrDefFree(def->next);
     VIR_FREE(def);
 }
 
@@ -312,7 +307,6 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def)
     if (!def)
         return;
 
-    virDomainSoundDefFree(def->next);
     VIR_FREE(def);
 }
 
@@ -322,7 +316,6 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def)
         return;
 
     VIR_FREE(def->target);
-    virDomainHostdevDefFree(def->next);
     VIR_FREE(def);
 }
 
@@ -354,19 +347,45 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
 
 void virDomainDefFree(virDomainDefPtr def)
 {
+    unsigned int i;
+
     if (!def)
         return;
 
     virDomainGraphicsDefFree(def->graphics);
-    virDomainInputDefFree(def->inputs);
-    virDomainDiskDefFree(def->disks);
-    virDomainFSDefFree(def->fss);
-    virDomainNetDefFree(def->nets);
-    virDomainChrDefFree(def->serials);
-    virDomainChrDefFree(def->parallels);
+
+    for (i = 0 ; i < def->ninputs ; i++)
+        virDomainInputDefFree(def->inputs[i]);
+    VIR_FREE(def->inputs);
+
+    for (i = 0 ; i < def->ndisks ; i++)
+        virDomainDiskDefFree(def->disks[i]);
+    VIR_FREE(def->disks);
+
+    for (i = 0 ; i < def->nfss ; i++)
+        virDomainFSDefFree(def->fss[i]);
+    VIR_FREE(def->fss);
+
+    for (i = 0 ; i < def->nnets ; i++)
+        virDomainNetDefFree(def->nets[i]);
+    VIR_FREE(def->nets);
+    for (i = 0 ; i < def->nserials ; i++)
+        virDomainChrDefFree(def->serials[i]);
+    VIR_FREE(def->serials);
+
+    for (i = 0 ; i < def->nparallels ; i++)
+        virDomainChrDefFree(def->parallels[i]);
+    VIR_FREE(def->parallels);
+
     virDomainChrDefFree(def->console);
-    virDomainSoundDefFree(def->sounds);
-    virDomainHostdevDefFree(def->hostdevs);
+
+    for (i = 0 ; i < def->nsounds ; i++)
+        virDomainSoundDefFree(def->sounds[i]);
+    VIR_FREE(def->sounds);
+
+    for (i = 0 ; i < def->nhostdevs ; i++)
+        virDomainHostdevDefFree(def->hostdevs[i]);
+    VIR_FREE(def->hostdevs);
 
     VIR_FREE(def->os.type);
     VIR_FREE(def->os.arch);
@@ -1677,6 +1696,14 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn,
     return NULL;
 }
 
+int virDomainDiskQSort(const void *a, const void *b)
+{
+    const virDomainDiskDefPtr *da = a;
+    const virDomainDiskDefPtr *db = b;
+
+    return virDomainDiskCompare(*da, *db);
+}
+
 
 static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
                                             virCapsPtr caps,
@@ -1918,36 +1945,18 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
                              "%s", _("cannot extract disk devices"));
         goto error;
     }
+    if (n && VIR_ALLOC_N(def->disks, n) < 0)
+        goto no_memory;
     for (i = 0 ; i < n ; i++) {
         virDomainDiskDefPtr disk = virDomainDiskDefParseXML(conn,
                                                             nodes[i]);
         if (!disk)
             goto error;
 
-        /* Maintain list in sorted order according to target device name */
-        virDomainDiskDefPtr ptr = def->disks;
-        virDomainDiskDefPtr *prev = &(def->disks);
-        while (ptr) {
-            if (STREQ(disk->dst, ptr->dst)) {
-                virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                                     _("duplicate disk target '%s'"),
-                                     disk->dst);
-                goto error;
-            }
-            if (virDomainDiskCompare(disk, ptr) < 0) {
-                disk->next = ptr;
-                *prev = disk;
-                break;
-            }
-            prev = &(ptr->next);
-            ptr = ptr->next;
-        }
-
-        if (!ptr) {
-            disk->next = ptr;
-            *prev = disk;
-        }
+        def->disks[def->ndisks++] = disk;
     }
+    qsort(def->disks, def->ndisks, sizeof(*def->disks),
+          virDomainDiskQSort);
     VIR_FREE(nodes);
 
     /* analysis of the filesystems */
@@ -1956,14 +1965,15 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
                              "%s", _("cannot extract filesystem devices"));
         goto error;
     }
-    for (i = n - 1 ; i >= 0 ; i--) {
+    if (n && VIR_ALLOC_N(def->fss, n) < 0)
+        goto no_memory;
+    for (i = 0 ; i < n ; i++) {
         virDomainFSDefPtr fs = virDomainFSDefParseXML(conn,
                                                       nodes[i]);
         if (!fs)
             goto error;
 
-        fs->next = def->fss;
-        def->fss = fs;
+        def->fss[def->nfss++] = fs;
     }
     VIR_FREE(nodes);
 
@@ -1973,14 +1983,15 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
                              "%s", _("cannot extract network devices"));
         goto error;
     }
-    for (i = n - 1 ; i >= 0 ; i--) {
+    if (n && VIR_ALLOC_N(def->nets, n) < 0)
+        goto no_memory;
+    for (i = 0 ; i < n ; i++) {
         virDomainNetDefPtr net = virDomainNetDefParseXML(conn,
                                                          nodes[i]);
         if (!net)
             goto error;
 
-        net->next = def->nets;
-        def->nets = net;
+        def->nets[def->nnets++] = net;
     }
     VIR_FREE(nodes);
 
@@ -1991,15 +2002,17 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
                              "%s", _("cannot extract parallel devices"));
         goto error;
     }
-    for (i = n - 1 ; i >= 0 ; i--) {
+    if (n && VIR_ALLOC_N(def->parallels, n) < 0)
+        goto no_memory;
+
+    for (i = 0 ; i < n ; i++) {
         virDomainChrDefPtr chr = virDomainChrDefParseXML(conn,
                                                          nodes[i]);
         if (!chr)
             goto error;
 
         chr->dstPort = i;
-        chr->next = def->parallels;
-        def->parallels = chr;
+        def->parallels[def->nparallels++] = chr;
     }
     VIR_FREE(nodes);
 
@@ -2008,15 +2021,17 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
                              "%s", _("cannot extract serial devices"));
         goto error;
     }
-    for (i = n - 1 ; i >= 0 ; i--) {
+    if (n && VIR_ALLOC_N(def->serials, n) < 0)
+        goto no_memory;
+
+    for (i = 0 ; i < n ; i++) {
         virDomainChrDefPtr chr = virDomainChrDefParseXML(conn,
                                                          nodes[i]);
         if (!chr)
             goto error;
 
         chr->dstPort = i;
-        chr->next = def->serials;
-        def->serials = chr;
+        def->serials[def->nserials++] = chr;
     }
     VIR_FREE(nodes);
 
@@ -2024,7 +2039,7 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
      * If no serial devices were listed, then look for console
      * devices which is the legacy syntax for the same thing
      */
-    if (def->serials == NULL) {
+    if (def->nserials == 0) {
         if ((node = virXPathNode(conn, "./devices/console[1]", ctxt)) != NULL) {
             virDomainChrDefPtr chr = virDomainChrDefParseXML(conn,
                                                              node);
@@ -2037,8 +2052,12 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
              * while for non-HVM it was a parvirt console
              */
             if (STREQ(def->os.type, "hvm")) {
-                chr->next = def->serials;
-                def->serials = chr;
+                if (VIR_ALLOC_N(def->serials, 1) < 0) {
+                    virDomainChrDefFree(chr);
+                    goto no_memory;
+                }
+                def->nserials = 1;
+                def->serials[0] = chr;
             } else {
                 def->console = chr;
             }
@@ -2052,7 +2071,10 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
                              "%s", _("cannot extract input devices"));
         goto error;
     }
-    for (i = n - 1 ; i >= 0 ; i--) {
+    if (n && VIR_ALLOC_N(def->inputs, n) < 0)
+        goto no_memory;
+
+    for (i = 0 ; i < n ; i++) {
         virDomainInputDefPtr input = virDomainInputDefParseXML(conn,
                                                                def->os.type,
                                                                nodes[i]);
@@ -2073,8 +2095,7 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
             continue;
         }
 
-        input->next = def->inputs;
-        def->inputs = input;
+        def->inputs[def->ninputs++] = input;
     }
     VIR_FREE(nodes);
 
@@ -2109,8 +2130,13 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
             input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
             input->bus = VIR_DOMAIN_INPUT_BUS_XEN;
         }
-        input->next = def->inputs;
-        def->inputs = input;
+
+        if (VIR_REALLOC_N(def->inputs, def->ninputs + 1) < 0) {
+            virDomainInputDefFree(input);
+            goto no_memory;
+        }
+        def->inputs[def->ninputs] = input;
+        def->ninputs++;
     }
 
 
@@ -2120,28 +2146,26 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
                              "%s", _("cannot extract sound devices"));
         goto error;
     }
-    for (i = n - 1 ; i >= 0 ; i--) {
-        int collision = 0;
-        virDomainSoundDefPtr check;
+    if (n && VIR_ALLOC_N(def->sounds, n) < 0)
+        goto no_memory;
+    for (i = 0 ; i < n ; i++) {
+        int collision = 0, j;
         virDomainSoundDefPtr sound = virDomainSoundDefParseXML(conn,
                                                                nodes[i]);
         if (!sound)
             goto error;
 
         /* Verify there's no duplicated sound card */
-        check = def->sounds;
-        while (check) {
-            if (check->model == sound->model)
+        for (j = 0 ; j < def->nsounds ; j++) {
+            if (def->sounds[j]->model == sound->model)
                 collision = 1;
-            check = check->next;
         }
         if (collision) {
             virDomainSoundDefFree(sound);
             continue;
         }
 
-        sound->next = def->sounds;
-        def->sounds = sound;
+        def->sounds[def->nsounds++] = sound;
     }
     VIR_FREE(nodes);
 
@@ -2151,18 +2175,23 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
                              "%s", _("cannot extract host devices"));
         goto error;
     }
+    if (n && VIR_ALLOC_N(def->hostdevs, n) < 0)
+        goto no_memory;
     for (i = 0 ; i < n ; i++) {
         virDomainHostdevDefPtr hostdev = virDomainHostdevDefParseXML(conn, nodes[i]);
         if (!hostdev)
             goto error;
 
-        hostdev->next = def->hostdevs;
-        def->hostdevs = hostdev;
+        def->hostdevs[def->nhostdevs++] = hostdev;
     }
     VIR_FREE(nodes);
 
     return def;
 
+no_memory:
+    virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+    /* fallthrough */
+
  error:
     VIR_FREE(tmp);
     VIR_FREE(nodes);
@@ -2953,13 +2982,6 @@ char *virDomainDefFormat(virConnectPtr conn,
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     unsigned char *uuid;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
-    virDomainDiskDefPtr disk;
-    virDomainFSDefPtr fs;
-    virDomainNetDefPtr net;
-    virDomainSoundDefPtr sound;
-    virDomainInputDefPtr input;
-    virDomainChrDefPtr chr;
-    virDomainHostdevDefPtr hostdev;
     const char *type = NULL, *tmp;
     int n, allones = 1;
 
@@ -3096,67 +3118,49 @@ char *virDomainDefFormat(virConnectPtr conn,
         virBufferEscapeString(&buf, "    <emulator>%s</emulator>\n",
                               def->emulator);
 
-    disk = def->disks;
-    while (disk) {
-        if (virDomainDiskDefFormat(conn, &buf, disk) < 0)
+    for (n = 0 ; n < def->ndisks ; n++)
+        if (virDomainDiskDefFormat(conn, &buf, def->disks[n]) < 0)
             goto cleanup;
-        disk = disk->next;
-    }
 
-    fs = def->fss;
-    while (fs) {
-        if (virDomainFSDefFormat(conn, &buf, fs) < 0)
+    for (n = 0 ; n < def->nfss ; n++)
+        if (virDomainFSDefFormat(conn, &buf, def->fss[n]) < 0)
             goto cleanup;
-        fs = fs->next;
-    }
 
-    net = def->nets;
-    while (net) {
-        if (virDomainNetDefFormat(conn, &buf, net) < 0)
-            goto cleanup;
-        net = net->next;
-    }
 
+    for (n = 0 ; n < def->nnets ; n++)
+        if (virDomainNetDefFormat(conn, &buf, def->nets[n]) < 0)
+            goto cleanup;
 
-    chr = def->serials;
-    while (chr) {
-        if (virDomainChrDefFormat(conn, &buf, chr, "serial") < 0)
+    for (n = 0 ; n < def->nserials ; n++)
+        if (virDomainChrDefFormat(conn, &buf, def->serials[n], "serial") < 0)
             goto cleanup;
-        chr = chr->next;
-    }
 
-    chr = def->parallels;
-    while (chr) {
-        if (virDomainChrDefFormat(conn, &buf, chr, "parallel") < 0)
+    for (n = 0 ; n < def->nparallels ; n++)
+        if (virDomainChrDefFormat(conn, &buf, def->parallels[n], "parallel") < 0)
             goto cleanup;
-        chr = chr->next;
-    }
 
     /* If there's a PV console that's preferred.. */
     if (def->console) {
         if (virDomainChrDefFormat(conn, &buf, def->console, "console") < 0)
             goto cleanup;
-    } else if (def->serials != NULL) {
+    } else if (def->nserials != 0) {
         /* ..else for legacy compat duplicate the serial device as a console */
-        if (virDomainChrDefFormat(conn, &buf, def->serials, "console") < 0)
+        if (virDomainChrDefFormat(conn, &buf, def->serials[n], "console") < 0)
             goto cleanup;
     }
 
-    input = def->inputs;
-    while (input) {
-        if (input->bus == VIR_DOMAIN_INPUT_BUS_USB &&
-            virDomainInputDefFormat(conn, &buf, input) < 0)
+    for (n = 0 ; n < def->ninputs ; n++)
+        if (def->inputs[n]->bus == VIR_DOMAIN_INPUT_BUS_USB &&
+            virDomainInputDefFormat(conn, &buf, def->inputs[n]) < 0)
             goto cleanup;
-        input = input->next;
-    }
 
     if (def->graphics) {
         /* If graphics is enabled, add the implicit mouse */
         virDomainInputDef autoInput = {
             VIR_DOMAIN_INPUT_TYPE_MOUSE,
             STREQ(def->os.type, "hvm") ?
-            VIR_DOMAIN_INPUT_BUS_PS2 : VIR_DOMAIN_INPUT_BUS_XEN,
-            NULL };
+            VIR_DOMAIN_INPUT_BUS_PS2 : VIR_DOMAIN_INPUT_BUS_XEN
+        };
 
         if (virDomainInputDefFormat(conn, &buf, &autoInput) < 0)
             goto cleanup;
@@ -3165,19 +3169,13 @@ char *virDomainDefFormat(virConnectPtr conn,
             goto cleanup;
     }
 
-    sound = def->sounds;
-    while(sound) {
-        if (virDomainSoundDefFormat(conn, &buf, sound) < 0)
+    for (n = 0 ; n < def->nsounds ; n++)
+        if (virDomainSoundDefFormat(conn, &buf, def->sounds[n]) < 0)
             goto cleanup;
-        sound = sound->next;
-    }
 
-    hostdev = def->hostdevs;
-    while (hostdev) {
-        if (virDomainHostdevDefFormat(conn, &buf, hostdev) < 0)
+    for (n = 0 ; n < def->nhostdevs ; n++)
+        if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n]) < 0)
             goto cleanup;
-        hostdev = hostdev->next;
-    }
 
     virBufferAddLit(&buf, "  </devices>\n");
     virBufferAddLit(&buf, "</domain>\n");
index 1a48c8926dc27d731b92093216ed725ecf615f8c..4d193f4e7a55570580a5ef0f2c1d6b0b2124ec9f 100644 (file)
@@ -90,8 +90,6 @@ struct _virDomainDiskDef {
     char *driverType;
     unsigned int readonly : 1;
     unsigned int shared : 1;
-
-    virDomainDiskDefPtr next;
 };
 
 
@@ -112,8 +110,6 @@ struct _virDomainFSDef {
     char *src;
     char *dst;
     unsigned int readonly : 1;
-
-    virDomainFSDefPtr next;
 };
 
 
@@ -158,8 +154,6 @@ struct _virDomainNetDef {
         } bridge;
     } data;
     char *ifname;
-
-    virDomainNetDefPtr next;
 };
 
 enum virDomainChrSrcType {
@@ -211,8 +205,6 @@ struct _virDomainChrDef {
             int listen;
         } nix;
     } data;
-
-    virDomainChrDefPtr next;
 };
 
 enum virDomainInputType {
@@ -235,7 +227,6 @@ typedef virDomainInputDef *virDomainInputDefPtr;
 struct _virDomainInputDef {
     int type;
     int bus;
-    virDomainInputDefPtr next;
 };
 
 enum virDomainSoundModel {
@@ -250,7 +241,6 @@ typedef struct _virDomainSoundDef virDomainSoundDef;
 typedef virDomainSoundDef *virDomainSoundDefPtr;
 struct _virDomainSoundDef {
     int model;
-    virDomainSoundDefPtr next;
 };
 
 /* 3 possible graphics console modes */
@@ -324,7 +314,6 @@ struct _virDomainHostdevDef {
         } caps;
     } source;
     char* target;
-    virDomainHostdevDefPtr next;
 };
 
 /* Flags for the 'type' field in next struct */
@@ -428,15 +417,34 @@ struct _virDomainDef {
 
     int localtime;
 
+    /* Only 1 */
     virDomainGraphicsDefPtr graphics;
-    virDomainDiskDefPtr disks;
-    virDomainFSDefPtr fss;
-    virDomainNetDefPtr nets;
-    virDomainInputDefPtr inputs;
-    virDomainSoundDefPtr sounds;
-    virDomainHostdevDefPtr hostdevs;
-    virDomainChrDefPtr serials;
-    virDomainChrDefPtr parallels;
+
+    int ndisks;
+    virDomainDiskDefPtr *disks;
+
+    int nfss;
+    virDomainFSDefPtr *fss;
+
+    int nnets;
+    virDomainNetDefPtr *nets;
+
+    int ninputs;
+    virDomainInputDefPtr *inputs;
+
+    int nsounds;
+    virDomainSoundDefPtr *sounds;
+
+    int nhostdevs;
+    virDomainHostdevDefPtr *hostdevs;
+
+    int nserials;
+    virDomainChrDefPtr *serials;
+
+    int nparallels;
+    virDomainChrDefPtr *parallels;
+
+    /* Only 1 */
     virDomainChrDefPtr console;
 };
 
@@ -531,6 +539,7 @@ char *virDomainCpuSetFormat(virConnectPtr conn,
                             char *cpuset,
                             int maxcpu);
 
+int virDomainDiskQSort(const void *a, const void *b);
 int virDomainDiskCompare(virDomainDiskDefPtr a,
                          virDomainDiskDefPtr b);
 
index 7599b75e416981efb44d1eaa2ea1c2139134ff82..379e0af4c900411af291bbdf8a3a60dadc2f1296 100644 (file)
@@ -365,28 +365,28 @@ static int lxcContainerPopulateDevices(void)
 
 static int lxcContainerMountNewFS(virDomainDefPtr vmDef)
 {
-    virDomainFSDefPtr tmp;
+    int i;
 
     /* Pull in rest of container's mounts */
-    for (tmp = vmDef->fss; tmp; tmp = tmp->next) {
+    for (i = 0 ; i < vmDef->nfss ; i++) {
         char *src;
-        if (STREQ(tmp->dst, "/"))
+        if (STREQ(vmDef->fss[i]->dst, "/"))
             continue;
         // XXX fix
-        if (tmp->type != VIR_DOMAIN_FS_TYPE_MOUNT)
+        if (vmDef->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
             continue;
 
-        if (asprintf(&src, "/.oldroot/%s", tmp->src) < 0) {
+        if (asprintf(&src, "/.oldroot/%s", vmDef->fss[i]->src) < 0) {
             lxcError(NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
             return -1;
         }
 
-        if (virFileMakePath(tmp->dst) < 0 ||
-            mount(src, tmp->dst, NULL, MS_BIND, NULL) < 0) {
+        if (virFileMakePath(vmDef->fss[i]->dst) < 0 ||
+            mount(src, vmDef->fss[i]->dst, NULL, MS_BIND, NULL) < 0) {
             VIR_FREE(src);
             lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                      _("failed to mount %s at %s for container: %s"),
-                     tmp->src, tmp->dst, strerror(errno));
+                     vmDef->fss[i]->src, vmDef->fss[i]->dst, strerror(errno));
             return -1;
         }
         VIR_FREE(src);
@@ -479,21 +479,21 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
    but with extra stuff mapped in */
 static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef)
 {
-    virDomainFSDefPtr tmp;
+    int i;
 
-    for (tmp = vmDef->fss; tmp; tmp = tmp->next) {
+    for (i = 0 ; i < vmDef->nfss ; i++) {
         // XXX fix to support other mount types
-        if (tmp->type != VIR_DOMAIN_FS_TYPE_MOUNT)
+        if (vmDef->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
             continue;
 
-        if (mount(tmp->src,
-                  tmp->dst,
+        if (mount(vmDef->fss[i]->src,
+                  vmDef->fss[i]->dst,
                   NULL,
                   MS_BIND,
                   NULL) < 0) {
             lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                      _("failed to mount %s at %s for container: %s"),
-                     tmp->src, tmp->dst, strerror(errno));
+                     vmDef->fss[i]->src, vmDef->fss[i]->dst, strerror(errno));
             return -1;
         }
     }
@@ -511,14 +511,14 @@ static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef)
 
 static int lxcContainerSetupMounts(virDomainDefPtr vmDef)
 {
-    virDomainFSDefPtr tmp;
+    int i;
     virDomainFSDefPtr root = NULL;
 
-    for (tmp = vmDef->fss; tmp && !root; tmp = tmp->next) {
-        if (tmp->type != VIR_DOMAIN_FS_TYPE_MOUNT)
+    for (i = 0 ; i < vmDef->nfss ; i++) {
+        if (vmDef->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
             continue;
-        if (STREQ(tmp->dst, "/"))
-            root = tmp;
+        if (STREQ(vmDef->fss[i]->dst, "/"))
+            root = vmDef->fss[i];
     }
 
     if (root)
index 4721c8081870f177a4dd0bc49056d57a789c308c..c3eca37a9ac26a7da4fbdcf3a10ba93fb31abf3f 100644 (file)
@@ -499,8 +499,6 @@ int main(int argc, char *argv[])
     int bg = 0;
     virCapsPtr caps = NULL;
     virDomainDefPtr def = NULL;
-    int nnets = 0;
-    virDomainNetDefPtr nets = NULL;
     char *configFile = NULL;
     char *sockpath = NULL;
     const struct option const options[] = {
@@ -595,14 +593,9 @@ int main(int argc, char *argv[])
     if ((def = virDomainDefParseFile(NULL, caps, configFile)) == NULL)
         goto cleanup;
 
-    nets = def->nets;
-    while (nets) {
-        nnets++;
-        nets = nets->next;
-    }
-    if (nnets != nveths) {
+    if (def->nnets != nveths) {
         fprintf(stderr, "%s: expecting %d veths, but got %d\n",
-                argv[0], nnets, nveths);
+                argv[0], def->nnets, nveths);
         goto cleanup;
     }
 
index c790d0a6da790aee00372063c153fd47c721e7a8..e5e1d6aafd00678ff2b84fa60d1a3bc3b30b6ab1 100644 (file)
@@ -367,8 +367,8 @@ static int lxcVMCleanup(virConnectPtr conn,
     int rc = -1;
     int waitRc;
     int childStatus = -1;
-    virDomainNetDefPtr net;
     virCgroupPtr cgroup;
+    int i;
 
     while (((waitRc = waitpid(vm->pid, &childStatus, 0)) == -1) &&
            errno == EINTR)
@@ -398,9 +398,9 @@ static int lxcVMCleanup(virConnectPtr conn,
     vm->def->id = -1;
     vm->monitor = -1;
 
-    for (net = vm->def->nets; net; net = net->next) {
-        vethInterfaceUpOrDown(net->ifname, 0);
-        vethDelete(net->ifname);
+    for (i = 0 ; i < vm->def->nnets ; i++) {
+        vethInterfaceUpOrDown(vm->def->nets[i]->ifname, 0);
+        vethDelete(vm->def->nets[i]->ifname);
     }
 
     if (virCgroupForDomain(vm->def, "lxc", &cgroup) == 0) {
@@ -426,8 +426,7 @@ static int lxcSetupInterfaces(virConnectPtr conn,
                               unsigned int *nveths,
                               char ***veths)
 {
-    int rc = -1;
-    virDomainNetDefPtr net;
+    int rc = -1, i;
     char *bridge = NULL;
     char parentVeth[PATH_MAX] = "";
     char containerVeth[PATH_MAX] = "";
@@ -436,12 +435,12 @@ static int lxcSetupInterfaces(virConnectPtr conn,
     if (brInit(&brctl) != 0)
         return -1;
 
-    for (net = def->nets; net; net = net->next) {
-        switch (net->type) {
+    for (i = 0 ; i < def->nnets ; i++) {
+        switch (def->nets[i]->type) {
         case VIR_DOMAIN_NET_TYPE_NETWORK:
         {
             virNetworkPtr network = virNetworkLookupByName(conn,
-                                                           net->data.network.name);
+                                                           def->nets[i]->data.network.name);
             if (!network) {
                 goto error_exit;
             }
@@ -452,7 +451,7 @@ static int lxcSetupInterfaces(virConnectPtr conn,
             break;
         }
         case VIR_DOMAIN_NET_TYPE_BRIDGE:
-            bridge = net->data.bridge.brname;
+            bridge = def->nets[i]->data.bridge.brname;
             break;
         }
 
@@ -464,8 +463,8 @@ static int lxcSetupInterfaces(virConnectPtr conn,
         }
 
         DEBUG0("calling vethCreate()");
-        if (NULL != net->ifname) {
-            strcpy(parentVeth, net->ifname);
+        if (NULL != def->nets[i]->ifname) {
+            strcpy(parentVeth, def->nets[i]->ifname);
         }
         DEBUG("parentVeth: %s, containerVeth: %s", parentVeth, containerVeth);
         if (0 != (rc = vethCreate(parentVeth, PATH_MAX, containerVeth, PATH_MAX))) {
@@ -473,15 +472,15 @@ static int lxcSetupInterfaces(virConnectPtr conn,
                      _("failed to create veth device pair: %d"), rc);
             goto error_exit;
         }
-        if (NULL == net->ifname) {
-            net->ifname = strdup(parentVeth);
+        if (NULL == def->nets[i]->ifname) {
+            def->nets[i]->ifname = strdup(parentVeth);
         }
         if (VIR_REALLOC_N(*veths, (*nveths)+1) < 0)
             goto error_exit;
         if (((*veths)[(*nveths)++] = strdup(containerVeth)) == NULL)
             goto error_exit;
 
-        if (NULL == net->ifname) {
+        if (NULL == def->nets[i]->ifname) {
             lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                      _("failed to allocate veth names"));
             goto error_exit;
index ebde99d5ce2247296a5b3a28a95729a431c9f528..a2553d096a0f9965636de331689284a6be2acab1 100644 (file)
@@ -149,11 +149,12 @@ static int openvzParseMac(const char *macaddr, unsigned char *mac)
     return -1;
 }
 
-static virDomainNetDefPtr
-openvzReadNetworkConf(virConnectPtr conn, int veid) {
+static int
+openvzReadNetworkConf(virConnectPtr conn,
+                      virDomainDefPtr def,
+                      int veid) {
     int ret;
-    virDomainNetDefPtr net = NULL;
-    virDomainNetDefPtr new_net;
+    virDomainNetDefPtr net;
     char temp[4096];
     char *token, *saveptr = NULL;
 
@@ -171,11 +172,8 @@ openvzReadNetworkConf(virConnectPtr conn, int veid) {
     } else if (ret > 0) {
         token = strtok_r(temp, " ", &saveptr);
         while (token != NULL) {
-            new_net = NULL;
-            if (VIR_ALLOC(new_net) < 0)
+            if (VIR_ALLOC(net) < 0)
                 goto no_memory;
-            new_net->next = net;
-            net = new_net;
 
             net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
             net->data.ethernet.ipaddr = strdup(token);
@@ -183,6 +181,11 @@ openvzReadNetworkConf(virConnectPtr conn, int veid) {
             if (net->data.ethernet.ipaddr == NULL)
                 goto no_memory;
 
+            if (VIR_REALLOC_N(def->nets, def->nnets + 1) < 0)
+                goto no_memory;
+            def->nets[def->nnets++] = net;
+            net = NULL;
+
             token = strtok_r(NULL, " ", &saveptr);
         }
     }
@@ -202,11 +205,8 @@ openvzReadNetworkConf(virConnectPtr conn, int veid) {
         token = strtok_r(temp, ";", &saveptr);
         while (token != NULL) {
             /*add new device to list*/
-            new_net = NULL;
-            if (VIR_ALLOC(new_net) < 0)
+            if (VIR_ALLOC(net) < 0)
                 goto no_memory;
-            new_net->next = net;
-            net = new_net;
 
             net->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
 
@@ -256,16 +256,21 @@ openvzReadNetworkConf(virConnectPtr conn, int veid) {
                 p = ++next;
             } while (p < token + strlen(token));
 
+            if (VIR_REALLOC_N(def->nets, def->nnets + 1) < 0)
+                goto no_memory;
+            def->nets[def->nnets++] = net;
+            net = NULL;
+
             token = strtok_r(NULL, ";", &saveptr);
         }
     }
 
-    return net;
+    return 0;
 no_memory:
     openvzError(conn, VIR_ERR_NO_MEMORY, NULL);
 error:
     virDomainNetDefFree(net);
-    return NULL;
+    return -1;
 }
 
 
@@ -353,7 +358,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
 
         /* XXX load rest of VM config data .... */
 
-        dom->def->nets = openvzReadNetworkConf(NULL, veid);
+        openvzReadNetworkConf(NULL, dom->def, veid);
 
         if (VIR_REALLOC_N(driver->domains.objs,
                           driver->domains.count + 1) < 0)
index 9e3b6a6dc1919d7815d4e406dc6aba33e7d3fc9a..e3e3cc7fcc64a6579dea64b066d0c9a1a671b27e 100644 (file)
@@ -117,21 +117,21 @@ static int openvzDomainDefineCmd(virConnectPtr conn,
     ADD_ARG_LIT("create");
     ADD_ARG_LIT(vmdef->name);
 
-    if (vmdef->fss) {
-        if (vmdef->fss->type != VIR_DOMAIN_FS_TYPE_TEMPLATE) {
+    if (vmdef->nfss) {
+        if (vmdef->fss[0]->type != VIR_DOMAIN_FS_TYPE_TEMPLATE) {
             openvzError(conn, VIR_ERR_INTERNAL_ERROR,
                         "%s", _("only filesystem templates are supported"));
             return -1;
         }
 
-        if (vmdef->fss->next) {
+        if (vmdef->nfss > 1) {
             openvzError(conn, VIR_ERR_INTERNAL_ERROR,
                         "%s", _("only one filesystem supported"));
             return -1;
         }
 
         ADD_ARG_LIT("--ostemplate");
-        ADD_ARG_LIT(vmdef->fss->src);
+        ADD_ARG_LIT(vmdef->fss[0]->src);
     }
 #if 0
     if ((vmdef->profile && *(vmdef->profile))) {
@@ -394,12 +394,6 @@ openvzDomainSetNetwork(virConnectPtr conn, const char *vpsid,
         }
     }
 
-    if (net->next != NULL)
-       if (openvzDomainSetNetwork(conn, vpsid, net->next) < 0) {
-          rc = -1;
-          goto exit;
-       }
-
  exit:
     cmdExecFree(prog);
     VIR_FREE(mac);
@@ -422,6 +416,7 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
     virDomainDefPtr vmdef = NULL;
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
+    int i;
     const char *prog[OPENVZ_MAX_ARG];
     prog[0] = NULL;
 
@@ -471,10 +466,12 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
     if (dom)
         dom->id = -1;
 
-    if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets) < 0) {
-        openvzError(conn, VIR_ERR_INTERNAL_ERROR,
-                  _("Could not configure network"));
-        goto exit;
+    for (i = 0 ; i < vmdef->nnets ; i++) {
+        if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets[i]) < 0) {
+            openvzError(conn, VIR_ERR_INTERNAL_ERROR,
+                        _("Could not configure network"));
+            goto exit;
+        }
     }
 
     if (vmdef->vcpus > 0) {
@@ -497,6 +494,7 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
     virDomainDefPtr vmdef = NULL;
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
+    int i;
     struct openvz_driver *driver = (struct openvz_driver *) conn->privateData;
     const char *progstart[] = {VZCTL, "--quiet", "start", NULL, NULL};
     const char *progcreate[OPENVZ_MAX_ARG];
@@ -542,10 +540,12 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
         goto exit;
     }
 
-    if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets) < 0) {
-       openvzError(conn, VIR_ERR_INTERNAL_ERROR,
-                  _("Could not configure network"));
-        goto exit;
+    for (i = 0 ; i < vmdef->nnets ; i++) {
+        if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets[i]) < 0) {
+            openvzError(conn, VIR_ERR_INTERNAL_ERROR,
+                        _("Could not configure network"));
+            goto exit;
+        }
     }
 
     progstart[3] = vmdef->name;
index fdd72568384c40c18b0c5a6d1389b0964aa372e7..673ea6db5b0047242f8b28d0216ddaf14529b06e 100644 (file)
@@ -701,13 +701,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
     char memory[50];
     char vcpus[50];
     char boot[VIR_DOMAIN_BOOT_LAST];
-    virDomainDiskDefPtr disk = vm->def->disks;
-    virDomainNetDefPtr net = vm->def->nets;
-    virDomainInputDefPtr input = vm->def->inputs;
-    virDomainSoundDefPtr sound = vm->def->sounds;
-    virDomainHostdevDefPtr hostdev = vm->def->hostdevs;
-    virDomainChrDefPtr serial = vm->def->serials;
-    virDomainChrDefPtr parallel = vm->def->parallels;
     struct utsname ut;
     int disableKQEMU = 0;
     int qargc = 0, qarga = 0;
@@ -874,10 +867,11 @@ int qemudBuildCommandLine(virConnectPtr conn,
             }
         }
 
-        while (disk) {
+        for (i = 0 ; i < vm->def->ndisks ; i++) {
             char opt[PATH_MAX];
             const char *media = NULL;
             int bootable = 0;
+            virDomainDiskDefPtr disk = vm->def->disks[i];
             int idx = virDiskNameToIndex(disk->dst);
             const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
 
@@ -889,7 +883,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
                                      _("unsupported usb disk type for '%s'"), disk->src);
                     goto error;
                 }
-                disk = disk->next;
                 continue;
             }
 
@@ -925,12 +918,12 @@ int qemudBuildCommandLine(virConnectPtr conn,
 
             ADD_ARG_LIT("-drive");
             ADD_ARG_LIT(opt);
-            disk = disk->next;
         }
     } else {
-        while (disk) {
+        for (i = 0 ; i < vm->def->ndisks ; i++) {
             char dev[NAME_MAX];
             char file[PATH_MAX];
+            virDomainDiskDefPtr disk = vm->def->disks[i];
 
             if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
                 if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
@@ -940,7 +933,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
                                      _("unsupported usb disk type for '%s'"), disk->src);
                     goto error;
                 }
-                disk = disk->next;
                 continue;
             }
 
@@ -949,7 +941,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
                 if (disk->src) {
                     snprintf(dev, NAME_MAX, "-%s", "cdrom");
                 } else {
-                    disk = disk->next;
                     continue;
                 }
             } else {
@@ -967,18 +958,17 @@ int qemudBuildCommandLine(virConnectPtr conn,
 
             ADD_ARG_LIT(dev);
             ADD_ARG_LIT(file);
-
-            disk = disk->next;
         }
     }
 
-    if (!net) {
+    if (!vm->def->nnets) {
         ADD_ARG_LIT("-net");
         ADD_ARG_LIT("none");
     } else {
         int vlan = 0;
-        while (net) {
+        for (i = 0 ; i < vm->def->nnets ; i++) {
             char nic[100];
+            virDomainNetDefPtr net = vm->def->nets[i];
 
             if (snprintf(nic, sizeof(nic),
                          "nic,macaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s",
@@ -1059,53 +1049,50 @@ int qemudBuildCommandLine(virConnectPtr conn,
                 }
             }
 
-            net = net->next;
             vlan++;
         }
     }
 
-    if (!serial) {
+    if (!vm->def->nserials) {
         ADD_ARG_LIT("-serial");
         ADD_ARG_LIT("none");
     } else {
-        while (serial) {
+        for (i = 0 ; i < vm->def->nserials ; i++) {
             char buf[4096];
+            virDomainChrDefPtr serial = vm->def->serials[i];
 
             if (qemudBuildCommandLineChrDevStr(serial, buf, sizeof(buf)) < 0)
                 goto error;
 
             ADD_ARG_LIT("-serial");
             ADD_ARG_LIT(buf);
-
-            serial = serial->next;
         }
     }
 
-    if (!parallel) {
+    if (!vm->def->nparallels) {
         ADD_ARG_LIT("-parallel");
         ADD_ARG_LIT("none");
     } else {
-        while (parallel) {
+        for (i = 0 ; i < vm->def->nparallels ; i++) {
             char buf[4096];
+            virDomainChrDefPtr parallel = vm->def->parallels[i];
 
             if (qemudBuildCommandLineChrDevStr(parallel, buf, sizeof(buf)) < 0)
                 goto error;
 
             ADD_ARG_LIT("-parallel");
             ADD_ARG_LIT(buf);
-
-            parallel = parallel->next;
         }
     }
 
     ADD_ARG_LIT("-usb");
-    while (input) {
+    for (i = 0 ; i < vm->def->ninputs ; i++) {
+        virDomainInputDefPtr input = vm->def->inputs[i];
+
         if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
             ADD_ARG_LIT("-usbdevice");
             ADD_ARG_LIT(input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
         }
-
-        input = input->next;
     }
 
     if (vm->def->graphics &&
@@ -1151,13 +1138,14 @@ int qemudBuildCommandLine(virConnectPtr conn,
     }
 
     /* Add sound hardware */
-    if (sound) {
+    if (vm->def->nsounds) {
         int size = 100;
         char *modstr;
         if (VIR_ALLOC_N(modstr, size+1) < 0)
             goto no_memory;
 
-        while(sound && size > 0) {
+        for (i = 0 ; i < vm->def->nsounds && size > 0 ; i++) {
+            virDomainSoundDefPtr sound = vm->def->sounds[i];
             const char *model = virDomainSoundModelTypeToString(sound->model);
             if (!model) {
                 VIR_FREE(modstr);
@@ -1167,8 +1155,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
             }
             strncat(modstr, model, size);
             size -= strlen(model);
-            sound = sound->next;
-            if (sound)
+            if (i < (vm->def->nsounds - 1))
                strncat(modstr, ",", size--);
         }
         ADD_ARG_LIT("-soundhw");
@@ -1176,9 +1163,10 @@ int qemudBuildCommandLine(virConnectPtr conn,
     }
 
     /* Add host passthrough hardware */
-    while (hostdev) {
+    for (i = 0 ; i < vm->def->nhostdevs ; i++) {
         int ret;
         char* usbdev;
+        virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
 
         if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
             hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
@@ -1200,7 +1188,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
             ADD_ARG_LIT(usbdev);
             VIR_FREE(usbdev);
         }
-        hostdev = hostdev->next;
     }
 
     if (migrateFrom) {
index 80ece80440b0229faf318687bd469a28b296c8db..22a81c51f2eef98f870619e1ac63f0d9f03bd106 100644 (file)
@@ -496,8 +496,7 @@ qemudFindCharDevicePTYs(virConnectPtr conn,
 {
     char *monitor = NULL;
     size_t offset = 0;
-    virDomainChrDefPtr chr;
-    int ret;
+    int ret, i;
 
     /* The order in which QEMU prints out the PTY paths is
        the order in which it procsses its monitor, serial
@@ -509,25 +508,23 @@ qemudFindCharDevicePTYs(virConnectPtr conn,
         goto cleanup;
 
     /* then the serial devices */
-    chr = vm->def->serials;
-    while (chr) {
+    for (i = 0 ; i < vm->def->nserials ; i++) {
+        virDomainChrDefPtr chr = vm->def->serials[i];
         if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) {
             if ((ret = qemudExtractMonitorPath(conn, output, &offset,
                                                &chr->data.file.path)) != 0)
                 goto cleanup;
         }
-        chr = chr->next;
     }
 
     /* and finally the parallel devices */
-    chr = vm->def->parallels;
-    while (chr) {
+    for (i = 0 ; i < vm->def->nparallels ; i++) {
+        virDomainChrDefPtr chr = vm->def->parallels[i];
         if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) {
             if ((ret = qemudExtractMonitorPath(conn, output, &offset,
                                                &chr->data.file.path)) != 0)
                 goto cleanup;
         }
-        chr = chr->next;
     }
 
     /* Got them all, so now open the monitor console */
@@ -2381,6 +2378,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
     char *cmd, *reply, *safe_path;
     char *devname = NULL;
     unsigned int qemuCmdFlags;
+    int i;
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2389,12 +2387,12 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
     }
 
     newdisk = dev->data.disk;
-    origdisk = vm->def->disks;
-    while (origdisk) {
-        if (origdisk->bus == newdisk->bus &&
-            STREQ(origdisk->dst, newdisk->dst))
+    for (i = 0 ; i < vm->def->ndisks ; i++) {
+        if (vm->def->disks[i]->bus == newdisk->bus &&
+            STREQ(vm->def->disks[i]->dst, newdisk->dst)) {
+            origdisk = vm->def->disks[i];
             break;
-        origdisk = origdisk->next;
+        }
     }
 
     if (!origdisk) {
@@ -2496,7 +2494,6 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
     virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
     int ret;
     char *cmd, *reply;
-    virDomainDiskDefPtr *dest, *prev, ptr;
 
     if (!vm) {
         qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2504,26 +2501,9 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
         return -1;
     }
 
-    /* Find spot in domain definition where we will put the disk */
-    ptr = vm->def->disks;
-    prev = &(vm->def->disks);
-    while (ptr) {
-        if (STREQ(dev->data.disk->dst, ptr->dst)) {
-            qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("duplicate disk target '%s'"),
-                             dev->data.disk->dst);
-            return -1;
-        }
-        if (virDomainDiskCompare(dev->data.disk, ptr) < 0) {
-            dest = &(ptr);
-            break;
-        }
-        prev = &(ptr->next);
-        ptr = ptr->next;
-    }
-
-    if (!ptr) {
-        dest = prev;
+    if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
+        qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+        return -1;
     }
 
     ret = asprintf(&cmd, "usb_add disk:%s", dev->data.disk->src);
@@ -2551,9 +2531,9 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
         return -1;
     }
 
-    /* Actually update the xml */
-    dev->data.disk->next = *dest;
-    *prev = dev->data.disk;
+    vm->def->disks[vm->def->ndisks++] = dev->data.disk;
+    qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
+          virDomainDiskQSort);
 
     VIR_FREE(reply);
     VIR_FREE(cmd);
@@ -2572,6 +2552,10 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d
                          "%s", _("no domain with matching uuid"));
         return -1;
     }
+    if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
+        qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+        return -1;
+    }
 
     if (dev->data.hostdev->source.subsys.usb.vendor) {
         ret = asprintf(&cmd, "usb_add host:%.4x:%.4x",
@@ -2606,9 +2590,7 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d
         return -1;
     }
 
-    /* Update xml */
-    dev->data.hostdev->next = vm->def->hostdevs;
-    vm->def->hostdevs = dev->data.hostdev;
+    vm->def->hostdevs[vm->def->nhostdevs++] = dev->data.hostdev;
 
     VIR_FREE(reply);
     VIR_FREE(cmd);
@@ -2891,7 +2873,7 @@ qemudDomainInterfaceStats (virDomainPtr dom,
 #ifdef __linux__
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
     virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
-    virDomainNetDefPtr net;
+    int i;
 
     if (!vm) {
         qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2912,8 +2894,9 @@ qemudDomainInterfaceStats (virDomainPtr dom,
     }
 
     /* Check the path is one of the domain's network interfaces. */
-    for (net = vm->def->nets; net; net = net->next) {
-        if (net->ifname && STREQ (net->ifname, path))
+    for (i = 0 ; i < vm->def->nnets ; i++) {
+        if (vm->def->nets[i]->ifname &&
+            STREQ (vm->def->nets[i]->ifname, path))
             goto ok;
     }
 
@@ -2939,8 +2922,7 @@ qemudDomainBlockPeek (virDomainPtr dom,
 {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
     virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
-    virDomainDiskDefPtr disk;
-    int fd, ret = -1;
+    int fd, ret = -1, i;
 
     if (!vm) {
         qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@@ -2955,9 +2937,10 @@ qemudDomainBlockPeek (virDomainPtr dom,
     }
 
     /* Check the path belongs to this domain. */
-    for (disk = vm->def->disks ; disk != NULL ; disk = disk->next) {
-        if (disk->src != NULL &&
-            STREQ (disk->src, path)) goto found;
+    for (i = 0 ; i < vm->def->ndisks ; i++) {
+        if (vm->def->disks[i]->src != NULL &&
+            STREQ (vm->def->disks[i]->src, path))
+            goto found;
     }
     qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
                       _("invalid path"));
index 0737871fd92a97fe1224071d58173e911ed82aea..65564d8245d1962feca5cf491480b657f2b90cd6 100644 (file)
@@ -1595,7 +1595,7 @@ xenDaemonParseSxprDisks(virConnectPtr conn,
                         int xendConfigVersion)
 {
     const struct sexpr *cur, *node;
-    virDomainDiskDefPtr disk = NULL, prev = def->disks;
+    virDomainDiskDefPtr disk = NULL;
 
     for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
         node = cur->u.s.car;
@@ -1729,12 +1729,10 @@ xenDaemonParseSxprDisks(virConnectPtr conn,
                 strchr(mode, '!'))
                 disk->shared = 1;
 
-            if (prev)
-                prev->next = disk;
-            else
-                def->disks = disk;
+            if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
+                goto no_memory;
 
-            prev = disk;
+            def->disks[def->ndisks++] = disk;
             disk = NULL;
         }
     }
@@ -1755,7 +1753,7 @@ xenDaemonParseSxprNets(virConnectPtr conn,
                        virDomainDefPtr def,
                        const struct sexpr *root)
 {
-    virDomainNetDefPtr net = NULL, prev = def->nets;
+    virDomainNetDefPtr net = NULL;
     const struct sexpr *cur, *node;
     const char *tmp;
     int vif_index = 0;
@@ -1828,12 +1826,10 @@ xenDaemonParseSxprNets(virConnectPtr conn,
                 !(net->model = strdup(model)))
                 goto no_memory;
 
-            if (prev)
-                prev->next = net;
-            else
-                def->nets = net;
+            if (VIR_REALLOC_N(def->nets, def->nnets + 1) < 0)
+                goto no_memory;
 
-            prev = net;
+            def->nets[def->nnets++] = net;
             vif_index++;
         }
     }
@@ -1855,22 +1851,22 @@ xenDaemonParseSxprSound(virConnectPtr conn,
 {
     if (STREQ(str, "all")) {
         int i;
-        virDomainSoundDefPtr prev = NULL;
+
+        if (VIR_ALLOC_N(def->sounds,
+                        VIR_DOMAIN_SOUND_MODEL_LAST) < 0)
+            goto no_memory;
+
         for (i = 0 ; i < VIR_DOMAIN_SOUND_MODEL_LAST ; i++) {
             virDomainSoundDefPtr sound;
             if (VIR_ALLOC(sound) < 0)
                 goto no_memory;
             sound->model = i;
-            if (prev)
-                prev->next = sound;
-            else
-                def->sounds = sound;
-            prev = sound;
+            def->sounds[def->nsounds++] = sound;
         }
     } else {
         char model[10];
         const char *offset = str, *offset2;
-        virDomainSoundDefPtr prev = NULL;
+
         do {
             int len;
             virDomainSoundDefPtr sound;
@@ -1895,11 +1891,12 @@ xenDaemonParseSxprSound(virConnectPtr conn,
                 goto error;
             }
 
-            if (prev)
-                prev->next = sound;
-            else
-                def->sounds = sound;
-            prev = sound;
+            if (VIR_REALLOC_N(def->sounds, def->nsounds+1) < 0) {
+                virDomainSoundDefFree(sound);
+                goto no_memory;
+            }
+
+            def->sounds[def->nsounds++] = sound;
             offset = offset2 ? offset2 + 1 : NULL;
         } while (offset);
     }
@@ -1918,7 +1915,6 @@ xenDaemonParseSxprUSB(virConnectPtr conn,
                       virDomainDefPtr def,
                       const struct sexpr *root)
 {
-    virDomainInputDefPtr prev = def->inputs;
     struct sexpr *cur, *node;
     const char *tmp;
 
@@ -1938,11 +1934,11 @@ xenDaemonParseSxprUSB(virConnectPtr conn,
                     else
                         input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
 
-                    if (prev)
-                        prev->next = input;
-                    else
-                        def->inputs = input;
-                    prev = input;
+                    if (VIR_REALLOC_N(def->inputs, def->ninputs+1) < 0) {
+                        VIR_FREE(input);
+                        goto no_memory;
+                    }
+                    def->inputs[def->ninputs++] = input;
                 } else {
                     /* XXX Handle other non-input USB devices later */
                 }
@@ -2283,34 +2279,31 @@ xenDaemonParseSxpr(virConnectPtr conn,
         xendConfigVersion == 1) {
         tmp = sexpr_node(root, "domain/image/hvm/cdrom");
         if ((tmp != NULL) && (tmp[0] != 0)) {
-            virDomainDiskDefPtr disk, prev;
+            virDomainDiskDefPtr disk;
             if (VIR_ALLOC(disk) < 0)
                 goto no_memory;
             if (!(disk->src = strdup(tmp))) {
-                VIR_FREE(disk);
+                virDomainDiskDefFree(disk);
                 goto no_memory;
             }
             disk->type = VIR_DOMAIN_DISK_TYPE_FILE;
             disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
             if (!(disk->dst = strdup("hdc"))) {
-                VIR_FREE(disk);
+                virDomainDiskDefFree(disk);
                 goto no_memory;
             }
             if (!(disk->driverName = strdup("file"))) {
-                VIR_FREE(disk);
+                virDomainDiskDefFree(disk);
                 goto no_memory;
             }
             disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
             disk->readonly = 1;
 
-            prev = def->disks;
-            while (prev && prev->next) {
-                prev = prev->next;
+            if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
+                virDomainDiskDefFree(disk);
+                goto no_memory;
             }
-            if (prev)
-                prev->next = disk;
-            else
-                def->disks = disk;
+            def->disks[def->ndisks++] = disk;
         }
     }
 
@@ -2322,7 +2315,7 @@ xenDaemonParseSxpr(virConnectPtr conn,
         for (i = 0 ; i < sizeof(fds)/sizeof(fds[0]) ; i++) {
             tmp = sexpr_fmt_node(root, "domain/image/hvm/%s", fds[i]);
             if ((tmp != NULL) && (tmp[0] != 0)) {
-                virDomainDiskDefPtr disk, prev;
+                virDomainDiskDefPtr disk;
                 if (VIR_ALLOC(disk) < 0)
                     goto no_memory;
                 if (!(disk->src = strdup(tmp))) {
@@ -2332,26 +2325,25 @@ xenDaemonParseSxpr(virConnectPtr conn,
                 disk->type = VIR_DOMAIN_DISK_TYPE_FILE;
                 disk->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
                 if (!(disk->dst = strdup(fds[i]))) {
-                    VIR_FREE(disk);
+                    virDomainDiskDefFree(disk);
                     goto no_memory;
                 }
                 if (!(disk->driverName = strdup("file"))) {
-                    VIR_FREE(disk);
+                    virDomainDiskDefFree(disk);
                     goto no_memory;
                 }
                 disk->bus = VIR_DOMAIN_DISK_BUS_FDC;
 
-                prev = def->disks;
-                while (prev && prev->next) {
-                    prev = prev->next;
+                if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
+                    virDomainDiskDefFree(disk);
+                    goto no_memory;
                 }
-                if (prev)
-                    prev->next = disk;
-                else
-                    def->disks = disk;
+                def->disks[def->ndisks++] = disk;
             }
         }
     }
+    qsort(def->disks, def->ndisks, sizeof(*def->disks),
+          virDomainDiskQSort);
 
     /* in case of HVM we have USB device emulation */
     if (hvm &&
@@ -2363,14 +2355,26 @@ xenDaemonParseSxpr(virConnectPtr conn,
     if (hvm) {
         tmp = sexpr_node(root, "domain/image/hvm/serial");
         if (tmp && STRNEQ(tmp, "none")) {
-            if ((def->serials = xenDaemonParseSxprChar(conn, tmp, tty)) == NULL)
+            virDomainChrDefPtr chr;
+            if ((chr = xenDaemonParseSxprChar(conn, tmp, tty)) == NULL)
                 goto error;
+            if (VIR_REALLOC_N(def->serials, def->nserials+1) < 0) {
+                virDomainChrDefFree(chr);
+                goto no_memory;
+            }
+            def->serials[def->nserials++] = chr;
         }
         tmp = sexpr_node(root, "domain/image/hvm/parallel");
         if (tmp && STRNEQ(tmp, "none")) {
+            virDomainChrDefPtr chr;
             /* XXX does XenD stuff parallel port tty info into xenstore somewhere ? */
-            if ((def->parallels = xenDaemonParseSxprChar(conn, tmp, NULL)) == NULL)
+            if ((chr = xenDaemonParseSxprChar(conn, tmp, NULL)) == NULL)
                 goto error;
+            if (VIR_REALLOC_N(def->parallels, def->nparallels+1) < 0) {
+                virDomainChrDefFree(chr);
+                goto no_memory;
+            }
+            def->parallels[def->nparallels++] = chr;
         }
     } else {
         /* Fake a paravirt console, since that's not in the sexpr */
@@ -4676,9 +4680,8 @@ xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path,
     xenUnifiedPrivatePtr priv;
     struct sexpr *root = NULL;
     int fd = -1, ret = -1;
-    int found = 0;
+    int found = 0, i;
     virDomainDefPtr def;
-    virDomainDiskDefPtr disk;
 
     priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
 
@@ -4707,14 +4710,12 @@ xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path,
     if (!(def = xenDaemonParseSxpr(domain->conn, root, priv->xendConfigVersion, NULL)))
         goto cleanup;
 
-    disk = def->disks;
-    while (disk) {
-        if (disk->src &&
-            STREQ(disk->src, path)) {
+    for (i = 0 ; i < def->ndisks ; i++) {
+        if (def->disks[i]->src &&
+            STREQ(def->disks[i]->src, path)) {
             found = 1;
             break;
         }
-        disk = disk->next;
     }
     if (!found) {
         virXendError (domain->conn, VIR_ERR_INVALID_ARG,
@@ -5161,21 +5162,20 @@ xenDaemonFormatSxprNet(virConnectPtr conn,
 
 int
 xenDaemonFormatSxprSound(virConnectPtr conn,
-                         virDomainSoundDefPtr sound,
+                         virDomainDefPtr def,
                          virBufferPtr buf)
 {
     const char *str;
-    virDomainSoundDefPtr prev = NULL;
+    int i;
 
-    while (sound) {
-        if (!(str = virDomainSoundModelTypeToString(sound->model))) {
+    for (i = 0 ; i < def->nsounds ; i++) {
+        if (!(str = virDomainSoundModelTypeToString(def->sounds[i]->model))) {
             virXendError(conn, VIR_ERR_INTERNAL_ERROR,
-                         _("unexpected sound model %d"), sound->model);
+                         _("unexpected sound model %d"),
+                         def->sounds[i]->model);
             return -1;
         }
-        virBufferVSprintf(buf, "%s%s", prev ? "," : "", str);
-        prev = sound;
-        sound = sound->next;
+        virBufferVSprintf(buf, "%s%s", i ? "," : "", str);
     }
 
     return 0;
@@ -5225,9 +5225,6 @@ xenDaemonFormatSxpr(virConnectPtr conn,
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     const char *tmp;
     int hvm = 0, i;
-    virDomainNetDefPtr net;
-    virDomainDiskDefPtr disk;
-    virDomainInputDefPtr input;
 
     virBufferAddLit(&buf, "(vm ");
     virBufferVSprintf(&buf, "(name '%s')", def->name);
@@ -5339,16 +5336,14 @@ xenDaemonFormatSxpr(virConnectPtr conn,
             /* get the cdrom device file */
             /* Only XenD <= 3.0.2 wants cdrom config here */
             if (xendConfigVersion == 1) {
-                disk = def->disks;
-                while (disk) {
-                    if (disk->type == VIR_DOMAIN_DISK_DEVICE_CDROM &&
-                        STREQ(disk->dst, "hdc") &&
-                        disk->src) {
+                for (i = 0 ; i < def->ndisks ; i++) {
+                    if (def->disks[i]->type == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+                        STREQ(def->disks[i]->dst, "hdc") &&
+                        def->disks[i]->src) {
                         virBufferVSprintf(&buf, "(cdrom '%s')",
-                                          disk->src);
+                                          def->disks[i]->src);
                         break;
                     }
-                    disk = disk->next;
                 }
             }
 
@@ -5361,16 +5356,13 @@ xenDaemonFormatSxpr(virConnectPtr conn,
 
             virBufferAddLit(&buf, "(usb 1)");
 
-            input = def->inputs;
-            while (input) {
-                if (xenDaemonFormatSxprInput(conn, input, &buf) < 0)
+            for (i = 0 ; i < def->ninputs ; i++)
+                if (xenDaemonFormatSxprInput(conn, def->inputs[i], &buf) < 0)
                     goto error;
-                input = input->next;
-            }
 
             if (def->parallels) {
                 virBufferAddLit(&buf, "(parallel ");
-                if (xenDaemonFormatSxprChr(conn, def->parallels, &buf) < 0)
+                if (xenDaemonFormatSxprChr(conn, def->parallels[0], &buf) < 0)
                     goto error;
                 virBufferAddLit(&buf, ")");
             } else {
@@ -5378,7 +5370,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
             }
             if (def->serials) {
                 virBufferAddLit(&buf, "(serial ");
-                if (xenDaemonFormatSxprChr(conn, def->serials, &buf) < 0)
+                if (xenDaemonFormatSxprChr(conn, def->serials[0], &buf) < 0)
                     goto error;
                 virBufferAddLit(&buf, ")");
             } else {
@@ -5390,7 +5382,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
 
             if (def->sounds) {
                 virBufferAddLit(&buf, "(soundhw '");
-                if (xenDaemonFormatSxprSound(conn, def->sounds, &buf) < 0)
+                if (xenDaemonFormatSxprSound(conn, def, &buf) < 0)
                     goto error;
                 virBufferAddLit(&buf, "')");
             }
@@ -5412,19 +5404,15 @@ xenDaemonFormatSxpr(virConnectPtr conn,
         virBufferAddLit(&buf, "))");
     }
 
-    disk = def->disks;
-    while (disk) {
-        if (xenDaemonFormatSxprDisk(conn, disk, &buf, hvm, xendConfigVersion, 0) < 0)
+    for (i = 0 ; i < def->ndisks ; i++)
+        if (xenDaemonFormatSxprDisk(conn, def->disks[i],
+                                    &buf, hvm, xendConfigVersion, 0) < 0)
             goto error;
-        disk = disk->next;
-    }
 
-    net = def->nets;
-    while (net) {
-        if (xenDaemonFormatSxprNet(conn, net, &buf, hvm, xendConfigVersion, 0) < 0)
+    for (i = 0 ; i < def->nnets ; i++)
+        if (xenDaemonFormatSxprNet(conn, def->nets[i],
+                                   &buf, hvm, xendConfigVersion, 0) < 0)
             goto error;
-        net = net->next;
-    }
 
     /* New style PV graphics config xen >= 3.0.4,
      * or HVM graphics config xen >= 3.0.5 */
index e87a844cb9a12d6e30bdbbe4c1eb5e99193c1234..ad0dcbda9bce131a185068b819f53bf9bc724bf8 100644 (file)
@@ -115,7 +115,7 @@ xenDaemonFormatSxprChr(virConnectPtr conn,
                        virBufferPtr buf);
 int
 xenDaemonFormatSxprSound(virConnectPtr conn,
-                         virDomainSoundDefPtr sound,
+                         virDomainDefPtr def,
                          virBufferPtr buf);
 
 char *
index d1cd21672c55eb8acea4780cf045f5bfc18b8ec5..e117a362cc80a962fee18d29ec754e81882bb1f8 100644 (file)
@@ -51,8 +51,6 @@
 
 static int xenXMConfigSetString(virConfPtr conf, const char *setting,
                                 const char *str);
-static int xenXMDiskCompare(virDomainDiskDefPtr a,
-                            virDomainDiskDefPtr b);
 
 typedef struct xenXMConfCache *xenXMConfCachePtr;
 typedef struct xenXMConfCache {
@@ -872,20 +870,9 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
                 disk->shared = 1;
 
             /* Maintain list in sorted order according to target device name */
-            if (def->disks == NULL) {
-                disk->next = def->disks;
-                def->disks = disk;
-            } else {
-                virDomainDiskDefPtr ptr = def->disks;
-                while (ptr) {
-                    if (!ptr->next || xenXMDiskCompare(disk, ptr->next) < 0) {
-                        disk->next = ptr->next;
-                        ptr->next = disk;
-                        break;
-                    }
-                    ptr = ptr->next;
-                }
-            }
+            if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
+                goto no_memory;
+            def->disks[def->ndisks++] = disk;
             disk = NULL;
 
             skipdisk:
@@ -912,25 +899,14 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
             disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
             disk->readonly = 1;
 
-
-            /* Maintain list in sorted order according to target device name */
-            if (def->disks == NULL) {
-                disk->next = def->disks;
-                def->disks = disk;
-            } else {
-                virDomainDiskDefPtr ptr = def->disks;
-                while (ptr) {
-                    if (!ptr->next || xenXMDiskCompare(disk, ptr->next) < 0) {
-                        disk->next = ptr->next;
-                        ptr->next = disk;
-                        break;
-                    }
-                    ptr = ptr->next;
-                }
-            }
+            if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
+                goto no_memory;
+            def->disks[def->ndisks++] = disk;
             disk = NULL;
         }
     }
+    qsort(def->disks, def->ndisks, sizeof(*def->disks),
+          virDomainDiskQSort);
 
     list = virConfGetValue(conf, "vif");
     if (list && list->type == VIR_CONF_LIST) {
@@ -1048,15 +1024,9 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
                 !(net->model = strdup(model)))
                 goto no_memory;
 
-            if (!def->nets) {
-                net->next = NULL;
-                def->nets = net;
-            } else {
-                virDomainNetDefPtr ptr = def->nets;
-                while (ptr->next)
-                    ptr = ptr->next;
-                ptr->next = net;
-            }
+            if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0)
+                goto no_memory;
+            def->nets[def->nnets++] = net;
             net = NULL;
 
         skipnic:
@@ -1078,7 +1048,12 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
             input->type = STREQ(str, "tablet") ?
                 VIR_DOMAIN_INPUT_TYPE_TABLET :
                 VIR_DOMAIN_INPUT_TYPE_MOUSE;
-            def->inputs = input;
+            if (VIR_ALLOC_N(def->inputs, 1) < 0) {
+                virDomainInputDefFree(input);
+                goto no_memory;
+            }
+            def->inputs[0] = input;
+            def->ninputs = 1;
         }
     }
 
@@ -1196,17 +1171,38 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
     }
 
     if (hvm) {
+        virDomainChrDefPtr chr = NULL;
+
         if (xenXMConfigGetString(conn, conf, "parallel", &str, NULL) < 0)
             goto cleanup;
         if (str && STRNEQ(str, "none") &&
-            !(def->parallels = xenDaemonParseSxprChar(conn, str, NULL)))
+            !(chr = xenDaemonParseSxprChar(conn, str, NULL)))
             goto cleanup;
 
+        if (chr) {
+            if (VIR_ALLOC_N(def->parallels, 1) < 0) {
+                virDomainChrDefFree(chr);
+                goto no_memory;
+            }
+            def->parallels[0] = chr;
+            def->nparallels++;
+            chr = NULL;
+        }
+
         if (xenXMConfigGetString(conn, conf, "serial", &str, NULL) < 0)
             goto cleanup;
         if (str && STRNEQ(str, "none") &&
-            !(def->serials = xenDaemonParseSxprChar(conn, str, NULL)))
+            !(chr = xenDaemonParseSxprChar(conn, str, NULL)))
             goto cleanup;
+
+        if (chr) {
+            if (VIR_ALLOC_N(def->serials, 1) < 0) {
+                virDomainChrDefFree(chr);
+                goto no_memory;
+            }
+            def->serials[0] = chr;
+            def->nserials++;
+        }
     } else {
         if (!(def->console = xenDaemonParseSxprChar(conn, "pty", NULL)))
             goto cleanup;
@@ -1805,8 +1801,6 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
     char *cpus = NULL;
     const char *lifecycle;
     char uuid[VIR_UUID_STRING_BUFLEN];
-    virDomainDiskDefPtr disk;
-    virDomainNetDefPtr net;
     virConfValuePtr diskVal = NULL;
     virConfValuePtr netVal = NULL;
 
@@ -1899,15 +1893,16 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
             goto no_memory;
 
         if (priv->xendConfigVersion == 1) {
-            disk = def->disks;
-            while (disk) {
-                if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
-                    disk->dst && STREQ(disk->dst, "hdc") && disk->src) {
-                    if (xenXMConfigSetString(conf, "cdrom", disk->src) < 0)
+            for (i = 0 ; i < def->ndisks ; i++) {
+                if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+                    def->disks[i]->dst &&
+                    STREQ(def->disks[i]->dst, "hdc") &&
+                    def->disks[i]->src) {
+                    if (xenXMConfigSetString(conf, "cdrom",
+                                             def->disks[i]->src) < 0)
                         goto no_memory;
                     break;
                 }
-                disk = disk->next;
             }
         }
 
@@ -1960,23 +1955,20 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
 
 
     if (hvm) {
-        virDomainInputDefPtr input;
         if (def->emulator &&
             xenXMConfigSetString(conf, "device_model", def->emulator) < 0)
             goto no_memory;
 
-        input = def->inputs;
-        while (input) {
-            if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
+        for (i = 0 ; i < def->ninputs ; i++) {
+            if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
                 if (xenXMConfigSetInt(conf, "usb", 1) < 0)
                     goto no_memory;
                 if (xenXMConfigSetString(conf, "usbdevice",
-                                         input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
+                                         def->inputs[i]->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
                                          "mouse" : "tablet") < 0)
                     goto no_memory;
                 break;
             }
-            input = input->next;
         }
     }
 
@@ -2076,27 +2068,24 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
     }
 
     /* analyze of the devices */
-    disk = def->disks;
     if (VIR_ALLOC(diskVal) < 0)
         goto no_memory;
     diskVal->type = VIR_CONF_LIST;
     diskVal->list = NULL;
 
-    while (disk) {
+    for (i = 0 ; i < def->ndisks ; i++) {
         if (priv->xendConfigVersion == 1 &&
-            disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
-            disk->dst && STREQ(disk->dst, "hdc")) {
-            disk = disk->next;
+            def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+            def->disks[i]->dst &&
+            STREQ(def->disks[i]->dst, "hdc")) {
             continue;
         }
-        if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
+        if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
             continue;
 
-        if (xenXMDomainConfigFormatDisk(conn, diskVal, disk,
+        if (xenXMDomainConfigFormatDisk(conn, diskVal, def->disks[i],
                                         hvm, priv->xendConfigVersion) < 0)
             goto cleanup;
-
-        disk = disk->next;
     }
     if (diskVal->list == NULL)
         VIR_FREE(diskVal);
@@ -2107,18 +2096,16 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
     diskVal = NULL;
 
 
-    net = def->nets;
     if (VIR_ALLOC(netVal) < 0)
         goto no_memory;
     netVal->type = VIR_CONF_LIST;
     netVal->list = NULL;
 
-    while (net) {
-        if (xenXMDomainConfigFormatNet(conn, netVal, net,
+    for (i = 0 ; i < def->nnets ; i++) {
+        if (xenXMDomainConfigFormatNet(conn, netVal,
+                                       def->nets[i],
                                        hvm) < 0)
             goto cleanup;
-
-        net = net->next;
     }
     if (netVal->list == NULL)
         VIR_FREE(netVal);
@@ -2129,12 +2116,12 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
     netVal = NULL;
 
     if (hvm) {
-        if (def->parallels) {
+        if (def->nparallels) {
             virBuffer buf = VIR_BUFFER_INITIALIZER;
             char *str;
             int ret;
 
-            ret = xenDaemonFormatSxprChr(conn, def->parallels, &buf);
+            ret = xenDaemonFormatSxprChr(conn, def->parallels[0], &buf);
             str = virBufferContentAndReset(&buf);
             if (ret == 0)
                 ret = xenXMConfigSetString(conf, "parallel", str);
@@ -2146,12 +2133,12 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
                 goto no_memory;
         }
 
-        if (def->serials) {
+        if (def->nserials) {
             virBuffer buf = VIR_BUFFER_INITIALIZER;
             char *str;
             int ret;
 
-            ret = xenDaemonFormatSxprChr(conn, def->serials, &buf);
+            ret = xenDaemonFormatSxprChr(conn, def->serials[0], &buf);
             str = virBufferContentAndReset(&buf);
             if (ret == 0)
                 ret = xenXMConfigSetString(conf, "serial", str);
@@ -2168,7 +2155,7 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
             virBuffer buf = VIR_BUFFER_INITIALIZER;
             char *str = NULL;
             int ret = xenDaemonFormatSxprSound(conn,
-                                               def->sounds,
+                                               def,
                                                &buf);
             str = virBufferContentAndReset(&buf);
             if (ret == 0)
@@ -2417,14 +2404,6 @@ int xenXMNumOfDefinedDomains(virConnectPtr conn) {
     return virHashSize(nameConfigMap);
 }
 
-static int xenXMDiskCompare(virDomainDiskDefPtr a,
-                            virDomainDiskDefPtr b) {
-    if (a->bus == b->bus)
-        return virDiskNameToIndex(a->dst) - virDiskNameToIndex(b->dst);
-    else
-        return a->bus - b->bus;
-}
-
 
 /**
  * xenXMDomainAttachDevice:
@@ -2442,6 +2421,7 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) {
     xenXMConfCachePtr entry = NULL;
     int ret = -1;
     virDomainDeviceDefPtr dev = NULL;
+    virDomainDefPtr def;
 
     if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) {
         xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
@@ -2457,6 +2437,7 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) {
         return -1;
     if (!(entry = virHashLookup(configCache, filename)))
         return -1;
+    def = entry->def;
 
     if (!(dev = virDomainDeviceDefParse(domain->conn,
                                         entry->def,
@@ -2466,34 +2447,24 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) {
     switch (dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
     {
-        /* Maintain list in sorted order according to target device name */
-        if (entry->def->disks == NULL) {
-            dev->data.disk->next = entry->def->disks;
-            entry->def->disks = dev->data.disk;
-        } else {
-            virDomainDiskDefPtr ptr = entry->def->disks;
-            while (ptr) {
-                if (!ptr->next || xenXMDiskCompare(dev->data.disk, ptr->next) < 0) {
-                    dev->data.disk->next = ptr->next;
-                    ptr->next = dev->data.disk;
-                    break;
-                }
-                ptr = ptr->next;
-            }
+        if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
+            xenXMError(domain->conn, VIR_ERR_NO_MEMORY, NULL);
+            goto cleanup;
         }
+        def->disks[def->ndisks++] = dev->data.disk;
         dev->data.disk = NULL;
+        qsort(def->disks, def->ndisks, sizeof(*def->disks),
+              virDomainDiskQSort);
     }
     break;
 
     case VIR_DOMAIN_DEVICE_NET:
     {
-        virDomainNetDefPtr net = entry->def->nets;
-        while (net && net->next)
-            net = net->next;
-        if (net)
-            net->next = dev->data.net;
-        else
-            entry->def->nets = dev->data.net;
+        if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0) {
+            xenXMError(domain->conn, VIR_ERR_NO_MEMORY, NULL);
+            goto cleanup;
+        }
+        def->nets[def->nnets++] = dev->data.net;
         dev->data.net = NULL;
         break;
     }
@@ -2555,7 +2526,9 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) {
     const char *filename = NULL;
     xenXMConfCachePtr entry = NULL;
     virDomainDeviceDefPtr dev = NULL;
+    virDomainDefPtr def;
     int ret = -1;
+    int i;
 
     if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) {
         xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
@@ -2570,6 +2543,7 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) {
         return -1;
     if (!(entry = virHashLookup(configCache, filename)))
         return -1;
+    def = entry->def;
 
     if (!(dev = virDomainDeviceDefParse(domain->conn,
                                         entry->def,
@@ -2579,42 +2553,34 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) {
     switch (dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
     {
-        virDomainDiskDefPtr disk = entry->def->disks;
-        virDomainDiskDefPtr prev = NULL;
-        while (disk) {
-            if (disk->dst &&
+        for (i = 0 ; i < def->ndisks ; i++) {
+            if (def->disks[i]->dst &&
                 dev->data.disk->dst &&
-                STREQ(disk->dst, dev->data.disk->dst)) {
-                if (prev) {
-                    prev->next = disk->next;
-                } else {
-                    entry->def->disks = disk->next;
-                }
-                virDomainDiskDefFree(disk);
+                STREQ(def->disks[i]->dst, dev->data.disk->dst)) {
+                virDomainDiskDefFree(def->disks[i]);
+                if (i < (def->ndisks - 1))
+                    memmove(def->disks + i,
+                            def->disks + i + 1,
+                            def->ndisks - (i + 1));
                 break;
             }
-            prev = disk;
-            disk = disk->next;
         }
         break;
     }
 
     case VIR_DOMAIN_DEVICE_NET:
     {
-        virDomainNetDefPtr net = entry->def->nets;
-        virDomainNetDefPtr prev = NULL;
-        while (net) {
-            if (!memcmp(net->mac, dev->data.net->mac, VIR_DOMAIN_NET_MAC_SIZE)) {
-                if (prev) {
-                    prev->next = net->next;
-                } else {
-                    entry->def->nets = net->next;
-                }
-                virDomainNetDefFree(net);
+        for (i = 0 ; i < def->nnets ; i++) {
+            if (!memcmp(def->nets[i]->mac,
+                        dev->data.net->mac,
+                        VIR_DOMAIN_NET_MAC_SIZE)) {
+                virDomainNetDefFree(def->nets[i]);
+                if (i < (def->nnets - 1))
+                    memmove(def->nets + i,
+                            def->nets + i + 1,
+                            def->nnets - (i + 1));
                 break;
             }
-            prev = net;
-            net = net->next;
         }
         break;
     }
index 144a57a8335f0f03c58f361aee7b98bfdbca7d6b..1014d7660d967337814a5ddb623b99fc7eae7714 100644 (file)
   <on_crash>restart</on_crash>
   <devices>
     <emulator>/usr/lib64/xen/bin/qemu-dm</emulator>
+    <disk type='file' device='disk'>
+      <driver name='file'/>
+      <source file='/root/foo.img'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
     <disk type='file' device='cdrom'>
       <driver name='file'/>
       <source file='/root/boot.iso'/>
       <target dev='hdc' bus='ide'/>
       <readonly/>
     </disk>
-    <disk type='file' device='disk'>
-      <driver name='file'/>
-      <source file='/root/foo.img'/>
-      <target dev='hda' bus='ide'/>
-    </disk>
     <interface type='bridge'>
       <mac address='00:16:3e:1b:b1:47'/>
       <source bridge='xenbr0'/>