diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 75584a026db02f006d8a17c5c7812be2d4c17956..18a7d575fde506e70ddeb54f561aa362308c605a 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1967,81 +1967,6 @@ cleanup: return def; } -int -virNetworkObjUpdateParseFile(const char *filename, - virNetworkObjPtr net) -{ - int ret = -1; - xmlDocPtr xml = NULL; - xmlNodePtr node = NULL; - virNetworkDefPtr tmp = NULL; - xmlXPathContextPtr ctxt = NULL; - - xml = virXMLParse(filename, NULL, _("(network status)")); - if (!xml) - return -1; - - ctxt = xmlXPathNewContext(xml); - if (ctxt == NULL) { - virReportOOMError(); - goto cleanup; - } - - node = xmlDocGetRootElement(xml); - if (xmlStrEqual(node->name, BAD_CAST "networkstatus")) { - /* Newer network status file. Contains useful - * info which are not to be found in bare config XML */ - char *class_id = NULL; - char *floor_sum = NULL; - - ctxt->node = node; - class_id = virXPathString("string(./class_id[1]/@bitmap)", ctxt); - if (class_id) { - virBitmapFree(net->class_id); - if (virBitmapParse(class_id, 0, - &net->class_id, CLASS_ID_BITMAP_SIZE) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Malformed 'class_id' attribute: %s"), - class_id); - VIR_FREE(class_id); - goto cleanup; - } - } - VIR_FREE(class_id); - - floor_sum = virXPathString("string(./floor[1]/@sum)", ctxt); - if (floor_sum && - virStrToLong_ull(floor_sum, NULL, 10, &net->floor_sum) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Malformed 'floor_sum' attribute: %s"), - floor_sum); - VIR_FREE(floor_sum); - } - VIR_FREE(floor_sum); - } - - node = virXPathNode("//network", ctxt); - if (!node) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Could not find any 'network' element")); - goto cleanup; - } - - ctxt->node = node; - tmp = virNetworkDefParseXML(ctxt); - - if (tmp) { - net->newDef = net->def; - net->def = tmp; - } - - ret = 0; - -cleanup: - xmlFreeDoc(xml); - xmlXPathFreeContext(ctxt); - return ret; -} static int virNetworkDNSDefFormat(virBufferPtr buf, @@ -2554,6 +2479,104 @@ cleanup: return ret; } +virNetworkObjPtr +virNetworkLoadState(virNetworkObjListPtr nets, + const char *stateDir, + const char *name) +{ + char *configFile = NULL; + virNetworkDefPtr def = NULL; + virNetworkObjPtr net = NULL; + xmlDocPtr xml = NULL; + xmlNodePtr node = NULL; + xmlXPathContextPtr ctxt = NULL; + virBitmapPtr class_id_map = NULL; + unsigned long long floor_sum_val = 0; + + + if ((configFile = virNetworkConfigFile(stateDir, name)) == NULL) + goto error; + + if (!(xml = virXMLParseCtxt(configFile, NULL, _("(network status)"), &ctxt))) + goto error; + + if (!(node = virXPathNode("//network", ctxt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find any 'network' element in status file")); + goto error; + } + + /* parse the definition first */ + ctxt->node = node; + if (!(def = virNetworkDefParseXML(ctxt))) + goto error; + + if (!STREQ(name, def->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Network config filename '%s'" + " does not match network name '%s'"), + configFile, def->name); + goto error; + } + + /* now parse possible status data */ + node = xmlDocGetRootElement(xml); + if (xmlStrEqual(node->name, BAD_CAST "networkstatus")) { + /* Newer network status file. Contains useful + * info which are not to be found in bare config XML */ + char *class_id = NULL; + char *floor_sum = NULL; + + ctxt->node = node; + if ((class_id = virXPathString("string(./class_id[1]/@bitmap)", ctxt))) { + if (virBitmapParse(class_id, 0, &class_id_map, + CLASS_ID_BITMAP_SIZE) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Malformed 'class_id' attribute: %s"), + class_id); + VIR_FREE(class_id); + goto error; + } + } + VIR_FREE(class_id); + + floor_sum = virXPathString("string(./floor[1]/@sum)", ctxt); + if (floor_sum && + virStrToLong_ull(floor_sum, NULL, 10, &floor_sum_val) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Malformed 'floor_sum' attribute: %s"), + floor_sum); + VIR_FREE(floor_sum); + } + VIR_FREE(floor_sum); + } + + /* create the object */ + if (!(net = virNetworkAssignDef(nets, def, true))) + goto error; + /* do not put any "goto error" below this comment */ + + /* assign status data stored in the network object */ + if (class_id_map) { + virBitmapFree(net->class_id); + net->class_id = class_id_map; + } + + if (floor_sum_val > 0) + net->floor_sum = floor_sum_val; + +cleanup: + VIR_FREE(configFile); + xmlFreeDoc(xml); + xmlXPathFreeContext(ctxt); + return net; + +error: + virBitmapFree(class_id_map); + virNetworkDefFree(def); + goto cleanup; +} + virNetworkObjPtr virNetworkLoadConfig(virNetworkObjListPtr nets, const char *configDir, const char *autostartDir, @@ -2612,6 +2635,40 @@ error: return NULL; } + +int +virNetworkLoadAllState(virNetworkObjListPtr nets, + const char *stateDir) +{ + DIR *dir; + struct dirent *entry; + + if (!(dir = opendir(stateDir))) { + if (errno == ENOENT) + return 0; + + virReportSystemError(errno, _("Failed to open dir '%s'"), stateDir); + return -1; + } + + while ((entry = readdir(dir))) { + virNetworkObjPtr net; + + if (entry->d_name[0] == '.') + continue; + + if (!virFileStripSuffix(entry->d_name, ".xml")) + continue; + + if ((net = virNetworkLoadState(nets, stateDir, entry->d_name))) + virNetworkObjUnlock(net); + } + + closedir(dir); + return 0; +} + + int virNetworkLoadAllConfigs(virNetworkObjListPtr nets, const char *configDir, const char *autostartDir) diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 1a86e3d5628c504aa441ff3bef4e44648b965d50..163478c834f5255bfae36efeff3c8731a098945f 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -280,9 +280,6 @@ virNetworkDefPtr virNetworkDefParseString(const char *xmlStr); virNetworkDefPtr virNetworkDefParseFile(const char *filename); virNetworkDefPtr virNetworkDefParseNode(xmlDocPtr xml, xmlNodePtr root); -int virNetworkObjUpdateParseFile(const char *filename, - virNetworkObjPtr net); - char *virNetworkDefFormat(const virNetworkDefPtr def, unsigned int flags); static inline const char * @@ -318,10 +315,17 @@ virNetworkObjPtr virNetworkLoadConfig(virNetworkObjListPtr nets, const char *autostartDir, const char *file); +virNetworkObjPtr virNetworkLoadState(virNetworkObjListPtr nets, + const char *stateDir, + const char *name); + int virNetworkLoadAllConfigs(virNetworkObjListPtr nets, const char *configDir, const char *autostartDir); +int virNetworkLoadAllState(virNetworkObjListPtr nets, + const char *stateDir); + int virNetworkDeleteConfig(const char *configDir, const char *autostartDir, virNetworkObjPtr net); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 30fdcd72d884a2274173d14d5a8b8829e7a01e09..f778e9cd382c0ee29ff671b95109e99c8b0a5995 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -454,6 +454,7 @@ virNetworkIpDefNetmask; virNetworkIpDefPrefix; virNetworkList; virNetworkLoadAllConfigs; +virNetworkLoadAllState; virNetworkObjAssignDef; virNetworkObjFree; virNetworkObjGetPersistentDef; @@ -465,7 +466,6 @@ virNetworkObjSetDefTransient; virNetworkObjUnlock; virNetworkObjUnsetDefTransient; virNetworkObjUpdate; -virNetworkObjUpdateParseFile; virNetworkRemoveInactive; virNetworkSaveConfig; virNetworkSaveStatus; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 6ea09faad8b46791760680e462cec4a3776c8189..27dd230ee781f79c8b70c1a9fbc0a4b5d287dda2 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -180,6 +180,7 @@ networkRemoveInactive(struct network_driver *driver, char *radvdconfigfile = NULL; char *configfile = NULL; char *radvdpidbase = NULL; + char *statusfile = NULL; dnsmasqContext *dctx = NULL; virNetworkDefPtr def = virNetworkObjGetPersistentDef(net); @@ -201,6 +202,9 @@ networkRemoveInactive(struct network_driver *driver, if (!(configfile = networkDnsmasqConfigFileName(def->name))) goto no_memory; + if (!(statusfile = virNetworkConfigFile(NETWORK_STATE_DIR, def->name))) + goto no_memory; + /* dnsmasq */ dnsmasqDelete(dctx); unlink(leasefile); @@ -210,6 +214,9 @@ networkRemoveInactive(struct network_driver *driver, unlink(radvdconfigfile); virPidFileDelete(NETWORK_PID_DIR, radvdpidbase); + /* remove status file */ + unlink(statusfile); + /* remove the network definition */ virNetworkRemoveInactive(&driver->networks, net); @@ -220,6 +227,7 @@ cleanup: VIR_FREE(configfile); VIR_FREE(radvdconfigfile); VIR_FREE(radvdpidbase); + VIR_FREE(statusfile); dnsmasqContextFree(dctx); return ret; @@ -253,33 +261,15 @@ networkBridgeDummyNicName(const char *brname) } static void -networkFindActiveConfigs(struct network_driver *driver) { +networkFindActiveConfigs(struct network_driver *driver) +{ unsigned int i; for (i = 0 ; i < driver->networks.count ; i++) { virNetworkObjPtr obj = driver->networks.objs[i]; - char *config; virNetworkObjLock(obj); - if ((config = virNetworkConfigFile(NETWORK_STATE_DIR, - obj->def->name)) == NULL) { - virNetworkObjUnlock(obj); - continue; - } - - if (access(config, R_OK) < 0) { - VIR_FREE(config); - virNetworkObjUnlock(obj); - continue; - } - - /* Try and load the live config */ - if (virNetworkObjUpdateParseFile(config, obj) < 0) - VIR_WARN("Unable to update config of '%s' network", - obj->def->name); - VIR_FREE(config); - /* If bridge exists, then mark it active */ if (obj->def->bridge && virNetDevExists(obj->def->bridge) == 1) { @@ -306,6 +296,21 @@ networkFindActiveConfigs(struct network_driver *driver) { cleanup: virNetworkObjUnlock(obj); } + + /* remove inactive transient networks */ + i = 0; + while (i < driver->networks.count) { + virNetworkObjPtr obj = driver->networks.objs[i]; + virNetworkObjLock(obj); + + if (!obj->persistent && !obj->active) { + networkRemoveInactive(driver, obj); + continue; + } + + virNetworkObjUnlock(obj); + i++; + } } @@ -415,6 +420,10 @@ networkStartup(bool privileged, /* if this fails now, it will be retried later with dnsmasqCapsRefresh() */ driverState->dnsmasqCaps = dnsmasqCapsNewFromBinary(DNSMASQ); + if (virNetworkLoadAllState(&driverState->networks, + NETWORK_STATE_DIR) < 0) + goto error; + if (virNetworkLoadAllConfigs(&driverState->networks, driverState->networkConfigDir, driverState->networkAutostartDir) < 0) @@ -479,6 +488,8 @@ networkReload(void) { return 0; networkDriverLock(driverState); + virNetworkLoadAllState(&driverState->networks, + NETWORK_STATE_DIR); virNetworkLoadAllConfigs(&driverState->networks, driverState->networkConfigDir, driverState->networkAutostartDir);