/*
* virNetworkObjAssignDef:
* @network: the network object to update
- * @def: the new NetworkDef (will be consumed by this function iff successful)
+ * @def: the new NetworkDef (will be consumed by this function)
* @live: is this new def the "live" version, or the "persistent" version
*
- * Replace the appropriate copy of the given network's NetworkDef
+ * Replace the appropriate copy of the given network's def or newDef
* with def. Use "live" and current state of the network to determine
- * which to replace.
+ * which to replace and what to do with the old defs. When a non-live
+ * def is set, indicate that the network is now persistent.
+ *
+ * NB: a persistent network can be made transient by calling with:
+ * virNetworkObjAssignDef(network, NULL, false) (i.e. set the
+ * persistent def to NULL)
*
- * Returns 0 on success, -1 on failure.
*/
-int
+void
virNetworkObjAssignDef(virNetworkObjPtr network,
virNetworkDefPtr def,
bool live)
{
- if (virNetworkObjIsActive(network)) {
- if (live) {
+ if (live) {
+ /* before setting new live def, save (into newDef) any
+ * existing persistent (!live) def to be restored when the
+ * network is destroyed, unless there is one already saved.
+ */
+ if (network->persistent && !network->newDef)
+ network->newDef = network->def;
+ else
virNetworkDefFree(network->def);
- network->def = def;
- } else if (network->persistent) {
- /* save current configuration to be restored on network shutdown */
- virNetworkDefFree(network->newDef);
+ network->def = def;
+ } else { /* !live */
+ virNetworkDefFree(network->newDef);
+ if (virNetworkObjIsActive(network)) {
+ /* save new configuration to be restored on network
+ * shutdown, leaving current live def alone
+ */
network->newDef = def;
- } else {
- virReportError(VIR_ERR_OPERATION_INVALID,
- _("cannot save persistent config of transient "
- "network '%s'"), network->def->name);
- return -1;
+ } else { /* !live and !active */
+ if (network->def && !network->persistent) {
+ /* network isn't (yet) marked active or persistent,
+ * but already has a "live" def set. This means we are
+ * currently setting the persistent def as a part of
+ * the process of starting the network, so we need to
+ * preserve the "not yet live" def in network->def.
+ */
+ network->newDef = def;
+ } else {
+ /* either there is no live def set, or this network
+ * was already set as persistent, so the proper thing
+ * is to overwrite network->def.
+ */
+ network->newDef = NULL;
+ virNetworkDefFree(network->def);
+ network->def = def;
+ }
}
- } else if (!live) {
- virNetworkDefFree(network->newDef);
- virNetworkDefFree(network->def);
- network->newDef = NULL;
- network->def = def;
- } else {
- virReportError(VIR_ERR_OPERATION_INVALID,
- _("cannot save live config of inactive "
- "network '%s'"), network->def->name);
- return -1;
+ network->persistent = !!def;
}
- return 0;
}
/*
virNetworkObjPtr network;
if ((network = virNetworkFindByName(nets, def->name))) {
- if (virNetworkObjAssignDef(network, def, live) < 0) {
- virNetworkObjUnlock(network);
- return NULL;
- }
+ virNetworkObjAssignDef(network, def, live);
return network;
}
ignore_value(virBitmapSetBit(network->class_id, 2));
network->def = def;
-
+ network->persistent = !live;
return network;
+
error:
virNetworkObjUnlock(network);
virNetworkObjFree(network);
goto error;
net->autostart = autostart;
- net->persistent = 1;
VIR_FREE(configFile);
VIR_FREE(autostartLink);
if (networkValidate(driver, def, true) < 0)
goto cleanup;
- /* NB: "live" is false because this transient network hasn't yet
- * been started
+ /* NB: even though this transient network hasn't yet been started,
+ * we assign the def with live = true in anticipation that it will
+ * be started momentarily.
*/
- if (!(network = virNetworkAssignDef(&driver->networks, def, false)))
+ if (!(network = virNetworkAssignDef(&driver->networks, def, true)))
goto cleanup;
def = NULL;
if (networkValidate(driver, def, false) < 0)
goto cleanup;
- if ((network = virNetworkFindByName(&driver->networks, def->name))) {
- network->persistent = 1;
- if (virNetworkObjAssignDef(network, def, false) < 0)
- goto cleanup;
- } else {
- if (!(network = virNetworkAssignDef(&driver->networks, def, false)))
- goto cleanup;
- }
-
- /* define makes the network persistent - always */
- network->persistent = 1;
+ if (!(network = virNetworkAssignDef(&driver->networks, def, false)))
+ goto cleanup;
- /* def was asigned */
+ /* def was assigned to network object */
freeDef = false;
if (virNetworkSaveConfig(driver->networkConfigDir, def) < 0) {
network = NULL;
goto cleanup;
}
- network->persistent = 0;
- virNetworkDefFree(network->newDef);
- network->newDef = NULL;
+ /* if network was active already, just undo new persistent
+ * definition by making it transient.
+ * XXX - this isn't necessarily the correct thing to do.
+ */
+ virNetworkObjAssignDef(network, NULL, false);
goto cleanup;
}
if (virNetworkObjIsActive(network))
active = true;
+ /* remove autostart link */
if (virNetworkDeleteConfig(driver->networkConfigDir,
driver->networkAutostartDir,
network) < 0)
goto cleanup;
-
- /* make the network transient */
- network->persistent = 0;
network->autostart = 0;
- virNetworkDefFree(network->newDef);
- network->newDef = NULL;
event = virNetworkEventLifecycleNew(network->def->name,
network->def->uuid,
goto cleanup;
}
network = NULL;
+ } else {
+
+ /* if the network still exists, it was active, and we need to make
+ * it transient (by deleting the persistent def)
+ */
+ virNetworkObjAssignDef(network, NULL, false);
}
ret = 0;
goto error;
}
netobj->active = 1;
- netobj->persistent = 1;
virNetworkObjUnlock(netobj);
if (!(interfacedef = virInterfaceDefParseString(defaultInterfaceXML)))
goto error;
}
- obj->persistent = 1;
obj->active = 1;
virNetworkObjUnlock(obj);
}
if ((def = virNetworkDefParseString(xml)) == NULL)
goto cleanup;
- if (!(net = virNetworkAssignDef(&privconn->networks, def, false)))
+ if (!(net = virNetworkAssignDef(&privconn->networks, def, true)))
goto cleanup;
def = NULL;
net->active = 1;
if (!(net = virNetworkAssignDef(&privconn->networks, def, false)))
goto cleanup;
def = NULL;
- net->persistent = 1;
event = virNetworkEventLifecycleNew(net->def->name, net->def->uuid,
VIR_NETWORK_EVENT_DEFINED,