Switch domain device objects to array instead of linked list

This commit is contained in:
Daniel P. Berrange 2008-10-10 16:08:01 +00:00
parent 2e53a9912e
commit 427f7a8b09
14 changed files with 471 additions and 534 deletions

View File

@ -1,3 +1,12 @@
Fri Oct 10 17:03:00 BST 2008 Daniel P. Berrange <berrange@redhat.com>
* src/domain_conf.c, src/domain_conf.h, src/lxc_container.c,
src/lxc_controller.c, src/lxc_driver.c, src/openvz_conf.c,
src/openvz_driver.c, src/qemu_conf.c, src/qemu_driver.c,
src/xend_internal.c, src/xend_internal.h, src/xminternal.c:
Switch to using arrays instead of linked lists for devices
* tests/sexpr2xmldata/sexpr2xml-fv-v2.xml: Fix device ordering
Fri Oct 10 15:39:00 BST 2008 Daniel P. Berrange <berrange@redhat.com> 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, * src/storage_conf.c, src/storage_conf.h, src/storage_driver.c,

View File

@ -209,7 +209,6 @@ void virDomainInputDefFree(virDomainInputDefPtr def)
if (!def) if (!def)
return; return;
virDomainInputDefFree(def->next);
VIR_FREE(def); VIR_FREE(def);
} }
@ -223,7 +222,6 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
VIR_FREE(def->driverName); VIR_FREE(def->driverName);
VIR_FREE(def->driverType); VIR_FREE(def->driverType);
virDomainDiskDefFree(def->next);
VIR_FREE(def); VIR_FREE(def);
} }
@ -235,7 +233,6 @@ void virDomainFSDefFree(virDomainFSDefPtr def)
VIR_FREE(def->src); VIR_FREE(def->src);
VIR_FREE(def->dst); VIR_FREE(def->dst);
virDomainFSDefFree(def->next);
VIR_FREE(def); VIR_FREE(def);
} }
@ -269,7 +266,6 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
} }
VIR_FREE(def->ifname); VIR_FREE(def->ifname);
virDomainNetDefFree(def->next);
VIR_FREE(def); VIR_FREE(def);
} }
@ -303,7 +299,6 @@ void virDomainChrDefFree(virDomainChrDefPtr def)
break; break;
} }
virDomainChrDefFree(def->next);
VIR_FREE(def); VIR_FREE(def);
} }
@ -312,7 +307,6 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def)
if (!def) if (!def)
return; return;
virDomainSoundDefFree(def->next);
VIR_FREE(def); VIR_FREE(def);
} }
@ -322,7 +316,6 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def)
return; return;
VIR_FREE(def->target); VIR_FREE(def->target);
virDomainHostdevDefFree(def->next);
VIR_FREE(def); VIR_FREE(def);
} }
@ -354,19 +347,45 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
void virDomainDefFree(virDomainDefPtr def) void virDomainDefFree(virDomainDefPtr def)
{ {
unsigned int i;
if (!def) if (!def)
return; return;
virDomainGraphicsDefFree(def->graphics); virDomainGraphicsDefFree(def->graphics);
virDomainInputDefFree(def->inputs);
virDomainDiskDefFree(def->disks); for (i = 0 ; i < def->ninputs ; i++)
virDomainFSDefFree(def->fss); virDomainInputDefFree(def->inputs[i]);
virDomainNetDefFree(def->nets); VIR_FREE(def->inputs);
virDomainChrDefFree(def->serials);
virDomainChrDefFree(def->parallels); 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); 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.type);
VIR_FREE(def->os.arch); VIR_FREE(def->os.arch);
@ -1677,6 +1696,14 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn,
return NULL; 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, static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
virCapsPtr caps, virCapsPtr caps,
@ -1918,36 +1945,18 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
"%s", _("cannot extract disk devices")); "%s", _("cannot extract disk devices"));
goto error; goto error;
} }
if (n && VIR_ALLOC_N(def->disks, n) < 0)
goto no_memory;
for (i = 0 ; i < n ; i++) { for (i = 0 ; i < n ; i++) {
virDomainDiskDefPtr disk = virDomainDiskDefParseXML(conn, virDomainDiskDefPtr disk = virDomainDiskDefParseXML(conn,
nodes[i]); nodes[i]);
if (!disk) if (!disk)
goto error; goto error;
/* Maintain list in sorted order according to target device name */ def->disks[def->ndisks++] = disk;
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;
}
} }
qsort(def->disks, def->ndisks, sizeof(*def->disks),
virDomainDiskQSort);
VIR_FREE(nodes); VIR_FREE(nodes);
/* analysis of the filesystems */ /* analysis of the filesystems */
@ -1956,14 +1965,15 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
"%s", _("cannot extract filesystem devices")); "%s", _("cannot extract filesystem devices"));
goto error; 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, virDomainFSDefPtr fs = virDomainFSDefParseXML(conn,
nodes[i]); nodes[i]);
if (!fs) if (!fs)
goto error; goto error;
fs->next = def->fss; def->fss[def->nfss++] = fs;
def->fss = fs;
} }
VIR_FREE(nodes); VIR_FREE(nodes);
@ -1973,14 +1983,15 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
"%s", _("cannot extract network devices")); "%s", _("cannot extract network devices"));
goto error; 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, virDomainNetDefPtr net = virDomainNetDefParseXML(conn,
nodes[i]); nodes[i]);
if (!net) if (!net)
goto error; goto error;
net->next = def->nets; def->nets[def->nnets++] = net;
def->nets = net;
} }
VIR_FREE(nodes); VIR_FREE(nodes);
@ -1991,15 +2002,17 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
"%s", _("cannot extract parallel devices")); "%s", _("cannot extract parallel devices"));
goto error; 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, virDomainChrDefPtr chr = virDomainChrDefParseXML(conn,
nodes[i]); nodes[i]);
if (!chr) if (!chr)
goto error; goto error;
chr->dstPort = i; chr->dstPort = i;
chr->next = def->parallels; def->parallels[def->nparallels++] = chr;
def->parallels = chr;
} }
VIR_FREE(nodes); VIR_FREE(nodes);
@ -2008,15 +2021,17 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
"%s", _("cannot extract serial devices")); "%s", _("cannot extract serial devices"));
goto error; 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, virDomainChrDefPtr chr = virDomainChrDefParseXML(conn,
nodes[i]); nodes[i]);
if (!chr) if (!chr)
goto error; goto error;
chr->dstPort = i; chr->dstPort = i;
chr->next = def->serials; def->serials[def->nserials++] = chr;
def->serials = chr;
} }
VIR_FREE(nodes); VIR_FREE(nodes);
@ -2024,7 +2039,7 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
* If no serial devices were listed, then look for console * If no serial devices were listed, then look for console
* devices which is the legacy syntax for the same thing * 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) { if ((node = virXPathNode(conn, "./devices/console[1]", ctxt)) != NULL) {
virDomainChrDefPtr chr = virDomainChrDefParseXML(conn, virDomainChrDefPtr chr = virDomainChrDefParseXML(conn,
node); node);
@ -2037,8 +2052,12 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
* while for non-HVM it was a parvirt console * while for non-HVM it was a parvirt console
*/ */
if (STREQ(def->os.type, "hvm")) { if (STREQ(def->os.type, "hvm")) {
chr->next = def->serials; if (VIR_ALLOC_N(def->serials, 1) < 0) {
def->serials = chr; virDomainChrDefFree(chr);
goto no_memory;
}
def->nserials = 1;
def->serials[0] = chr;
} else { } else {
def->console = chr; def->console = chr;
} }
@ -2052,7 +2071,10 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
"%s", _("cannot extract input devices")); "%s", _("cannot extract input devices"));
goto error; 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, virDomainInputDefPtr input = virDomainInputDefParseXML(conn,
def->os.type, def->os.type,
nodes[i]); nodes[i]);
@ -2073,8 +2095,7 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
continue; continue;
} }
input->next = def->inputs; def->inputs[def->ninputs++] = input;
def->inputs = input;
} }
VIR_FREE(nodes); VIR_FREE(nodes);
@ -2109,8 +2130,13 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE; input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
input->bus = VIR_DOMAIN_INPUT_BUS_XEN; 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")); "%s", _("cannot extract sound devices"));
goto error; goto error;
} }
for (i = n - 1 ; i >= 0 ; i--) { if (n && VIR_ALLOC_N(def->sounds, n) < 0)
int collision = 0; goto no_memory;
virDomainSoundDefPtr check; for (i = 0 ; i < n ; i++) {
int collision = 0, j;
virDomainSoundDefPtr sound = virDomainSoundDefParseXML(conn, virDomainSoundDefPtr sound = virDomainSoundDefParseXML(conn,
nodes[i]); nodes[i]);
if (!sound) if (!sound)
goto error; goto error;
/* Verify there's no duplicated sound card */ /* Verify there's no duplicated sound card */
check = def->sounds; for (j = 0 ; j < def->nsounds ; j++) {
while (check) { if (def->sounds[j]->model == sound->model)
if (check->model == sound->model)
collision = 1; collision = 1;
check = check->next;
} }
if (collision) { if (collision) {
virDomainSoundDefFree(sound); virDomainSoundDefFree(sound);
continue; continue;
} }
sound->next = def->sounds; def->sounds[def->nsounds++] = sound;
def->sounds = sound;
} }
VIR_FREE(nodes); VIR_FREE(nodes);
@ -2151,18 +2175,23 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
"%s", _("cannot extract host devices")); "%s", _("cannot extract host devices"));
goto error; goto error;
} }
if (n && VIR_ALLOC_N(def->hostdevs, n) < 0)
goto no_memory;
for (i = 0 ; i < n ; i++) { for (i = 0 ; i < n ; i++) {
virDomainHostdevDefPtr hostdev = virDomainHostdevDefParseXML(conn, nodes[i]); virDomainHostdevDefPtr hostdev = virDomainHostdevDefParseXML(conn, nodes[i]);
if (!hostdev) if (!hostdev)
goto error; goto error;
hostdev->next = def->hostdevs; def->hostdevs[def->nhostdevs++] = hostdev;
def->hostdevs = hostdev;
} }
VIR_FREE(nodes); VIR_FREE(nodes);
return def; return def;
no_memory:
virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL);
/* fallthrough */
error: error:
VIR_FREE(tmp); VIR_FREE(tmp);
VIR_FREE(nodes); VIR_FREE(nodes);
@ -2953,13 +2982,6 @@ char *virDomainDefFormat(virConnectPtr conn,
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
unsigned char *uuid; unsigned char *uuid;
char uuidstr[VIR_UUID_STRING_BUFLEN]; 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; const char *type = NULL, *tmp;
int n, allones = 1; int n, allones = 1;
@ -3096,67 +3118,49 @@ char *virDomainDefFormat(virConnectPtr conn,
virBufferEscapeString(&buf, " <emulator>%s</emulator>\n", virBufferEscapeString(&buf, " <emulator>%s</emulator>\n",
def->emulator); def->emulator);
disk = def->disks; for (n = 0 ; n < def->ndisks ; n++)
while (disk) { if (virDomainDiskDefFormat(conn, &buf, def->disks[n]) < 0)
if (virDomainDiskDefFormat(conn, &buf, disk) < 0)
goto cleanup; goto cleanup;
disk = disk->next;
}
fs = def->fss; for (n = 0 ; n < def->nfss ; n++)
while (fs) { if (virDomainFSDefFormat(conn, &buf, def->fss[n]) < 0)
if (virDomainFSDefFormat(conn, &buf, fs) < 0)
goto cleanup; goto cleanup;
fs = fs->next;
}
net = def->nets;
while (net) {
if (virDomainNetDefFormat(conn, &buf, net) < 0)
goto cleanup;
net = net->next;
}
chr = def->serials; for (n = 0 ; n < def->nnets ; n++)
while (chr) { if (virDomainNetDefFormat(conn, &buf, def->nets[n]) < 0)
if (virDomainChrDefFormat(conn, &buf, chr, "serial") < 0)
goto cleanup; goto cleanup;
chr = chr->next;
}
chr = def->parallels; for (n = 0 ; n < def->nserials ; n++)
while (chr) { if (virDomainChrDefFormat(conn, &buf, def->serials[n], "serial") < 0)
if (virDomainChrDefFormat(conn, &buf, chr, "parallel") < 0) goto cleanup;
for (n = 0 ; n < def->nparallels ; n++)
if (virDomainChrDefFormat(conn, &buf, def->parallels[n], "parallel") < 0)
goto cleanup; goto cleanup;
chr = chr->next;
}
/* If there's a PV console that's preferred.. */ /* If there's a PV console that's preferred.. */
if (def->console) { if (def->console) {
if (virDomainChrDefFormat(conn, &buf, def->console, "console") < 0) if (virDomainChrDefFormat(conn, &buf, def->console, "console") < 0)
goto cleanup; goto cleanup;
} else if (def->serials != NULL) { } else if (def->nserials != 0) {
/* ..else for legacy compat duplicate the serial device as a console */ /* ..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; goto cleanup;
} }
input = def->inputs; for (n = 0 ; n < def->ninputs ; n++)
while (input) { if (def->inputs[n]->bus == VIR_DOMAIN_INPUT_BUS_USB &&
if (input->bus == VIR_DOMAIN_INPUT_BUS_USB && virDomainInputDefFormat(conn, &buf, def->inputs[n]) < 0)
virDomainInputDefFormat(conn, &buf, input) < 0)
goto cleanup; goto cleanup;
input = input->next;
}
if (def->graphics) { if (def->graphics) {
/* If graphics is enabled, add the implicit mouse */ /* If graphics is enabled, add the implicit mouse */
virDomainInputDef autoInput = { virDomainInputDef autoInput = {
VIR_DOMAIN_INPUT_TYPE_MOUSE, VIR_DOMAIN_INPUT_TYPE_MOUSE,
STREQ(def->os.type, "hvm") ? STREQ(def->os.type, "hvm") ?
VIR_DOMAIN_INPUT_BUS_PS2 : VIR_DOMAIN_INPUT_BUS_XEN, VIR_DOMAIN_INPUT_BUS_PS2 : VIR_DOMAIN_INPUT_BUS_XEN
NULL }; };
if (virDomainInputDefFormat(conn, &buf, &autoInput) < 0) if (virDomainInputDefFormat(conn, &buf, &autoInput) < 0)
goto cleanup; goto cleanup;
@ -3165,19 +3169,13 @@ char *virDomainDefFormat(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
sound = def->sounds; for (n = 0 ; n < def->nsounds ; n++)
while(sound) { if (virDomainSoundDefFormat(conn, &buf, def->sounds[n]) < 0)
if (virDomainSoundDefFormat(conn, &buf, sound) < 0)
goto cleanup; goto cleanup;
sound = sound->next;
}
hostdev = def->hostdevs; for (n = 0 ; n < def->nhostdevs ; n++)
while (hostdev) { if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n]) < 0)
if (virDomainHostdevDefFormat(conn, &buf, hostdev) < 0)
goto cleanup; goto cleanup;
hostdev = hostdev->next;
}
virBufferAddLit(&buf, " </devices>\n"); virBufferAddLit(&buf, " </devices>\n");
virBufferAddLit(&buf, "</domain>\n"); virBufferAddLit(&buf, "</domain>\n");

View File

@ -90,8 +90,6 @@ struct _virDomainDiskDef {
char *driverType; char *driverType;
unsigned int readonly : 1; unsigned int readonly : 1;
unsigned int shared : 1; unsigned int shared : 1;
virDomainDiskDefPtr next;
}; };
@ -112,8 +110,6 @@ struct _virDomainFSDef {
char *src; char *src;
char *dst; char *dst;
unsigned int readonly : 1; unsigned int readonly : 1;
virDomainFSDefPtr next;
}; };
@ -158,8 +154,6 @@ struct _virDomainNetDef {
} bridge; } bridge;
} data; } data;
char *ifname; char *ifname;
virDomainNetDefPtr next;
}; };
enum virDomainChrSrcType { enum virDomainChrSrcType {
@ -211,8 +205,6 @@ struct _virDomainChrDef {
int listen; int listen;
} nix; } nix;
} data; } data;
virDomainChrDefPtr next;
}; };
enum virDomainInputType { enum virDomainInputType {
@ -235,7 +227,6 @@ typedef virDomainInputDef *virDomainInputDefPtr;
struct _virDomainInputDef { struct _virDomainInputDef {
int type; int type;
int bus; int bus;
virDomainInputDefPtr next;
}; };
enum virDomainSoundModel { enum virDomainSoundModel {
@ -250,7 +241,6 @@ typedef struct _virDomainSoundDef virDomainSoundDef;
typedef virDomainSoundDef *virDomainSoundDefPtr; typedef virDomainSoundDef *virDomainSoundDefPtr;
struct _virDomainSoundDef { struct _virDomainSoundDef {
int model; int model;
virDomainSoundDefPtr next;
}; };
/* 3 possible graphics console modes */ /* 3 possible graphics console modes */
@ -324,7 +314,6 @@ struct _virDomainHostdevDef {
} caps; } caps;
} source; } source;
char* target; char* target;
virDomainHostdevDefPtr next;
}; };
/* Flags for the 'type' field in next struct */ /* Flags for the 'type' field in next struct */
@ -428,15 +417,34 @@ struct _virDomainDef {
int localtime; int localtime;
/* Only 1 */
virDomainGraphicsDefPtr graphics; virDomainGraphicsDefPtr graphics;
virDomainDiskDefPtr disks;
virDomainFSDefPtr fss; int ndisks;
virDomainNetDefPtr nets; virDomainDiskDefPtr *disks;
virDomainInputDefPtr inputs;
virDomainSoundDefPtr sounds; int nfss;
virDomainHostdevDefPtr hostdevs; virDomainFSDefPtr *fss;
virDomainChrDefPtr serials;
virDomainChrDefPtr parallels; 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; virDomainChrDefPtr console;
}; };
@ -531,6 +539,7 @@ char *virDomainCpuSetFormat(virConnectPtr conn,
char *cpuset, char *cpuset,
int maxcpu); int maxcpu);
int virDomainDiskQSort(const void *a, const void *b);
int virDomainDiskCompare(virDomainDiskDefPtr a, int virDomainDiskCompare(virDomainDiskDefPtr a,
virDomainDiskDefPtr b); virDomainDiskDefPtr b);

