The easiest way to explain where I'm coming from with
this patch is to look at the current qemudLoadConfigXML().
It carries out three distinct operations - (a) parse the
supplied XML, (b) assign the def to a VM (creating one
if needed) and (c) save the XML.
It's used in three places:
1) Loading at startup - you want (a) and (b), but you
want to check whether the name matches the filename
before doing (b)
2) Create() - you want (a) and (b)
3) Define() - you want (a), (b) and (c)
So, mostly I'm just splitting the function into three
and making the logic above much more obvious. It should
also make some of the autostart code much more
straightforward.
There are a number of misc. improvements lurking in
here too:
- The couple of places where we remove a VM or network
from the list is co-alesced into qemudRemoveInactiveVM()
and qemudRemoveInactiveNetwork()
- In qemudDomainCreate() and qemudNetworkCreate(), if
starting the VM/network failed, we were leaving it
on the list
- The compareFileToNameSuffix() stuff
- When loading config files at startup, we were failing
to log any errors
Signed-off-by: Mark McLoughlin <markmc(a)redhat.c>
Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -1140,22 +1140,14 @@ int qemudBuildCommandLine(struct qemud_s
/* Save a guest's config data into a persistent file */
static int qemudSaveConfig(struct qemud_server *server,
- struct qemud_vm *vm) {
+ struct qemud_vm *vm,
+ struct qemud_vm_def *def) {
char *xml;
int fd = -1, ret = -1;
int towrite;
- int err;
- if (!(xml = qemudGenerateXML(server, vm, 0))) {
+ if (!(xml = qemudGenerateXML(server, vm, def, 0)))
return -1;
- }
-
- if ((err = qemudEnsureDir(server->configDir))) {
- qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
- "cannot create config directory %s: %s",
- server->configDir, strerror(err));
- goto cleanup;
- }
if ((fd = open(vm->configFile,
O_WRONLY | O_CREAT | O_TRUNC,
@@ -1192,31 +1184,33 @@ static int qemudSaveConfig(struct qemud_
return ret;
}
-
-/* Create a qemud_vm instance, populating it based on the data
- * in a libvirt XML document describing the guest */
-struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
- const char *file,
- const char *doc,
- int save) {
- struct qemud_vm_def *def = NULL;
- struct qemud_vm *vm = NULL;
+struct qemud_vm_def *
+qemudParseVMDef(struct qemud_server *server,
+ const char *xmlStr,
+ const char *displayName) {
xmlDocPtr xml;
- int newVM = 0;
+ struct qemud_vm_def *def = NULL;
- if (!(xml = xmlReadDoc(BAD_CAST doc, file ? file : "domain.xml", NULL,
+ if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName :
"domain.xml", NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
qemudReportError(server, VIR_ERR_XML_ERROR, NULL);
return NULL;
}
- if (!(def = qemudParseXML(server, xml))) {
- xmlFreeDoc(xml);
- return NULL;
- }
+ def = qemudParseXML(server, xml);
+
xmlFreeDoc(xml);
+ return def;
+}
+
+struct qemud_vm *
+qemudAssignVMDef(struct qemud_server *server,
+ struct qemud_vm_def *def)
+{
+ struct qemud_vm *vm = NULL;
+
if ((vm = qemudFindVMByName(server, def->name))) {
if (!qemudIsActiveVM(vm)) {
qemudFreeVMDef(vm->def);
@@ -1226,63 +1220,87 @@ struct qemud_vm *qemudLoadConfigXML(stru
qemudFreeVMDef(vm->newDef);
vm->newDef = def;
}
- } else {
- if (!(vm = calloc(1, sizeof(struct qemud_vm)))) {
- qemudReportError(server, VIR_ERR_NO_MEMORY, "vm");
- qemudFreeVMDef(def);
- return NULL;
- }
-
- vm->stdout = -1;
- vm->stderr = -1;
- vm->monitor = -1;
- vm->pid = -1;
- vm->id = -1;
- vm->def = def;
- newVM = 1;
- }
-
- if (file) {
- strncpy(vm->configFile, file, PATH_MAX);
- vm->configFile[PATH_MAX-1] = '\0';
- } else {
- if (save) {
- if (qemudMakeConfigPath(server->configDir, vm->def->name,
".xml", vm->configFile, PATH_MAX) < 0) {
- qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
- "cannot construct config file path");
- if (newVM)
- qemudFreeVM(vm);
- return NULL;
- }
- if (qemudSaveConfig(server, vm) < 0) {
- if (newVM)
- qemudFreeVM(vm);
- return NULL;
- }
- } else {
- vm->configFile[0] = '\0';
- }
+ return vm;
}
- if (newVM) {
- vm->next = server->vms;
- server->vms = vm;
- server->ninactivevms++;
+ if (!(vm = calloc(1, sizeof(struct qemud_vm)))) {
+ qemudReportError(server, VIR_ERR_NO_MEMORY, "vm");
+ return NULL;
}
+ vm->stdout = -1;
+ vm->stderr = -1;
+ vm->monitor = -1;
+ vm->pid = -1;
+ vm->id = -1;
+ vm->def = def;
+ vm->next = server->vms;
+
+ server->vms = vm;
+ server->ninactivevms++;
+
return vm;
}
+void
+qemudRemoveInactiveVM(struct qemud_server *server,
+ struct qemud_vm *vm)
+{
+ struct qemud_vm *prev = NULL, *curr;
+
+ curr = server->vms;
+ while (curr != vm) {
+ prev = curr;
+ curr = curr->next;
+ }
+
+ if (curr) {
+ if (prev)
+ prev->next = curr->next;
+ else
+ server->vms = curr->next;
+
+ server->ninactivevms--;
+ }
+
+ qemudFreeVM(vm);
+}
+
+int
+qemudSaveVMDef(struct qemud_server *server,
+ struct qemud_vm *vm,
+ struct qemud_vm_def *def) {
+ if (vm->configFile[0] == '\0') {
+ int err;
+
+ if ((err = qemudEnsureDir(server->configDir))) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "cannot create config directory %s: %s",
+ server->configDir, strerror(err));
+ return -1;
+ }
+
+ if (qemudMakeConfigPath(server->configDir, def->name, ".xml",
+ vm->configFile, PATH_MAX) < 0) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "cannot construct config file path");
+ return -1;
+ }
+ }
+
+ return qemudSaveConfig(server, vm, def);
+}
static int qemudSaveNetworkConfig(struct qemud_server *server,
- struct qemud_network *network) {
+ struct qemud_network *network,
+ struct qemud_network_def *def) {
char *xml;
int fd, ret = -1;
int towrite;
int err;
- if (!(xml = qemudGenerateNetworkXML(server, network, 0))) {
+ if (!(xml = qemudGenerateNetworkXML(server, network, def))) {
return -1;
}
@@ -1550,28 +1568,32 @@ static struct qemud_network_def *qemudPa
return NULL;
}
-struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
- const char *file,
- const char *doc,
- int save) {
- struct qemud_network_def *def = NULL;
- struct qemud_network *network = NULL;
+struct qemud_network_def *
+qemudParseNetworkDef(struct qemud_server *server,
+ const char *xmlStr,
+ const char *displayName) {
xmlDocPtr xml;
- int newNetwork = 0;
+ struct qemud_network_def *def;
- if (!(xml = xmlReadDoc(BAD_CAST doc, file ? file : "network.xml", NULL,
+ if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName :
"network.xml", NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
qemudReportError(server, VIR_ERR_XML_ERROR, NULL);
return NULL;
}
- if (!(def = qemudParseNetworkXML(server, xml))) {
- xmlFreeDoc(xml);
- return NULL;
- }
+ def = qemudParseNetworkXML(server, xml);
+
xmlFreeDoc(xml);
+ return def;
+}
+
+struct qemud_network *
+qemudAssignNetworkDef(struct qemud_server *server,
+ struct qemud_network_def *def) {
+ struct qemud_network *network;
+
if ((network = qemudFindNetworkByName(server, def->name))) {
if (!qemudIsActiveNetwork(network)) {
qemudFreeNetworkDef(network->def);
@@ -1581,87 +1603,203 @@ struct qemud_network *qemudLoadNetworkCo
qemudFreeNetworkDef(network->newDef);
network->newDef = def;
}
- } else {
- if (!(network = calloc(1, sizeof(struct qemud_network)))) {
- qemudReportError(server, VIR_ERR_NO_MEMORY, "network");
- return NULL;
- }
- network->def = def;
- newNetwork = 1;
+ return network;
}
- if (file) {
- strncpy(network->configFile, file, PATH_MAX);
- network->configFile[PATH_MAX-1] = '\0';
- } else {
- if (save) {
- if (qemudMakeConfigPath(server->networkConfigDir,
network->def->name, ".xml", network->configFile, PATH_MAX) < 0) {
- qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot construct
config file path");
- if (newNetwork)
- qemudFreeNetwork(network);
- return NULL;
- }
+ if (!(network = calloc(1, sizeof(struct qemud_network)))) {
+ qemudReportError(server, VIR_ERR_NO_MEMORY, "network");
+ return NULL;
+ }
- if (qemudSaveNetworkConfig(server, network) < 0) {
- if (newNetwork)
- qemudFreeNetwork(network);
- return NULL;
- }
- } else {
- network->configFile[0] = '\0';
- }
+ network->def = def;
+ network->next = server->networks;
+
+ server->networks = network;
+ server->ninactivenetworks++;
+
+ return network;
+}
+
+void
+qemudRemoveInactiveNetwork(struct qemud_server *server,
+ struct qemud_network *network)
+{
+ struct qemud_network *prev = NULL, *curr;
+
+ curr = server->networks;
+ while (curr != network) {
+ prev = curr;
+ curr = curr->next;
}
- if (newNetwork) {
- network->next = server->networks;
- server->networks = network;
- server->ninactivenetworks++;
+ if (curr) {
+ if (prev)
+ prev->next = curr->next;
+ else
+ server->networks = curr->next;
+
+ server->ninactivenetworks--;
}
- return network;
+ qemudFreeNetwork(network);
}
+int
+qemudSaveNetworkDef(struct qemud_server *server,
+ struct qemud_network *network,
+ struct qemud_network_def *def) {
+
+ if (network->configFile[0] == '\0') {
+ int err;
+
+ if ((err = qemudEnsureDir(server->networkConfigDir))) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "cannot create config directory %s: %s",
+ server->networkConfigDir, strerror(err));
+ return -1;
+ }
+
+ if (qemudMakeConfigPath(server->networkConfigDir, def->name,
".xml",
+ network->configFile, PATH_MAX) < 0) {
+ qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
+ "cannot construct config file path");
+ return -1;
+ }
+ }
+
+ return qemudSaveNetworkConfig(server, network, def);
+}
-/* Load a guest from its persistent config file */
-static void qemudLoadConfig(struct qemud_server *server,
- const char *file,
- int isGuest) {
+static int
+qemudReadFile(const char *path,
+ char *buf,
+ int maxlen) {
FILE *fh;
struct stat st;
- char xml[QEMUD_MAX_XML_LEN];
- int ret;
+ int ret = 0;
- if (!(fh = fopen(file, "r"))) {
- qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot open config file
%s", file);
- return;
+ if (!(fh = fopen(path, "r"))) {
+ qemudLog(QEMUD_WARN, "Failed to open file '%s': %s",
+ path, strerror(errno));
+ goto error;
}
if (fstat(fileno(fh), &st) < 0) {
- qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot stat config file
%s", file);
- goto cleanup;
+ qemudLog(QEMUD_WARN, "Failed to stat file '%s': %s",
+ path, strerror(errno));
+ goto error;
}
- if (st.st_size >= QEMUD_MAX_XML_LEN) {
- qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "config too large in file
%s", file);
- goto cleanup;
+ if (S_ISDIR(st.st_mode)) {
+ qemudLog(QEMUD_DEBUG, "Ignoring directory '%s' - clearly not a
config file",
+ path);
+ goto error;
}
- if ((ret = fread(xml, st.st_size, 1, fh)) != 1) {
- qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot read config file
%s", file);
- goto cleanup;
+ if (st.st_size >= maxlen) {
+ qemudLog(QEMUD_WARN, "File '%s' is too large", path);
+ goto error;
}
- xml[st.st_size] = '\0';
- if (isGuest) {
- qemudLoadConfigXML(server, file, xml, 1);
- } else {
- qemudLoadNetworkConfigXML(server, file, xml, 1);
+ if ((ret = fread(buf, st.st_size, 1, fh)) != 1) {
+ qemudLog(QEMUD_WARN, "Failed to read config file '%s': %s",
+ path, strerror(errno));
+ goto error;
}
- cleanup:
- fclose(fh);
+
+ buf[st.st_size] = '\0';
+
+ ret = 1;
+
+ error:
+ if (fh)
+ fclose(fh);
+
+ return ret;
}
+static int
+compareFileToNameSuffix(const char *file,
+ const char *name,
+ const char *suffix) {
+ int filelen = strlen(file);
+ int namelen = strlen(name);
+ int suffixlen = strlen(suffix);
+
+ if (filelen == (namelen + suffixlen) &&
+ !strncmp(file, name, namelen) &&
+ !strncmp(file + namelen, suffix, suffixlen))
+ return 1;
+ else
+ return 0;
+}
+
+static struct qemud_vm *
+qemudLoadConfig(struct qemud_server *server,
+ const char *file,
+ const char *path,
+ const char *xml) {
+ struct qemud_vm_def *def;
+ struct qemud_vm *vm;
+
+ if (!(def = qemudParseVMDef(server, xml, file))) {
+ qemudLog(QEMUD_WARN, "Error parsing QEMU guest config '%s' :
%s",
+ path, server->errorMessage);
+ return NULL;
+ }
+
+ if (!compareFileToNameSuffix(file, def->name, ".xml")) {
+ qemudLog(QEMUD_WARN, "QEMU guest config filename '%s' does not match
guest name '%s'",
+ path, def->name);
+ qemudFreeVMDef(def);
+ return NULL;
+ }
+
+ if (!(vm = qemudAssignVMDef(server, def))) {
+ qemudLog(QEMUD_WARN, "Failed to load QEMU guest config '%s': out of
memory", path);
+ qemudFreeVMDef(def);
+ return NULL;
+ }
+
+ strncpy(vm->configFile, path, PATH_MAX);
+ vm->configFile[PATH_MAX-1] = '\0';
+
+ return vm;
+}
+
+static struct qemud_network *
+qemudLoadNetworkConfig(struct qemud_server *server,
+ const char *file,
+ const char *path,
+ const char *xml) {
+ struct qemud_network_def *def;
+ struct qemud_network *network;
+
+ if (!(def = qemudParseNetworkDef(server, xml, file))) {
+ qemudLog(QEMUD_WARN, "Error parsing network config '%s' : %s",
+ path, server->errorMessage);
+ return NULL;
+ }
+
+ if (!compareFileToNameSuffix(file, def->name, ".xml")) {
+ qemudLog(QEMUD_WARN, "Network config filename '%s' does not match
network name '%s'",
+ path, def->name);
+ qemudFreeNetworkDef(def);
+ return NULL;
+ }
+
+ if (!(network = qemudAssignNetworkDef(server, def))) {
+ qemudLog(QEMUD_WARN, "Failed to load network config '%s': out of
memory", path);
+ qemudFreeNetworkDef(def);
+ return NULL;
+ }
+
+ strncpy(network->configFile, path, PATH_MAX);
+ network->configFile[PATH_MAX-1] = '\0';
+
+ return network;
+}
static
int qemudScanConfigDir(struct qemud_server *server,
@@ -1679,14 +1817,25 @@ int qemudScanConfigDir(struct qemud_serv
}
while ((entry = readdir(dir))) {
- char file[PATH_MAX];
+ char xml[QEMUD_MAX_XML_LEN];
+ char path[PATH_MAX];
+
if (entry->d_name[0] == '.')
continue;
- if (qemudMakeConfigPath(configDir, entry->d_name, NULL, file, PATH_MAX) <
0)
+ if (qemudMakeConfigPath(configDir, entry->d_name, NULL, path, PATH_MAX) <
0) {
+ qemudLog(QEMUD_WARN, "Config filename '%s/%s' is too
long",
+ configDir, entry->d_name);
+ continue;
+ }
+
+ if (!qemudReadFile(path, xml, QEMUD_MAX_XML_LEN))
continue;
- qemudLoadConfig(server, file, isGuest);
+ if (isGuest)
+ qemudLoadConfig(server, entry->d_name, path, xml);
+ else
+ qemudLoadNetworkConfig(server, entry->d_name, path, xml);
}
closedir(dir);
@@ -1751,8 +1900,10 @@ int qemudBufferPrintf(struct qemudBuffer
}
/* Generate an XML document describing the guest's configuration */
-char *qemudGenerateXML(struct qemud_server *server, struct qemud_vm *vm, int live) {
- struct qemud_vm_def *def = live ? vm->def : (vm->newDef ? vm->newDef :
vm->def);
+char *qemudGenerateXML(struct qemud_server *server,
+ struct qemud_vm *vm,
+ struct qemud_vm_def *def,
+ int live) {
struct qemudBuffer buf;
unsigned char *uuid;
struct qemud_vm_disk_def *disk;
@@ -1986,9 +2137,8 @@ char *qemudGenerateXML(struct qemud_serv
char *qemudGenerateNetworkXML(struct qemud_server *server,
- struct qemud_network *network,
- int live) {
- struct qemud_network_def *def = live ? network->def : (network->newDef ?
network->newDef : network->def);
+ struct qemud_network *network ATTRIBUTE_UNUSED,
+ struct qemud_network_def *def) {
struct qemudBuffer buf;
unsigned char *uuid;
Index: libvirt/qemud/conf.h
===================================================================
--- libvirt.orig/qemud/conf.h
+++ libvirt/qemud/conf.h
@@ -26,33 +26,55 @@
#include "internal.h"
-int qemudBuildCommandLine(struct qemud_server *server,
- struct qemud_vm *vm,
- char ***argv);
-
-int qemudScanConfigs(struct qemud_server *server);
-int qemudDeleteConfig(struct qemud_server *server,
- const char *configFile,
- const char *name);
-
-void qemudFreeVMDef(struct qemud_vm_def *vm);
-void qemudFreeVM(struct qemud_vm *vm);
-struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
- const char *file,
- const char *doc,
- int persist);
-char *qemudGenerateXML(struct qemud_server *server,
- struct qemud_vm *vm, int live);
-
-void qemudFreeNetworkDef(struct qemud_network_def *def);
-void qemudFreeNetwork(struct qemud_network *network);
-struct qemud_network *qemudLoadNetworkConfigXML(struct qemud_server *server,
- const char *file,
- const char *doc,
- int persist);
-char *qemudGenerateNetworkXML(struct qemud_server *server,
- struct qemud_network *network,
- int live);
+int qemudBuildCommandLine (struct qemud_server *server,
+ struct qemud_vm *vm,
+ char ***argv);
+
+int qemudScanConfigs (struct qemud_server *server);
+int qemudDeleteConfig (struct qemud_server *server,
+ const char *configFile,
+ const char *name);
+
+void qemudFreeVMDef (struct qemud_vm_def *vm);
+void qemudFreeVM (struct qemud_vm *vm);
+
+struct qemud_vm *
+ qemudAssignVMDef (struct qemud_server *server,
+ struct qemud_vm_def *def);
+void qemudRemoveInactiveVM (struct qemud_server *server,
+ struct qemud_vm *vm);
+
+struct qemud_vm_def *
+ qemudParseVMDef (struct qemud_server *server,
+ const char *xmlStr,
+ const char *displayName);
+int qemudSaveVMDef (struct qemud_server *server,
+ struct qemud_vm *vm,
+ struct qemud_vm_def *def);
+char * qemudGenerateXML (struct qemud_server *server,
+ struct qemud_vm *vm,
+ struct qemud_vm_def *def,
+ int live);
+
+void qemudFreeNetworkDef (struct qemud_network_def *def);
+void qemudFreeNetwork (struct qemud_network *network);
+
+struct qemud_network *
+ qemudAssignNetworkDef (struct qemud_server *server,
+ struct qemud_network_def *def);
+void qemudRemoveInactiveNetwork (struct qemud_server *server,
+ struct qemud_network *network);
+
+struct qemud_network_def *
+ qemudParseNetworkDef (struct qemud_server *server,
+ const char *xmlStr,
+ const char *displayName);
+int qemudSaveNetworkDef (struct qemud_server *server,
+ struct qemud_network *network,
+ struct qemud_network_def *def);
+char * qemudGenerateNetworkXML (struct qemud_server *server,
+ struct qemud_network *network,
+ struct qemud_network_def *def);
#endif
Index: libvirt/qemud/driver.c
===================================================================
--- libvirt.orig/qemud/driver.c
+++ libvirt/qemud/driver.c
@@ -279,14 +279,20 @@ int qemudNumDomains(struct qemud_server
return server->nactivevms;
}
struct qemud_vm *qemudDomainCreate(struct qemud_server *server, const char *xml) {
+
+ struct qemud_vm_def *def;
struct qemud_vm *vm;
- if (!(vm = qemudLoadConfigXML(server, NULL, xml, 0))) {
+ if (!(def = qemudParseVMDef(server, xml, NULL)))
+ return NULL;
+
+ if (!(vm = qemudAssignVMDef(server, def))) {
+ qemudFreeVMDef(def);
return NULL;
}
if (qemudStartVMDaemon(server, vm) < 0) {
- qemudFreeVM(vm);
+ qemudRemoveInactiveVM(server, vm);
return NULL;
}
@@ -416,7 +422,7 @@ int qemudDomainDumpXML(struct qemud_serv
return -1;
}
- vmxml = qemudGenerateXML(server, vm, 1);
+ vmxml = qemudGenerateXML(server, vm, vm->def, 1);
if (!vmxml)
return -1;
@@ -461,12 +467,27 @@ struct qemud_vm *qemudDomainStart(struct
struct qemud_vm *qemudDomainDefine(struct qemud_server *server, const char *xml) {
- return qemudLoadConfigXML(server, NULL, xml, 1);
+ struct qemud_vm_def *def;
+ struct qemud_vm *vm;
+
+ if (!(def = qemudParseVMDef(server, xml, NULL)))
+ return NULL;
+
+ if (!(vm = qemudAssignVMDef(server, def))) {
+ qemudFreeVMDef(def);
+ return NULL;
+ }
+
+ if (qemudSaveVMDef(server, vm, def) < 0) {
+ qemudRemoveInactiveVM(server, vm);
+ return NULL;
+ }
+
+ return vm;
}
int qemudDomainUndefine(struct qemud_server *server, const unsigned char *uuid) {
struct qemud_vm *vm = qemudFindVMByUUID(server, uuid);
- struct qemud_vm *prev = NULL, *curr = server->vms;
if (!vm) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no domain with matching
uuid");
@@ -483,22 +504,7 @@ int qemudDomainUndefine(struct qemud_ser
vm->configFile[0] = '\0';
- while (curr) {
- if (curr == vm) {
- if (prev) {
- prev->next = curr->next;
- } else {
- server->vms = curr->next;
- }
- server->ninactivevms--;
- break;
- }
-
- prev = curr;
- curr = curr->next;
- }
-
- qemudFreeVM(vm);
+ qemudRemoveInactiveVM(server, vm);
return 0;
}
@@ -566,14 +572,19 @@ int qemudListDefinedNetworks(struct qemu
}
struct qemud_network *qemudNetworkCreate(struct qemud_server *server, const char *xml) {
+ struct qemud_network_def *def;
struct qemud_network *network;
- if (!(network = qemudLoadNetworkConfigXML(server, NULL, xml, 0))) {
+ if (!(def = qemudParseNetworkDef(server, xml, NULL)))
+ return NULL;
+
+ if (!(network = qemudAssignNetworkDef(server, def))) {
+ qemudFreeNetworkDef(def);
return NULL;
}
if (qemudStartNetworkDaemon(server, network) < 0) {
- qemudFreeNetwork(network);
+ qemudRemoveInactiveNetwork(server, network);
return NULL;
}
@@ -581,12 +592,27 @@ struct qemud_network *qemudNetworkCreate
}
struct qemud_network *qemudNetworkDefine(struct qemud_server *server, const char *xml) {
- return qemudLoadNetworkConfigXML(server, NULL, xml, 1);
+ struct qemud_network_def *def;
+ struct qemud_network *network;
+
+ if (!(def = qemudParseNetworkDef(server, xml, NULL)))
+ return NULL;
+
+ if (!(network = qemudAssignNetworkDef(server, def))) {
+ qemudFreeNetworkDef(def);
+ return NULL;
+ }
+
+ if (qemudSaveNetworkDef(server, network, def) < 0) {
+ qemudRemoveInactiveNetwork(server, network);
+ return NULL;
+ }
+
+ return network;
}
int qemudNetworkUndefine(struct qemud_server *server, const unsigned char *uuid) {
struct qemud_network *network = qemudFindNetworkByUUID(server, uuid);
- struct qemud_network *prev = NULL, *curr = server->networks;
if (!network) {
qemudReportError(server, VIR_ERR_INVALID_DOMAIN, "no network with matching
uuid");
@@ -598,22 +624,7 @@ int qemudNetworkUndefine(struct qemud_se
network->configFile[0] = '\0';
- while (curr) {
- if (curr == network) {
- if (prev) {
- prev->next = curr->next;
- } else {
- server->networks = curr->next;
- }
- server->ninactivenetworks--;
- break;
- }
-
- prev = curr;
- curr = curr->next;
- }
-
- qemudFreeNetwork(network);
+ qemudRemoveInactiveNetwork(server, network);
return 0;
}
@@ -650,7 +661,7 @@ int qemudNetworkDumpXML(struct qemud_ser
return -1;
}
- networkxml = qemudGenerateNetworkXML(server, network, 1);
+ networkxml = qemudGenerateNetworkXML(server, network, network->def);
if (!networkxml)
return -1;
Index: libvirt/qemud/qemud.c
===================================================================
--- libvirt.orig/qemud/qemud.c
+++ libvirt/qemud/qemud.c
@@ -1255,8 +1255,7 @@ static int qemudDispatchPoll(struct qemu
struct qemud_socket *sock = server->sockets;
struct qemud_client *client = server->clients;
struct qemud_vm *vm;
- struct qemud_vm *tmp;
- struct qemud_network *network, *prevnet;
+ struct qemud_network *network;
int ret = 0;
int fd = 0;
@@ -1336,42 +1335,24 @@ static int qemudDispatchPoll(struct qemu
/* Cleanup any VMs which shutdown & dont have an associated
config file */
vm = server->vms;
- tmp = NULL;
while (vm) {
- if (!qemudIsActiveVM(vm) && !vm->configFile[0]) {
- struct qemud_vm *next = vm->next;
- if (tmp) {
- tmp->next = next;
- } else {
- server->vms = next;
- }
- qemudFreeVM(vm);
- server->ninactivevms--;
- vm = next;
- } else {
- tmp = vm;
- vm = vm->next;
- }
+ struct qemud_vm *next = vm->next;
+
+ if (!qemudIsActiveVM(vm) && !vm->configFile[0])
+ qemudRemoveInactiveVM(server, vm);
+
+ vm = next;
}
/* Cleanup any networks too */
network = server->networks;
- prevnet = NULL;
while (network) {
- if (!qemudIsActiveNetwork(network) && !network->configFile[0]) {
- struct qemud_network *next = network->next;
- if (prevnet) {
- prevnet->next = next;
- } else {
- server->networks = next;
- }
- qemudFreeNetwork(network);
- server->ninactivenetworks--;
- network = next;
- } else {
- prevnet = network;
- network = network->next;
- }
+ struct qemud_network *next = network->next;
+
+ if (!qemudIsActiveNetwork(network) && !network->configFile[0])
+ qemudRemoveInactiveNetwork(server, network);
+
+ network = next;
}
return ret;
--