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 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; --