diff --git a/ChangeLog b/ChangeLog index 88a433a42b..c46769e467 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Fri Oct 10 17:03:00 BST 2008 Daniel P. Berrange + + * 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 * src/storage_conf.c, src/storage_conf.h, src/storage_driver.c, diff --git a/src/domain_conf.c b/src/domain_conf.c index d4dfb8b128..f57fb2d146 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -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, " %s\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; - } - chr = def->serials; - while (chr) { - if (virDomainChrDefFormat(conn, &buf, chr, "serial") < 0) + for (n = 0 ; n < def->nnets ; n++) + if (virDomainNetDefFormat(conn, &buf, def->nets[n]) < 0) goto cleanup; - chr = chr->next; - } - chr = def->parallels; - while (chr) { - if (virDomainChrDefFormat(conn, &buf, chr, "parallel") < 0) + for (n = 0 ; n < def->nserials ; n++) + if (virDomainChrDefFormat(conn, &buf, def->serials[n], "serial") < 0) + goto cleanup; + + 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, " \n"); virBufferAddLit(&buf, "\n"); diff --git a/src/domain_conf.h b/src/domain_conf.h index 1a48c8926d..4d193f4e7a 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -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); diff --git a/src/lxc_container.c b/src/lxc_container.c index 7599b75e41..379e0af4c9 100644 --- a/src/lxc_container.c +++ b/src/lxc_container.c @@ -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) diff --git a/src/lxc_controller.c b/src/lxc_controller.c index 4721c80818..c3eca37a9a 100644 --- a/src/lxc_controller.c +++ b/src/lxc_controller.c @@ -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; } diff --git a/src/lxc_driver.c b/src/lxc_driver.c index c790d0a6da..e5e1d6aafd 100644 --- a/src/lxc_driver.c +++ b/src/lxc_driver.c @@ -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; diff --git a/src/openvz_conf.c b/src/openvz_conf.c index ebde99d5ce..a2553d096a 100644 --- a/src/openvz_conf.c +++ b/src/openvz_conf.c @@ -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) diff --git a/src/openvz_driver.c b/src/openvz_driver.c index 9e3b6a6dc1..e3e3cc7fcc 100644 --- a/src/openvz_driver.c +++ b/src/openvz_driver.c @@ -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; diff --git a/src/qemu_conf.c b/src/qemu_conf.c index fdd7256838..673ea6db5b 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -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) { diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 80ece80440..22a81c51f2 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -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")); diff --git a/src/xend_internal.c b/src/xend_internal.c index 0737871fd9..65564d8245 100644 --- a/src/xend_internal.c +++ b/src/xend_internal.c @@ -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 */ diff --git a/src/xend_internal.h b/src/xend_internal.h index e87a844cb9..ad0dcbda9b 100644 --- a/src/xend_internal.h +++ b/src/xend_internal.h @@ -115,7 +115,7 @@ xenDaemonFormatSxprChr(virConnectPtr conn, virBufferPtr buf); int xenDaemonFormatSxprSound(virConnectPtr conn, - virDomainSoundDefPtr sound, + virDomainDefPtr def, virBufferPtr buf); char * diff --git a/src/xm_internal.c b/src/xm_internal.c index d1cd21672c..e117a362cc 100644 --- a/src/xm_internal.c +++ b/src/xm_internal.c @@ -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; } diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-v2.xml b/tests/sexpr2xmldata/sexpr2xml-fv-v2.xml index 144a57a833..1014d7660d 100644 --- a/tests/sexpr2xmldata/sexpr2xml-fv-v2.xml +++ b/tests/sexpr2xmldata/sexpr2xml-fv-v2.xml @@ -18,17 +18,17 @@ restart /usr/lib64/xen/bin/qemu-dm + + + + + - - - - -