View File

@ -365,28 +365,28 @@ static int lxcContainerPopulateDevices(void)
static int lxcContainerMountNewFS(virDomainDefPtr vmDef) static int lxcContainerMountNewFS(virDomainDefPtr vmDef)
{ {
virDomainFSDefPtr tmp; int i;
/* Pull in rest of container's mounts */ /* Pull in rest of container's mounts */
for (tmp = vmDef->fss; tmp; tmp = tmp->next) { for (i = 0 ; i < vmDef->nfss ; i++) {
char *src; char *src;
if (STREQ(tmp->dst, "/")) if (STREQ(vmDef->fss[i]->dst, "/"))
continue; continue;
// XXX fix // XXX fix
if (tmp->type != VIR_DOMAIN_FS_TYPE_MOUNT) if (vmDef->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
continue; 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); lxcError(NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
return -1; return -1;
} }
if (virFileMakePath(tmp->dst) < 0 || if (virFileMakePath(vmDef->fss[i]->dst) < 0 ||
mount(src, tmp->dst, NULL, MS_BIND, NULL) < 0) { mount(src, vmDef->fss[i]->dst, NULL, MS_BIND, NULL) < 0) {
VIR_FREE(src); VIR_FREE(src);
lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("failed to mount %s at %s for container: %s"), _("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; return -1;
} }
VIR_FREE(src); VIR_FREE(src);
@ -479,21 +479,21 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
but with extra stuff mapped in */ but with extra stuff mapped in */
static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef) 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 // 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; continue;
if (mount(tmp->src, if (mount(vmDef->fss[i]->src,
tmp->dst, vmDef->fss[i]->dst,
NULL, NULL,
MS_BIND, MS_BIND,
NULL) < 0) { NULL) < 0) {
lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("failed to mount %s at %s for container: %s"), _("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; return -1;
} }
} }
@ -511,14 +511,14 @@ static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef)
static int lxcContainerSetupMounts(virDomainDefPtr vmDef) static int lxcContainerSetupMounts(virDomainDefPtr vmDef)
{ {
virDomainFSDefPtr tmp; int i;
virDomainFSDefPtr root = NULL; virDomainFSDefPtr root = NULL;
for (tmp = vmDef->fss; tmp && !root; tmp = tmp->next) { for (i = 0 ; i < vmDef->nfss ; i++) {
if (tmp->type != VIR_DOMAIN_FS_TYPE_MOUNT) if (vmDef->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
continue; continue;
if (STREQ(tmp->dst, "/")) if (STREQ(vmDef->fss[i]->dst, "/"))
root = tmp; root = vmDef->fss[i];
} }
if (root) if (root)

View File

@ -499,8 +499,6 @@ int main(int argc, char *argv[])
int bg = 0; int bg = 0;
virCapsPtr caps = NULL; virCapsPtr caps = NULL;
virDomainDefPtr def = NULL; virDomainDefPtr def = NULL;
int nnets = 0;
virDomainNetDefPtr nets = NULL;
char *configFile = NULL; char *configFile = NULL;
char *sockpath = NULL; char *sockpath = NULL;
const struct option const options[] = { const struct option const options[] = {
@ -595,14 +593,9 @@ int main(int argc, char *argv[])
if ((def = virDomainDefParseFile(NULL, caps, configFile)) == NULL) if ((def = virDomainDefParseFile(NULL, caps, configFile)) == NULL)
goto cleanup; goto cleanup;
nets = def->nets; if (def->nnets != nveths) {
while (nets) {
nnets++;
nets = nets->next;
}
if (nnets != nveths) {
fprintf(stderr, "%s: expecting %d veths, but got %d\n", fprintf(stderr, "%s: expecting %d veths, but got %d\n",
argv[0], nnets, nveths); argv[0], def->nnets, nveths);
goto cleanup; goto cleanup;
} }

View File

@ -367,8 +367,8 @@ static int lxcVMCleanup(virConnectPtr conn,
int rc = -1; int rc = -1;
int waitRc; int waitRc;
int childStatus = -1; int childStatus = -1;
virDomainNetDefPtr net;
virCgroupPtr cgroup; virCgroupPtr cgroup;
int i;
while (((waitRc = waitpid(vm->pid, &childStatus, 0)) == -1) && while (((waitRc = waitpid(vm->pid, &childStatus, 0)) == -1) &&
errno == EINTR) errno == EINTR)
@ -398,9 +398,9 @@ static int lxcVMCleanup(virConnectPtr conn,
vm->def->id = -1; vm->def->id = -1;
vm->monitor = -1; vm->monitor = -1;
for (net = vm->def->nets; net; net = net->next) { for (i = 0 ; i < vm->def->nnets ; i++) {
vethInterfaceUpOrDown(net->ifname, 0); vethInterfaceUpOrDown(vm->def->nets[i]->ifname, 0);
vethDelete(net->ifname); vethDelete(vm->def->nets[i]->ifname);
} }
if (virCgroupForDomain(vm->def, "lxc", &cgroup) == 0) { if (virCgroupForDomain(vm->def, "lxc", &cgroup) == 0) {
@ -426,8 +426,7 @@ static int lxcSetupInterfaces(virConnectPtr conn,
unsigned int *nveths, unsigned int *nveths,
char ***veths) char ***veths)
{ {
int rc = -1; int rc = -1, i;
virDomainNetDefPtr net;
char *bridge = NULL; char *bridge = NULL;
char parentVeth[PATH_MAX] = ""; char parentVeth[PATH_MAX] = "";
char containerVeth[PATH_MAX] = ""; char containerVeth[PATH_MAX] = "";
@ -436,12 +435,12 @@ static int lxcSetupInterfaces(virConnectPtr conn,
if (brInit(&brctl) != 0) if (brInit(&brctl) != 0)
return -1; return -1;
for (net = def->nets; net; net = net->next) { for (i = 0 ; i < def->nnets ; i++) {
switch (net->type) { switch (def->nets[i]->type) {
case VIR_DOMAIN_NET_TYPE_NETWORK: case VIR_DOMAIN_NET_TYPE_NETWORK:
{ {
virNetworkPtr network = virNetworkLookupByName(conn, virNetworkPtr network = virNetworkLookupByName(conn,
net->data.network.name); def->nets[i]->data.network.name);
if (!network) { if (!network) {
goto error_exit; goto error_exit;
} }
@ -452,7 +451,7 @@ static int lxcSetupInterfaces(virConnectPtr conn,
break; break;
} }
case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_BRIDGE:
bridge = net->data.bridge.brname; bridge = def->nets[i]->data.bridge.brname;
break; break;
} }
@ -464,8 +463,8 @@ static int lxcSetupInterfaces(virConnectPtr conn,
} }
DEBUG0("calling vethCreate()"); DEBUG0("calling vethCreate()");
if (NULL != net->ifname) { if (NULL != def->nets[i]->ifname) {
strcpy(parentVeth, net->ifname); strcpy(parentVeth, def->nets[i]->ifname);
} }
DEBUG("parentVeth: %s, containerVeth: %s", parentVeth, containerVeth); DEBUG("parentVeth: %s, containerVeth: %s", parentVeth, containerVeth);
if (0 != (rc = vethCreate(parentVeth, PATH_MAX, containerVeth, PATH_MAX))) { 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); _("failed to create veth device pair: %d"), rc);
goto error_exit; goto error_exit;
} }
if (NULL == net->ifname) { if (NULL == def->nets[i]->ifname) {
net->ifname = strdup(parentVeth); def->nets[i]->ifname = strdup(parentVeth);
} }
if (VIR_REALLOC_N(*veths, (*nveths)+1) < 0) if (VIR_REALLOC_N(*veths, (*nveths)+1) < 0)
goto error_exit; goto error_exit;
if (((*veths)[(*nveths)++] = strdup(containerVeth)) == NULL) if (((*veths)[(*nveths)++] = strdup(containerVeth)) == NULL)
goto error_exit; goto error_exit;
if (NULL == net->ifname) { if (NULL == def->nets[i]->ifname) {
lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, lxcError(NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("failed to allocate veth names")); _("failed to allocate veth names"));
goto error_exit; goto error_exit;

View File

@ -149,11 +149,12 @@ static int openvzParseMac(const char *macaddr, unsigned char *mac)
return -1; return -1;
} }
static virDomainNetDefPtr static int
openvzReadNetworkConf(virConnectPtr conn, int veid) { openvzReadNetworkConf(virConnectPtr conn,
virDomainDefPtr def,
int veid) {
int ret; int ret;
virDomainNetDefPtr net = NULL; virDomainNetDefPtr net;
virDomainNetDefPtr new_net;
char temp[4096]; char temp[4096];
char *token, *saveptr = NULL; char *token, *saveptr = NULL;
@ -171,11 +172,8 @@ openvzReadNetworkConf(virConnectPtr conn, int veid) {
} else if (ret > 0) { } else if (ret > 0) {
token = strtok_r(temp, " ", &saveptr); token = strtok_r(temp, " ", &saveptr);
while (token != NULL) { while (token != NULL) {
new_net = NULL; if (VIR_ALLOC(net) < 0)
if (VIR_ALLOC(new_net) < 0)
goto no_memory; goto no_memory;
new_net->next = net;
net = new_net;
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET; net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
net->data.ethernet.ipaddr = strdup(token); net->data.ethernet.ipaddr = strdup(token);
@ -183,6 +181,11 @@ openvzReadNetworkConf(virConnectPtr conn, int veid) {
if (net->data.ethernet.ipaddr == NULL) if (net->data.ethernet.ipaddr == NULL)
goto no_memory; 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(NULL, " ", &saveptr);
} }
} }
@ -202,11 +205,8 @@ openvzReadNetworkConf(virConnectPtr conn, int veid) {
token = strtok_r(temp, ";", &saveptr); token = strtok_r(temp, ";", &saveptr);
while (token != NULL) { while (token != NULL) {
/*add new device to list*/ /*add new device to list*/
new_net = NULL; if (VIR_ALLOC(net) < 0)
if (VIR_ALLOC(new_net) < 0)
goto no_memory; goto no_memory;
new_net->next = net;
net = new_net;
net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; net->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
@ -256,16 +256,21 @@ openvzReadNetworkConf(virConnectPtr conn, int veid) {
p = ++next; p = ++next;
} while (p < token + strlen(token)); } 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); token = strtok_r(NULL, ";", &saveptr);
} }
} }
return net; return 0;
no_memory: no_memory:
openvzError(conn, VIR_ERR_NO_MEMORY, NULL); openvzError(conn, VIR_ERR_NO_MEMORY, NULL);
error: error:
virDomainNetDefFree(net); virDomainNetDefFree(net);
return NULL; return -1;
} }
@ -353,7 +358,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
/* XXX load rest of VM config data .... */ /* 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, if (VIR_REALLOC_N(driver->domains.objs,
driver->domains.count + 1) < 0) driver->domains.count + 1) < 0)

View File

@ -117,21 +117,21 @@ static int openvzDomainDefineCmd(virConnectPtr conn,
ADD_ARG_LIT("create"); ADD_ARG_LIT("create");
ADD_ARG_LIT(vmdef->name); ADD_ARG_LIT(vmdef->name);
if (vmdef->fss) { if (vmdef->nfss) {
if (vmdef->fss->type != VIR_DOMAIN_FS_TYPE_TEMPLATE) { if (vmdef->fss[0]->type != VIR_DOMAIN_FS_TYPE_TEMPLATE) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("only filesystem templates are supported")); "%s", _("only filesystem templates are supported"));
return -1; return -1;
} }
if (vmdef->fss->next) { if (vmdef->nfss > 1) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, openvzError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("only one filesystem supported")); "%s", _("only one filesystem supported"));
return -1; return -1;
} }
ADD_ARG_LIT("--ostemplate"); ADD_ARG_LIT("--ostemplate");
ADD_ARG_LIT(vmdef->fss->src); ADD_ARG_LIT(vmdef->fss[0]->src);
} }
#if 0 #if 0
if ((vmdef->profile && *(vmdef->profile))) { 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: exit:
cmdExecFree(prog); cmdExecFree(prog);
VIR_FREE(mac); VIR_FREE(mac);
@ -422,6 +416,7 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
virDomainDefPtr vmdef = NULL; virDomainDefPtr vmdef = NULL;
virDomainObjPtr vm = NULL; virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
int i;
const char *prog[OPENVZ_MAX_ARG]; const char *prog[OPENVZ_MAX_ARG];
prog[0] = NULL; prog[0] = NULL;
@ -471,10 +466,12 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
if (dom) if (dom)
dom->id = -1; dom->id = -1;
if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets) < 0) { for (i = 0 ; i < vmdef->nnets ; i++) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets[i]) < 0) {
_("Could not configure network")); openvzError(conn, VIR_ERR_INTERNAL_ERROR,
goto exit; _("Could not configure network"));
goto exit;
}
} }
if (vmdef->vcpus > 0) { if (vmdef->vcpus > 0) {
@ -497,6 +494,7 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
virDomainDefPtr vmdef = NULL; virDomainDefPtr vmdef = NULL;
virDomainObjPtr vm = NULL; virDomainObjPtr vm = NULL;
virDomainPtr dom = NULL; virDomainPtr dom = NULL;
int i;
struct openvz_driver *driver = (struct openvz_driver *) conn->privateData; struct openvz_driver *driver = (struct openvz_driver *) conn->privateData;
const char *progstart[] = {VZCTL, "--quiet", "start", NULL, NULL}; const char *progstart[] = {VZCTL, "--quiet", "start", NULL, NULL};
const char *progcreate[OPENVZ_MAX_ARG]; const char *progcreate[OPENVZ_MAX_ARG];
@ -542,10 +540,12 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
goto exit; goto exit;
} }
if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets) < 0) { for (i = 0 ; i < vmdef->nnets ; i++) {
openvzError(conn, VIR_ERR_INTERNAL_ERROR, if (openvzDomainSetNetwork(conn, vmdef->name, vmdef->nets[i]) < 0) {
_("Could not configure network")); openvzError(conn, VIR_ERR_INTERNAL_ERROR,
goto exit; _("Could not configure network"));
goto exit;
}
} }
progstart[3] = vmdef->name; progstart[3] = vmdef->name;

View File

@ -701,13 +701,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
char memory[50]; char memory[50];
char vcpus[50]; char vcpus[50];
char boot[VIR_DOMAIN_BOOT_LAST]; 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; struct utsname ut;
int disableKQEMU = 0; int disableKQEMU = 0;
int qargc = 0, qarga = 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]; char opt[PATH_MAX];
const char *media = NULL; const char *media = NULL;
int bootable = 0; int bootable = 0;
virDomainDiskDefPtr disk = vm->def->disks[i];
int idx = virDiskNameToIndex(disk->dst); int idx = virDiskNameToIndex(disk->dst);
const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus); const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
@ -889,7 +883,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
_("unsupported usb disk type for '%s'"), disk->src); _("unsupported usb disk type for '%s'"), disk->src);
goto error; goto error;
} }
disk = disk->next;
continue; continue;
} }
@ -925,12 +918,12 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ARG_LIT("-drive"); ADD_ARG_LIT("-drive");
ADD_ARG_LIT(opt); ADD_ARG_LIT(opt);
disk = disk->next;
} }
} else { } else {
while (disk) { for (i = 0 ; i < vm->def->ndisks ; i++) {
char dev[NAME_MAX]; char dev[NAME_MAX];
char file[PATH_MAX]; char file[PATH_MAX];
virDomainDiskDefPtr disk = vm->def->disks[i];
if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) { if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
@ -940,7 +933,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
_("unsupported usb disk type for '%s'"), disk->src); _("unsupported usb disk type for '%s'"), disk->src);
goto error; goto error;
} }
disk = disk->next;
continue; continue;
} }
@ -949,7 +941,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
if (disk->src) { if (disk->src) {
snprintf(dev, NAME_MAX, "-%s", "cdrom"); snprintf(dev, NAME_MAX, "-%s", "cdrom");
} else { } else {
disk = disk->next;
continue; continue;
} }
} else { } else {
@ -967,18 +958,17 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ARG_LIT(dev); ADD_ARG_LIT(dev);
ADD_ARG_LIT(file); ADD_ARG_LIT(file);
disk = disk->next;
} }
} }
if (!net) { if (!vm->def->nnets) {
ADD_ARG_LIT("-net"); ADD_ARG_LIT("-net");
ADD_ARG_LIT("none"); ADD_ARG_LIT("none");
} else { } else {
int vlan = 0; int vlan = 0;
while (net) { for (i = 0 ; i < vm->def->nnets ; i++) {
char nic[100]; char nic[100];
virDomainNetDefPtr net = vm->def->nets[i];
if (snprintf(nic, sizeof(nic), if (snprintf(nic, sizeof(nic),
"nic,macaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s", "nic,macaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s",
@ -1059,53 +1049,50 @@ int qemudBuildCommandLine(virConnectPtr conn,
} }
} }
net = net->next;
vlan++; vlan++;
} }
} }
if (!serial) { if (!vm->def->nserials) {
ADD_ARG_LIT("-serial"); ADD_ARG_LIT("-serial");
ADD_ARG_LIT("none"); ADD_ARG_LIT("none");
} else { } else {
while (serial) { for (i = 0 ; i < vm->def->nserials ; i++) {
char buf[4096]; char buf[4096];
virDomainChrDefPtr serial = vm->def->serials[i];
if (qemudBuildCommandLineChrDevStr(serial, buf, sizeof(buf)) < 0) if (qemudBuildCommandLineChrDevStr(serial, buf, sizeof(buf)) < 0)
goto error; goto error;
ADD_ARG_LIT("-serial"); ADD_ARG_LIT("-serial");
ADD_ARG_LIT(buf); ADD_ARG_LIT(buf);
serial = serial->next;
} }
} }
if (!parallel) { if (!vm->def->nparallels) {
ADD_ARG_LIT("-parallel"); ADD_ARG_LIT("-parallel");
ADD_ARG_LIT("none"); ADD_ARG_LIT("none");
} else { } else {
while (parallel) { for (i = 0 ; i < vm->def->nparallels ; i++) {
char buf[4096]; char buf[4096];
virDomainChrDefPtr parallel = vm->def->parallels[i];
if (qemudBuildCommandLineChrDevStr(parallel, buf, sizeof(buf)) < 0) if (qemudBuildCommandLineChrDevStr(parallel, buf, sizeof(buf)) < 0)
goto error; goto error;
ADD_ARG_LIT("-parallel"); ADD_ARG_LIT("-parallel");
ADD_ARG_LIT(buf); ADD_ARG_LIT(buf);
parallel = parallel->next;
} }
} }
ADD_ARG_LIT("-usb"); 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) { if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
ADD_ARG_LIT("-usbdevice"); ADD_ARG_LIT("-usbdevice");
ADD_ARG_LIT(input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? "mouse" : "tablet"); ADD_ARG_LIT(input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
} }
input = input->next;
} }
if (vm->def->graphics && if (vm->def->graphics &&
@ -1151,13 +1138,14 @@ int qemudBuildCommandLine(virConnectPtr conn,
} }
/* Add sound hardware */ /* Add sound hardware */
if (sound) { if (vm->def->nsounds) {
int size = 100; int size = 100;
char *modstr; char *modstr;
if (VIR_ALLOC_N(modstr, size+1) < 0) if (VIR_ALLOC_N(modstr, size+1) < 0)
goto no_memory; 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); const char *model = virDomainSoundModelTypeToString(sound->model);
if (!model) { if (!model) {
VIR_FREE(modstr); VIR_FREE(modstr);
@ -1167,8 +1155,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
} }
strncat(modstr, model, size); strncat(modstr, model, size);
size -= strlen(model); size -= strlen(model);
sound = sound->next; if (i < (vm->def->nsounds - 1))
if (sound)
strncat(modstr, ",", size--); strncat(modstr, ",", size--);
} }
ADD_ARG_LIT("-soundhw"); ADD_ARG_LIT("-soundhw");
@ -1176,9 +1163,10 @@ int qemudBuildCommandLine(virConnectPtr conn,
} }
/* Add host passthrough hardware */ /* Add host passthrough hardware */
while (hostdev) { for (i = 0 ; i < vm->def->nhostdevs ; i++) {
int ret; int ret;
char* usbdev; char* usbdev;
virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
@ -1200,7 +1188,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ARG_LIT(usbdev); ADD_ARG_LIT(usbdev);
VIR_FREE(usbdev); VIR_FREE(usbdev);
} }
hostdev = hostdev->next;
} }
if (migrateFrom) { if (migrateFrom) {

View File

@ -496,8 +496,7 @@ qemudFindCharDevicePTYs(virConnectPtr conn,
{ {
char *monitor = NULL; char *monitor = NULL;
size_t offset = 0; size_t offset = 0;
virDomainChrDefPtr chr; int ret, i;
int ret;
/* The order in which QEMU prints out the PTY paths is /* The order in which QEMU prints out the PTY paths is
the order in which it procsses its monitor, serial the order in which it procsses its monitor, serial
@ -509,25 +508,23 @@ qemudFindCharDevicePTYs(virConnectPtr conn,
goto cleanup; goto cleanup;
/* then the serial devices */ /* then the serial devices */
chr = vm->def->serials; for (i = 0 ; i < vm->def->nserials ; i++) {
while (chr) { virDomainChrDefPtr chr = vm->def->serials[i];
if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) { if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) {
if ((ret = qemudExtractMonitorPath(conn, output, &offset, if ((ret = qemudExtractMonitorPath(conn, output, &offset,
&chr->data.file.path)) != 0) &chr->data.file.path)) != 0)
goto cleanup; goto cleanup;
} }
chr = chr->next;
} }
/* and finally the parallel devices */ /* and finally the parallel devices */
chr = vm->def->parallels; for (i = 0 ; i < vm->def->nparallels ; i++) {
while (chr) { virDomainChrDefPtr chr = vm->def->parallels[i];
if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) { if (chr->type == VIR_DOMAIN_CHR_TYPE_PTY) {
if ((ret = qemudExtractMonitorPath(conn, output, &offset, if ((ret = qemudExtractMonitorPath(conn, output, &offset,
&chr->data.file.path)) != 0) &chr->data.file.path)) != 0)
goto cleanup; goto cleanup;
} }
chr = chr->next;
} }
/* Got them all, so now open the monitor console */ /* Got them all, so now open the monitor console */
@ -2381,6 +2378,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
char *cmd, *reply, *safe_path; char *cmd, *reply, *safe_path;
char *devname = NULL; char *devname = NULL;
unsigned int qemuCmdFlags; unsigned int qemuCmdFlags;
int i;
if (!vm) { if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@ -2389,12 +2387,12 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
} }
newdisk = dev->data.disk; newdisk = dev->data.disk;
origdisk = vm->def->disks; for (i = 0 ; i < vm->def->ndisks ; i++) {
while (origdisk) { if (vm->def->disks[i]->bus == newdisk->bus &&
if (origdisk->bus == newdisk->bus && STREQ(vm->def->disks[i]->dst, newdisk->dst)) {
STREQ(origdisk->dst, newdisk->dst)) origdisk = vm->def->disks[i];
break; break;
origdisk = origdisk->next; }
} }
if (!origdisk) { if (!origdisk) {
@ -2496,7 +2494,6 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid); virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
int ret; int ret;
char *cmd, *reply; char *cmd, *reply;
virDomainDiskDefPtr *dest, *prev, ptr;
if (!vm) { if (!vm) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@ -2504,26 +2501,9 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
return -1; return -1;
} }
/* Find spot in domain definition where we will put the disk */ if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) {
ptr = vm->def->disks; qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
prev = &(vm->def->disks); return -1;
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;
} }
ret = asprintf(&cmd, "usb_add disk:%s", dev->data.disk->src); ret = asprintf(&cmd, "usb_add disk:%s", dev->data.disk->src);
@ -2551,9 +2531,9 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi
return -1; return -1;
} }
/* Actually update the xml */ vm->def->disks[vm->def->ndisks++] = dev->data.disk;
dev->data.disk->next = *dest; qsort(vm->def->disks, vm->def->ndisks, sizeof(*vm->def->disks),
*prev = dev->data.disk; virDomainDiskQSort);
VIR_FREE(reply); VIR_FREE(reply);
VIR_FREE(cmd); VIR_FREE(cmd);
@ -2572,6 +2552,10 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d
"%s", _("no domain with matching uuid")); "%s", _("no domain with matching uuid"));
return -1; 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) { if (dev->data.hostdev->source.subsys.usb.vendor) {
ret = asprintf(&cmd, "usb_add host:%.4x:%.4x", ret = asprintf(&cmd, "usb_add host:%.4x:%.4x",
@ -2606,9 +2590,7 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d
return -1; return -1;
} }
/* Update xml */ vm->def->hostdevs[vm->def->nhostdevs++] = dev->data.hostdev;
dev->data.hostdev->next = vm->def->hostdevs;
vm->def->hostdevs = dev->data.hostdev;
VIR_FREE(reply); VIR_FREE(reply);
VIR_FREE(cmd); VIR_FREE(cmd);
@ -2891,7 +2873,7 @@ qemudDomainInterfaceStats (virDomainPtr dom,
#ifdef __linux__ #ifdef __linux__
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData; struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id); virDomainObjPtr vm = virDomainFindByID(&driver->domains, dom->id);
virDomainNetDefPtr net; int i;
if (!vm) { if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, 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. */ /* Check the path is one of the domain's network interfaces. */
for (net = vm->def->nets; net; net = net->next) { for (i = 0 ; i < vm->def->nnets ; i++) {
if (net->ifname && STREQ (net->ifname, path)) if (vm->def->nets[i]->ifname &&
STREQ (vm->def->nets[i]->ifname, path))
goto ok; goto ok;
} }
@ -2939,8 +2922,7 @@ qemudDomainBlockPeek (virDomainPtr dom,
{ {
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData; struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid); virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
virDomainDiskDefPtr disk; int fd, ret = -1, i;
int fd, ret = -1;
if (!vm) { if (!vm) {
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
@ -2955,9 +2937,10 @@ qemudDomainBlockPeek (virDomainPtr dom,
} }
/* Check the path belongs to this domain. */ /* Check the path belongs to this domain. */
for (disk = vm->def->disks ; disk != NULL ; disk = disk->next) { for (i = 0 ; i < vm->def->ndisks ; i++) {
if (disk->src != NULL && if (vm->def->disks[i]->src != NULL &&
STREQ (disk->src, path)) goto found; STREQ (vm->def->disks[i]->src, path))
goto found;
} }
qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG, qemudReportError (dom->conn, dom, NULL, VIR_ERR_INVALID_ARG,
_("invalid path")); _("invalid path"));

View File

@ -1595,7 +1595,7 @@ xenDaemonParseSxprDisks(virConnectPtr conn,
int xendConfigVersion) int xendConfigVersion)
{ {
const struct sexpr *cur, *node; 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) { for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
node = cur->u.s.car; node = cur->u.s.car;
@ -1729,12 +1729,10 @@ xenDaemonParseSxprDisks(virConnectPtr conn,
strchr(mode, '!')) strchr(mode, '!'))
disk->shared = 1; disk->shared = 1;
if (prev) if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
prev->next = disk; goto no_memory;
else
def->disks = disk;
prev = disk; def->disks[def->ndisks++] = disk;
disk = NULL; disk = NULL;
} }
} }
@ -1755,7 +1753,7 @@ xenDaemonParseSxprNets(virConnectPtr conn,
virDomainDefPtr def, virDomainDefPtr def,
const struct sexpr *root) const struct sexpr *root)
{ {
virDomainNetDefPtr net = NULL, prev = def->nets; virDomainNetDefPtr net = NULL;
const struct sexpr *cur, *node; const struct sexpr *cur, *node;
const char *tmp; const char *tmp;
int vif_index = 0; int vif_index = 0;
@ -1828,12 +1826,10 @@ xenDaemonParseSxprNets(virConnectPtr conn,
!(net->model = strdup(model))) !(net->model = strdup(model)))
goto no_memory; goto no_memory;
if (prev) if (VIR_REALLOC_N(def->nets, def->nnets + 1) < 0)
prev->next = net; goto no_memory;
else
def->nets = net;
prev = net; def->nets[def->nnets++] = net;
vif_index++; vif_index++;
} }
} }
@ -1855,22 +1851,22 @@ xenDaemonParseSxprSound(virConnectPtr conn,
{ {
if (STREQ(str, "all")) { if (STREQ(str, "all")) {
int i; 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++) { for (i = 0 ; i < VIR_DOMAIN_SOUND_MODEL_LAST ; i++) {
virDomainSoundDefPtr sound; virDomainSoundDefPtr sound;
if (VIR_ALLOC(sound) < 0) if (VIR_ALLOC(sound) < 0)
goto no_memory; goto no_memory;
sound->model = i; sound->model = i;
if (prev) def->sounds[def->nsounds++] = sound;
prev->next = sound;
else
def->sounds = sound;
prev = sound;
} }
} else { } else {
char model[10]; char model[10];
const char *offset = str, *offset2; const char *offset = str, *offset2;
virDomainSoundDefPtr prev = NULL;
do { do {
int len; int len;
virDomainSoundDefPtr sound; virDomainSoundDefPtr sound;
@ -1895,11 +1891,12 @@ xenDaemonParseSxprSound(virConnectPtr conn,
goto error; goto error;
} }
if (prev) if (VIR_REALLOC_N(def->sounds, def->nsounds+1) < 0) {
prev->next = sound; virDomainSoundDefFree(sound);
else goto no_memory;
def->sounds = sound; }
prev = sound;
def->sounds[def->nsounds++] = sound;
offset = offset2 ? offset2 + 1 : NULL; offset = offset2 ? offset2 + 1 : NULL;
} while (offset); } while (offset);
} }
@ -1918,7 +1915,6 @@ xenDaemonParseSxprUSB(virConnectPtr conn,
virDomainDefPtr def, virDomainDefPtr def,
const struct sexpr *root) const struct sexpr *root)
{ {
virDomainInputDefPtr prev = def->inputs;
struct sexpr *cur, *node; struct sexpr *cur, *node;
const char *tmp; const char *tmp;
@ -1938,11 +1934,11 @@ xenDaemonParseSxprUSB(virConnectPtr conn,
else else
input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE; input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
if (prev) if (VIR_REALLOC_N(def->inputs, def->ninputs+1) < 0) {
prev->next = input; VIR_FREE(input);
else goto no_memory;
def->inputs = input; }
prev = input; def->inputs[def->ninputs++] = input;
} else { } else {
/* XXX Handle other non-input USB devices later */ /* XXX Handle other non-input USB devices later */
} }
@ -2283,34 +2279,31 @@ xenDaemonParseSxpr(virConnectPtr conn,
xendConfigVersion == 1) { xendConfigVersion == 1) {
tmp = sexpr_node(root, "domain/image/hvm/cdrom"); tmp = sexpr_node(root, "domain/image/hvm/cdrom");
if ((tmp != NULL) && (tmp[0] != 0)) { if ((tmp != NULL) && (tmp[0] != 0)) {
virDomainDiskDefPtr disk, prev; virDomainDiskDefPtr disk;
if (VIR_ALLOC(disk) < 0) if (VIR_ALLOC(disk) < 0)
goto no_memory; goto no_memory;
if (!(disk->src = strdup(tmp))) { if (!(disk->src = strdup(tmp))) {
VIR_FREE(disk); virDomainDiskDefFree(disk);
goto no_memory; goto no_memory;
} }
disk->type = VIR_DOMAIN_DISK_TYPE_FILE; disk->type = VIR_DOMAIN_DISK_TYPE_FILE;
disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM; disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
if (!(disk->dst = strdup("hdc"))) { if (!(disk->dst = strdup("hdc"))) {
VIR_FREE(disk); virDomainDiskDefFree(disk);
goto no_memory; goto no_memory;
} }
if (!(disk->driverName = strdup("file"))) { if (!(disk->driverName = strdup("file"))) {
VIR_FREE(disk); virDomainDiskDefFree(disk);
goto no_memory; goto no_memory;
} }
disk->bus = VIR_DOMAIN_DISK_BUS_IDE; disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
disk->readonly = 1; disk->readonly = 1;
prev = def->disks; if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
while (prev && prev->next) { virDomainDiskDefFree(disk);
prev = prev->next; goto no_memory;
} }
if (prev) def->disks[def->ndisks++] = disk;
prev->next = disk;
else
def->disks = disk;
} }
} }
@ -2322,7 +2315,7 @@ xenDaemonParseSxpr(virConnectPtr conn,
for (i = 0 ; i < sizeof(fds)/sizeof(fds[0]) ; i++) { for (i = 0 ; i < sizeof(fds)/sizeof(fds[0]) ; i++) {
tmp = sexpr_fmt_node(root, "domain/image/hvm/%s", fds[i]); tmp = sexpr_fmt_node(root, "domain/image/hvm/%s", fds[i]);
if ((tmp != NULL) && (tmp[0] != 0)) { if ((tmp != NULL) && (tmp[0] != 0)) {
virDomainDiskDefPtr disk, prev; virDomainDiskDefPtr disk;
if (VIR_ALLOC(disk) < 0) if (VIR_ALLOC(disk) < 0)
goto no_memory; goto no_memory;
if (!(disk->src = strdup(tmp))) { if (!(disk->src = strdup(tmp))) {
@ -2332,26 +2325,25 @@ xenDaemonParseSxpr(virConnectPtr conn,
disk->type = VIR_DOMAIN_DISK_TYPE_FILE; disk->type = VIR_DOMAIN_DISK_TYPE_FILE;
disk->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY; disk->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
if (!(disk->dst = strdup(fds[i]))) { if (!(disk->dst = strdup(fds[i]))) {
VIR_FREE(disk); virDomainDiskDefFree(disk);
goto no_memory; goto no_memory;
} }
if (!(disk->driverName = strdup("file"))) { if (!(disk->driverName = strdup("file"))) {
VIR_FREE(disk); virDomainDiskDefFree(disk);
goto no_memory; goto no_memory;
} }
disk->bus = VIR_DOMAIN_DISK_BUS_FDC; disk->bus = VIR_DOMAIN_DISK_BUS_FDC;
prev = def->disks; if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
while (prev && prev->next) { virDomainDiskDefFree(disk);
prev = prev->next; goto no_memory;
} }
if (prev) def->disks[def->ndisks++] = disk;
prev->next = disk;
else
def->disks = disk;
} }
} }
} }
qsort(def->disks, def->ndisks, sizeof(*def->disks),
virDomainDiskQSort);
/* in case of HVM we have USB device emulation */ /* in case of HVM we have USB device emulation */
if (hvm && if (hvm &&
@ -2363,14 +2355,26 @@ xenDaemonParseSxpr(virConnectPtr conn,
if (hvm) { if (hvm) {
tmp = sexpr_node(root, "domain/image/hvm/serial"); tmp = sexpr_node(root, "domain/image/hvm/serial");
if (tmp && STRNEQ(tmp, "none")) { if (tmp && STRNEQ(tmp, "none")) {
if ((def->serials = xenDaemonParseSxprChar(conn, tmp, tty)) == NULL) virDomainChrDefPtr chr;
if ((chr = xenDaemonParseSxprChar(conn, tmp, tty)) == NULL)
goto error; 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"); tmp = sexpr_node(root, "domain/image/hvm/parallel");
if (tmp && STRNEQ(tmp, "none")) { if (tmp && STRNEQ(tmp, "none")) {
virDomainChrDefPtr chr;
/* XXX does XenD stuff parallel port tty info into xenstore somewhere ? */ /* 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; goto error;
if (VIR_REALLOC_N(def->parallels, def->nparallels+1) < 0) {
virDomainChrDefFree(chr);
goto no_memory;
}
def->parallels[def->nparallels++] = chr;
} }
} else { } else {
/* Fake a paravirt console, since that's not in the sexpr */ /* Fake a paravirt console, since that's not in the sexpr */
@ -4676,9 +4680,8 @@ xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path,
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv;
struct sexpr *root = NULL; struct sexpr *root = NULL;
int fd = -1, ret = -1; int fd = -1, ret = -1;
int found = 0; int found = 0, i;
virDomainDefPtr def; virDomainDefPtr def;
virDomainDiskDefPtr disk;
priv = (xenUnifiedPrivatePtr) domain->conn->privateData; priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
@ -4707,14 +4710,12 @@ xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path,
if (!(def = xenDaemonParseSxpr(domain->conn, root, priv->xendConfigVersion, NULL))) if (!(def = xenDaemonParseSxpr(domain->conn, root, priv->xendConfigVersion, NULL)))
goto cleanup; goto cleanup;
disk = def->disks; for (i = 0 ; i < def->ndisks ; i++) {
while (disk) { if (def->disks[i]->src &&
if (disk->src && STREQ(def->disks[i]->src, path)) {
STREQ(disk->src, path)) {
found = 1; found = 1;
break; break;
} }
disk = disk->next;
} }
if (!found) { if (!found) {
virXendError (domain->conn, VIR_ERR_INVALID_ARG, virXendError (domain->conn, VIR_ERR_INVALID_ARG,
@ -5161,21 +5162,20 @@ xenDaemonFormatSxprNet(virConnectPtr conn,
int int
xenDaemonFormatSxprSound(virConnectPtr conn, xenDaemonFormatSxprSound(virConnectPtr conn,
virDomainSoundDefPtr sound, virDomainDefPtr def,
virBufferPtr buf) virBufferPtr buf)
{ {
const char *str; const char *str;
virDomainSoundDefPtr prev = NULL; int i;
while (sound) { for (i = 0 ; i < def->nsounds ; i++) {
if (!(str = virDomainSoundModelTypeToString(sound->model))) { if (!(str = virDomainSoundModelTypeToString(def->sounds[i]->model))) {
virXendError(conn, VIR_ERR_INTERNAL_ERROR, virXendError(conn, VIR_ERR_INTERNAL_ERROR,
_("unexpected sound model %d"), sound->model); _("unexpected sound model %d"),
def->sounds[i]->model);
return -1; return -1;
} }
virBufferVSprintf(buf, "%s%s", prev ? "," : "", str); virBufferVSprintf(buf, "%s%s", i ? "," : "", str);
prev = sound;
sound = sound->next;
} }
return 0; return 0;
@ -5225,9 +5225,6 @@ xenDaemonFormatSxpr(virConnectPtr conn,
char uuidstr[VIR_UUID_STRING_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN];
const char *tmp; const char *tmp;
int hvm = 0, i; int hvm = 0, i;
virDomainNetDefPtr net;
virDomainDiskDefPtr disk;
virDomainInputDefPtr input;
virBufferAddLit(&buf, "(vm "); virBufferAddLit(&buf, "(vm ");
virBufferVSprintf(&buf, "(name '%s')", def->name); virBufferVSprintf(&buf, "(name '%s')", def->name);
@ -5339,16 +5336,14 @@ xenDaemonFormatSxpr(virConnectPtr conn,
/* get the cdrom device file */ /* get the cdrom device file */
/* Only XenD <= 3.0.2 wants cdrom config here */ /* Only XenD <= 3.0.2 wants cdrom config here */
if (xendConfigVersion == 1) { if (xendConfigVersion == 1) {
disk = def->disks; for (i = 0 ; i < def->ndisks ; i++) {
while (disk) { if (def->disks[i]->type == VIR_DOMAIN_DISK_DEVICE_CDROM &&
if (disk->type == VIR_DOMAIN_DISK_DEVICE_CDROM && STREQ(def->disks[i]->dst, "hdc") &&
STREQ(disk->dst, "hdc") && def->disks[i]->src) {
disk->src) {
virBufferVSprintf(&buf, "(cdrom '%s')", virBufferVSprintf(&buf, "(cdrom '%s')",
disk->src); def->disks[i]->src);
break; break;
} }
disk = disk->next;
} }
} }
@ -5361,16 +5356,13 @@ xenDaemonFormatSxpr(virConnectPtr conn,
virBufferAddLit(&buf, "(usb 1)"); virBufferAddLit(&buf, "(usb 1)");
input = def->inputs; for (i = 0 ; i < def->ninputs ; i++)
while (input) { if (xenDaemonFormatSxprInput(conn, def->inputs[i], &buf) < 0)
if (xenDaemonFormatSxprInput(conn, input, &buf) < 0)
goto error; goto error;
input = input->next;
}
if (def->parallels) { if (def->parallels) {
virBufferAddLit(&buf, "(parallel "); virBufferAddLit(&buf, "(parallel ");
if (xenDaemonFormatSxprChr(conn, def->parallels, &buf) < 0) if (xenDaemonFormatSxprChr(conn, def->parallels[0], &buf) < 0)
goto error; goto error;
virBufferAddLit(&buf, ")"); virBufferAddLit(&buf, ")");
} else { } else {
@ -5378,7 +5370,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
} }
if (def->serials) { if (def->serials) {
virBufferAddLit(&buf, "(serial "); virBufferAddLit(&buf, "(serial ");
if (xenDaemonFormatSxprChr(conn, def->serials, &buf) < 0) if (xenDaemonFormatSxprChr(conn, def->serials[0], &buf) < 0)
goto error; goto error;
virBufferAddLit(&buf, ")"); virBufferAddLit(&buf, ")");
} else { } else {
@ -5390,7 +5382,7 @@ xenDaemonFormatSxpr(virConnectPtr conn,
if (def->sounds) { if (def->sounds) {
virBufferAddLit(&buf, "(soundhw '"); virBufferAddLit(&buf, "(soundhw '");
if (xenDaemonFormatSxprSound(conn, def->sounds, &buf) < 0) if (xenDaemonFormatSxprSound(conn, def, &buf) < 0)
goto error; goto error;
virBufferAddLit(&buf, "')"); virBufferAddLit(&buf, "')");
} }
@ -5412,19 +5404,15 @@ xenDaemonFormatSxpr(virConnectPtr conn,
virBufferAddLit(&buf, "))"); virBufferAddLit(&buf, "))");
} }
disk = def->disks; for (i = 0 ; i < def->ndisks ; i++)
while (disk) { if (xenDaemonFormatSxprDisk(conn, def->disks[i],
if (xenDaemonFormatSxprDisk(conn, disk, &buf, hvm, xendConfigVersion, 0) < 0) &buf, hvm, xendConfigVersion, 0) < 0)
goto error; goto error;
disk = disk->next;
}
net = def->nets; for (i = 0 ; i < def->nnets ; i++)
while (net) { if (xenDaemonFormatSxprNet(conn, def->nets[i],
if (xenDaemonFormatSxprNet(conn, net, &buf, hvm, xendConfigVersion, 0) < 0) &buf, hvm, xendConfigVersion, 0) < 0)
goto error; goto error;
net = net->next;
}
/* New style PV graphics config xen >= 3.0.4, /* New style PV graphics config xen >= 3.0.4,
* or HVM graphics config xen >= 3.0.5 */ * or HVM graphics config xen >= 3.0.5 */

View File

@ -115,7 +115,7 @@ xenDaemonFormatSxprChr(virConnectPtr conn,
virBufferPtr buf); virBufferPtr buf);
int int
xenDaemonFormatSxprSound(virConnectPtr conn, xenDaemonFormatSxprSound(virConnectPtr conn,
virDomainSoundDefPtr sound, virDomainDefPtr def,
virBufferPtr buf); virBufferPtr buf);
char * char *

View File

@ -51,8 +51,6 @@
static int xenXMConfigSetString(virConfPtr conf, const char *setting, static int xenXMConfigSetString(virConfPtr conf, const char *setting,
const char *str); const char *str);
static int xenXMDiskCompare(virDomainDiskDefPtr a,
virDomainDiskDefPtr b);
typedef struct xenXMConfCache *xenXMConfCachePtr; typedef struct xenXMConfCache *xenXMConfCachePtr;
typedef struct xenXMConfCache { typedef struct xenXMConfCache {
@ -872,20 +870,9 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
disk->shared = 1; disk->shared = 1;
/* Maintain list in sorted order according to target device name */ /* Maintain list in sorted order according to target device name */
if (def->disks == NULL) { if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
disk->next = def->disks; goto no_memory;
def->disks = disk; def->disks[def->ndisks++] = 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;
}
}
disk = NULL; disk = NULL;
skipdisk: skipdisk:
@ -912,25 +899,14 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
disk->bus = VIR_DOMAIN_DISK_BUS_IDE; disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
disk->readonly = 1; disk->readonly = 1;
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
/* Maintain list in sorted order according to target device name */ goto no_memory;
if (def->disks == NULL) { def->disks[def->ndisks++] = disk;
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;
}
}
disk = NULL; disk = NULL;
} }
} }
qsort(def->disks, def->ndisks, sizeof(*def->disks),
virDomainDiskQSort);
list = virConfGetValue(conf, "vif"); list = virConfGetValue(conf, "vif");
if (list && list->type == VIR_CONF_LIST) { if (list && list->type == VIR_CONF_LIST) {
@ -1048,15 +1024,9 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
!(net->model = strdup(model))) !(net->model = strdup(model)))
goto no_memory; goto no_memory;
if (!def->nets) { if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0)
net->next = NULL; goto no_memory;
def->nets = net; def->nets[def->nnets++] = net;
} else {
virDomainNetDefPtr ptr = def->nets;
while (ptr->next)
ptr = ptr->next;
ptr->next = net;
}
net = NULL; net = NULL;
skipnic: skipnic:
@ -1078,7 +1048,12 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
input->type = STREQ(str, "tablet") ? input->type = STREQ(str, "tablet") ?
VIR_DOMAIN_INPUT_TYPE_TABLET : VIR_DOMAIN_INPUT_TYPE_TABLET :
VIR_DOMAIN_INPUT_TYPE_MOUSE; 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) { if (hvm) {
virDomainChrDefPtr chr = NULL;
if (xenXMConfigGetString(conn, conf, "parallel", &str, NULL) < 0) if (xenXMConfigGetString(conn, conf, "parallel", &str, NULL) < 0)
goto cleanup; goto cleanup;
if (str && STRNEQ(str, "none") && if (str && STRNEQ(str, "none") &&
!(def->parallels = xenDaemonParseSxprChar(conn, str, NULL))) !(chr = xenDaemonParseSxprChar(conn, str, NULL)))
goto cleanup; 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) if (xenXMConfigGetString(conn, conf, "serial", &str, NULL) < 0)
goto cleanup; goto cleanup;
if (str && STRNEQ(str, "none") && if (str && STRNEQ(str, "none") &&
!(def->serials = xenDaemonParseSxprChar(conn, str, NULL))) !(chr = xenDaemonParseSxprChar(conn, str, NULL)))
goto cleanup; goto cleanup;
if (chr) {
if (VIR_ALLOC_N(def->serials, 1) < 0) {
virDomainChrDefFree(chr);
goto no_memory;
}
def->serials[0] = chr;
def->nserials++;
}
} else { } else {
if (!(def->console = xenDaemonParseSxprChar(conn, "pty", NULL))) if (!(def->console = xenDaemonParseSxprChar(conn, "pty", NULL)))
goto cleanup; goto cleanup;
@ -1805,8 +1801,6 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
char *cpus = NULL; char *cpus = NULL;
const char *lifecycle; const char *lifecycle;
char uuid[VIR_UUID_STRING_BUFLEN]; char uuid[VIR_UUID_STRING_BUFLEN];
virDomainDiskDefPtr disk;
virDomainNetDefPtr net;
virConfValuePtr diskVal = NULL; virConfValuePtr diskVal = NULL;
virConfValuePtr netVal = NULL; virConfValuePtr netVal = NULL;
@ -1899,15 +1893,16 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
goto no_memory; goto no_memory;
if (priv->xendConfigVersion == 1) { if (priv->xendConfigVersion == 1) {
disk = def->disks; for (i = 0 ; i < def->ndisks ; i++) {
while (disk) { if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM && def->disks[i]->dst &&
disk->dst && STREQ(disk->dst, "hdc") && disk->src) { STREQ(def->disks[i]->dst, "hdc") &&
if (xenXMConfigSetString(conf, "cdrom", disk->src) < 0) def->disks[i]->src) {
if (xenXMConfigSetString(conf, "cdrom",
def->disks[i]->src) < 0)
goto no_memory; goto no_memory;
break; break;
} }
disk = disk->next;
} }
} }
@ -1960,23 +1955,20 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
if (hvm) { if (hvm) {
virDomainInputDefPtr input;
if (def->emulator && if (def->emulator &&
xenXMConfigSetString(conf, "device_model", def->emulator) < 0) xenXMConfigSetString(conf, "device_model", def->emulator) < 0)
goto no_memory; goto no_memory;
input = def->inputs; for (i = 0 ; i < def->ninputs ; i++) {
while (input) { if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
if (xenXMConfigSetInt(conf, "usb", 1) < 0) if (xenXMConfigSetInt(conf, "usb", 1) < 0)
goto no_memory; goto no_memory;
if (xenXMConfigSetString(conf, "usbdevice", if (xenXMConfigSetString(conf, "usbdevice",
input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? def->inputs[i]->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
"mouse" : "tablet") < 0) "mouse" : "tablet") < 0)
goto no_memory; goto no_memory;
break; break;
} }
input = input->next;
} }
} }
@ -2076,27 +2068,24 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
} }
/* analyze of the devices */ /* analyze of the devices */
disk = def->disks;
if (VIR_ALLOC(diskVal) < 0) if (VIR_ALLOC(diskVal) < 0)
goto no_memory; goto no_memory;
diskVal->type = VIR_CONF_LIST; diskVal->type = VIR_CONF_LIST;
diskVal->list = NULL; diskVal->list = NULL;
while (disk) { for (i = 0 ; i < def->ndisks ; i++) {
if (priv->xendConfigVersion == 1 && if (priv->xendConfigVersion == 1 &&
disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM && def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
disk->dst && STREQ(disk->dst, "hdc")) { def->disks[i]->dst &&
disk = disk->next; STREQ(def->disks[i]->dst, "hdc")) {
continue; continue;
} }
if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
continue; continue;
if (xenXMDomainConfigFormatDisk(conn, diskVal, disk, if (xenXMDomainConfigFormatDisk(conn, diskVal, def->disks[i],
hvm, priv->xendConfigVersion) < 0) hvm, priv->xendConfigVersion) < 0)
goto cleanup; goto cleanup;
disk = disk->next;
} }
if (diskVal->list == NULL) if (diskVal->list == NULL)
VIR_FREE(diskVal); VIR_FREE(diskVal);
@ -2107,18 +2096,16 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
diskVal = NULL; diskVal = NULL;
net = def->nets;
if (VIR_ALLOC(netVal) < 0) if (VIR_ALLOC(netVal) < 0)
goto no_memory; goto no_memory;
netVal->type = VIR_CONF_LIST; netVal->type = VIR_CONF_LIST;
netVal->list = NULL; netVal->list = NULL;
while (net) { for (i = 0 ; i < def->nnets ; i++) {
if (xenXMDomainConfigFormatNet(conn, netVal, net, if (xenXMDomainConfigFormatNet(conn, netVal,
def->nets[i],
hvm) < 0) hvm) < 0)
goto cleanup; goto cleanup;
net = net->next;
} }
if (netVal->list == NULL) if (netVal->list == NULL)
VIR_FREE(netVal); VIR_FREE(netVal);
@ -2129,12 +2116,12 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
netVal = NULL; netVal = NULL;
if (hvm) { if (hvm) {
if (def->parallels) { if (def->nparallels) {
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
char *str; char *str;
int ret; int ret;
ret = xenDaemonFormatSxprChr(conn, def->parallels, &buf); ret = xenDaemonFormatSxprChr(conn, def->parallels[0], &buf);
str = virBufferContentAndReset(&buf); str = virBufferContentAndReset(&buf);
if (ret == 0) if (ret == 0)
ret = xenXMConfigSetString(conf, "parallel", str); ret = xenXMConfigSetString(conf, "parallel", str);
@ -2146,12 +2133,12 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
goto no_memory; goto no_memory;
} }
if (def->serials) { if (def->nserials) {
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
char *str; char *str;
int ret; int ret;
ret = xenDaemonFormatSxprChr(conn, def->serials, &buf); ret = xenDaemonFormatSxprChr(conn, def->serials[0], &buf);
str = virBufferContentAndReset(&buf); str = virBufferContentAndReset(&buf);
if (ret == 0) if (ret == 0)
ret = xenXMConfigSetString(conf, "serial", str); ret = xenXMConfigSetString(conf, "serial", str);
@ -2168,7 +2155,7 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
char *str = NULL; char *str = NULL;
int ret = xenDaemonFormatSxprSound(conn, int ret = xenDaemonFormatSxprSound(conn,
def->sounds, def,
&buf); &buf);
str = virBufferContentAndReset(&buf); str = virBufferContentAndReset(&buf);
if (ret == 0) if (ret == 0)
@ -2417,14 +2404,6 @@ int xenXMNumOfDefinedDomains(virConnectPtr conn) {
return virHashSize(nameConfigMap); 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: * xenXMDomainAttachDevice:
@ -2442,6 +2421,7 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) {
xenXMConfCachePtr entry = NULL; xenXMConfCachePtr entry = NULL;
int ret = -1; int ret = -1;
virDomainDeviceDefPtr dev = NULL; virDomainDeviceDefPtr dev = NULL;
virDomainDefPtr def;
if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) { if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) {
xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
@ -2457,6 +2437,7 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) {
return -1; return -1;
if (!(entry = virHashLookup(configCache, filename))) if (!(entry = virHashLookup(configCache, filename)))
return -1; return -1;
def = entry->def;
if (!(dev = virDomainDeviceDefParse(domain->conn, if (!(dev = virDomainDeviceDefParse(domain->conn,
entry->def, entry->def,
@ -2466,34 +2447,24 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) {
switch (dev->type) { switch (dev->type) {
case VIR_DOMAIN_DEVICE_DISK: case VIR_DOMAIN_DEVICE_DISK:
{ {
/* Maintain list in sorted order according to target device name */ if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
if (entry->def->disks == NULL) { xenXMError(domain->conn, VIR_ERR_NO_MEMORY, NULL);
dev->data.disk->next = entry->def->disks; goto cleanup;
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;
}
} }
def->disks[def->ndisks++] = dev->data.disk;
dev->data.disk = NULL; dev->data.disk = NULL;
qsort(def->disks, def->ndisks, sizeof(*def->disks),
virDomainDiskQSort);
} }
break; break;
case VIR_DOMAIN_DEVICE_NET: case VIR_DOMAIN_DEVICE_NET:
{ {
virDomainNetDefPtr net = entry->def->nets; if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0) {
while (net && net->next) xenXMError(domain->conn, VIR_ERR_NO_MEMORY, NULL);
net = net->next; goto cleanup;
if (net) }
net->next = dev->data.net; def->nets[def->nnets++] = dev->data.net;
else
entry->def->nets = dev->data.net;
dev->data.net = NULL; dev->data.net = NULL;
break; break;
} }
@ -2555,7 +2526,9 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) {
const char *filename = NULL; const char *filename = NULL;
xenXMConfCachePtr entry = NULL; xenXMConfCachePtr entry = NULL;
virDomainDeviceDefPtr dev = NULL; virDomainDeviceDefPtr dev = NULL;
virDomainDefPtr def;
int ret = -1; int ret = -1;
int i;
if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) { if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) {
xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
@ -2570,6 +2543,7 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) {
return -1; return -1;
if (!(entry = virHashLookup(configCache, filename))) if (!(entry = virHashLookup(configCache, filename)))
return -1; return -1;
def = entry->def;
if (!(dev = virDomainDeviceDefParse(domain->conn, if (!(dev = virDomainDeviceDefParse(domain->conn,
entry->def, entry->def,
@ -2579,42 +2553,34 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) {
switch (dev->type) { switch (dev->type) {
case VIR_DOMAIN_DEVICE_DISK: case VIR_DOMAIN_DEVICE_DISK:
{ {
virDomainDiskDefPtr disk = entry->def->disks; for (i = 0 ; i < def->ndisks ; i++) {
virDomainDiskDefPtr prev = NULL; if (def->disks[i]->dst &&
while (disk) {
if (disk->dst &&
dev->data.disk->dst && dev->data.disk->dst &&
STREQ(disk->dst, dev->data.disk->dst)) { STREQ(def->disks[i]->dst, dev->data.disk->dst)) {
if (prev) { virDomainDiskDefFree(def->disks[i]);
prev->next = disk->next; if (i < (def->ndisks - 1))
} else { memmove(def->disks + i,
entry->def->disks = disk->next; def->disks + i + 1,
} def->ndisks - (i + 1));
virDomainDiskDefFree(disk);
break; break;
} }
prev = disk;
disk = disk->next;
} }
break; break;
} }
case VIR_DOMAIN_DEVICE_NET: case VIR_DOMAIN_DEVICE_NET:
{ {
virDomainNetDefPtr net = entry->def->nets; for (i = 0 ; i < def->nnets ; i++) {
virDomainNetDefPtr prev = NULL; if (!memcmp(def->nets[i]->mac,
while (net) { dev->data.net->mac,
if (!memcmp(net->mac, dev->data.net->mac, VIR_DOMAIN_NET_MAC_SIZE)) { VIR_DOMAIN_NET_MAC_SIZE)) {
if (prev) { virDomainNetDefFree(def->nets[i]);
prev->next = net->next; if (i < (def->nnets - 1))
} else { memmove(def->nets + i,
entry->def->nets = net->next; def->nets + i + 1,
} def->nnets - (i + 1));
virDomainNetDefFree(net);
break; break;
} }
prev = net;
net = net->next;
} }
break; break;
} }

View File

@ -18,17 +18,17 @@
<on_crash>restart</on_crash> <on_crash>restart</on_crash>
<devices> <devices>
<emulator>/usr/lib64/xen/bin/qemu-dm</emulator> <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'> <disk type='file' device='cdrom'>
<driver name='file'/> <driver name='file'/>
<source file='/root/boot.iso'/> <source file='/root/boot.iso'/>
<target dev='hdc' bus='ide'/> <target dev='hdc' bus='ide'/>
<readonly/> <readonly/>
</disk> </disk>
<disk type='file' device='disk'>
<driver name='file'/>
<source file='/root/foo.img'/>
<target dev='hda' bus='ide'/>
</disk>
<interface type='bridge'> <interface type='bridge'>
<mac address='00:16:3e:1b:b1:47'/> <mac address='00:16:3e:1b:b1:47'/>
<source bridge='xenbr0'/> <source bridge='xenbr0'/>