+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,
if (!def)
return;
- virDomainInputDefFree(def->next);
VIR_FREE(def);
}
VIR_FREE(def->driverName);
VIR_FREE(def->driverType);
- virDomainDiskDefFree(def->next);
VIR_FREE(def);
}
VIR_FREE(def->src);
VIR_FREE(def->dst);
- virDomainFSDefFree(def->next);
VIR_FREE(def);
}
}
VIR_FREE(def->ifname);
- virDomainNetDefFree(def->next);
VIR_FREE(def);
}
break;
}
- virDomainChrDefFree(def->next);
VIR_FREE(def);
}
if (!def)
return;
- virDomainSoundDefFree(def->next);
VIR_FREE(def);
}
return;
VIR_FREE(def->target);
- virDomainHostdevDefFree(def->next);
VIR_FREE(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);
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,
"%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 */
"%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);
"%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);
"%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);
"%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);
* 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);
* 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;
}
"%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]);
continue;
}
- input->next = def->inputs;
- def->inputs = input;
+ def->inputs[def->ninputs++] = input;
}
VIR_FREE(nodes);
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++;
}
"%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);
"%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);
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;
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;
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");
char *driverType;
unsigned int readonly : 1;
unsigned int shared : 1;
-
- virDomainDiskDefPtr next;
};
char *src;
char *dst;
unsigned int readonly : 1;
-
- virDomainFSDefPtr next;
};
} bridge;
} data;
char *ifname;
-
- virDomainNetDefPtr next;
};
enum virDomainChrSrcType {
int listen;
} nix;
} data;
-
- virDomainChrDefPtr next;
};
enum virDomainInputType {
struct _virDomainInputDef {
int type;
int bus;
- virDomainInputDefPtr next;
};
enum virDomainSoundModel {
typedef virDomainSoundDef *virDomainSoundDefPtr;
struct _virDomainSoundDef {
int model;
- virDomainSoundDefPtr next;
};
/* 3 possible graphics console modes */
} caps;
} source;
char* target;
- virDomainHostdevDefPtr next;
};
/* Flags for the 'type' field in next struct */
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;
};
char *cpuset,
int maxcpu);
+int virDomainDiskQSort(const void *a, const void *b);
int virDomainDiskCompare(virDomainDiskDefPtr a,
virDomainDiskDefPtr b);
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);
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;
}
}
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)
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[] = {
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;
}
int rc = -1;
int waitRc;
int childStatus = -1;
- virDomainNetDefPtr net;
virCgroupPtr cgroup;
+ int i;
while (((waitRc = waitpid(vm->pid, &childStatus, 0)) == -1) &&
errno == EINTR)
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) {
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] = "";
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;
}
break;
}
case VIR_DOMAIN_NET_TYPE_BRIDGE:
- bridge = net->data.bridge.brname;
+ bridge = def->nets[i]->data.bridge.brname;
break;
}
}
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))) {
_("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;
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;
} 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);
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);
}
}
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;
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;
}
/* 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)
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))) {
}
}
- if (net->next != NULL)
- if (openvzDomainSetNetwork(conn, vpsid, net->next) < 0) {
- rc = -1;
- goto exit;
- }
-
exit:
cmdExecFree(prog);
VIR_FREE(mac);
virDomainDefPtr vmdef = NULL;
virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL;
+ int i;
const char *prog[OPENVZ_MAX_ARG];
prog[0] = NULL;
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) {
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];
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;
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;
}
}
- 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);
_("unsupported usb disk type for '%s'"), disk->src);
goto error;
}
- disk = disk->next;
continue;
}
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) {
_("unsupported usb disk type for '%s'"), disk->src);
goto error;
}
- disk = disk->next;
continue;
}
if (disk->src) {
snprintf(dev, NAME_MAX, "-%s", "cdrom");
} else {
- disk = disk->next;
continue;
}
} else {
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",
}
}
- 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 &&
}
/* 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);
}
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");
}
/* 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) {
ADD_ARG_LIT(usbdev);
VIR_FREE(usbdev);
}
- hostdev = hostdev->next;
}
if (migrateFrom) {
{
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
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 */
char *cmd, *reply, *safe_path;
char *devname = NULL;
unsigned int qemuCmdFlags;
+ int i;
if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
}
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) {
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,
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);
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);
"%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",
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);
#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,
}
/* 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;
}
{
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,
}
/* 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"));
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;
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;
}
}
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;
!(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++;
}
}
{
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;
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);
}
virDomainDefPtr def,
const struct sexpr *root)
{
- virDomainInputDefPtr prev = def->inputs;
struct sexpr *cur, *node;
const char *tmp;
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 */
}
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;
}
}
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))) {
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 &&
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 */
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;
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,
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;
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);
/* 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;
}
}
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 {
}
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 {
if (def->sounds) {
virBufferAddLit(&buf, "(soundhw '");
- if (xenDaemonFormatSxprSound(conn, def->sounds, &buf) < 0)
+ if (xenDaemonFormatSxprSound(conn, def, &buf) < 0)
goto error;
virBufferAddLit(&buf, "')");
}
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 */
virBufferPtr buf);
int
xenDaemonFormatSxprSound(virConnectPtr conn,
- virDomainSoundDefPtr sound,
+ virDomainDefPtr def,
virBufferPtr buf);
char *
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 {
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:
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) {
!(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:
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;
}
}
}
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;
char *cpus = NULL;
const char *lifecycle;
char uuid[VIR_UUID_STRING_BUFLEN];
- virDomainDiskDefPtr disk;
- virDomainNetDefPtr net;
virConfValuePtr diskVal = NULL;
virConfValuePtr netVal = NULL;
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;
}
}
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;
}
}
}
/* 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);
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);
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);
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);
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *str = NULL;
int ret = xenDaemonFormatSxprSound(conn,
- def->sounds,
+ def,
&buf);
str = virBufferContentAndReset(&buf);
if (ret == 0)
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:
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,
return -1;
if (!(entry = virHashLookup(configCache, filename)))
return -1;
+ def = entry->def;
if (!(dev = virDomainDeviceDefParse(domain->conn,
entry->def,
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;
}
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,
return -1;
if (!(entry = virHashLookup(configCache, filename)))
return -1;
+ def = entry->def;
if (!(dev = virDomainDeviceDefParse(domain->conn,
entry->def,
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;
}
<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'/>