Loading src/network.cpp +43 −3 Changes for src/network.cpp: 43 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include <cctype> #include <cstdlib> #include <functional> #include <map> #include <unistd.h> #include <fcntl.h> Loading Loading @@ -754,6 +755,42 @@ static bool validIfname(const std::string &n) { // of configuration only loses its Bond=/Bridge=. static std::string memberConfigName(const std::string &ifname) { return "10-" + ifname; } // The .network/.netdev files in ConfigDir before a multi-file change, to put // back when a later write fails: a half-saved bond (its .netdev written, its // members not) would otherwise stay and be created on the next reload. namespace { struct ConfigSnapshot { std::map<std::string, std::string> files; // path -> contents ConfigSnapshot() { std::error_code ec; for (auto &e : std::filesystem::directory_iterator(NetworkManager::ConfigDir, ec)) { const std::string ext = e.path().extension().string(); if (ext != ".network" && ext != ".netdev") continue; std::ifstream in(e.path()); std::ostringstream text; text << in.rdbuf(); files[e.path().string()] = text.str(); } } void restore() const { std::error_code ec; for (auto &e : std::filesystem::directory_iterator(NetworkManager::ConfigDir, ec)) { const std::string ext = e.path().extension().string(); if ((ext == ".network" || ext == ".netdev") && !files.count(e.path().string())) std::filesystem::remove(e.path(), ec); } for (auto &[path, text] : files) { std::ifstream in(path); std::ostringstream now; now << in.rdbuf(); if (in.is_open() && now.str() == text) continue; std::ofstream out(path, std::ios::trunc); out << text; } } }; } bool NetworkManager::saveNetDev(const NetDevConfig &in, const std::vector<std::string> &members, std::string *err) { NetDevConfig nd = in; auto fail = [&](const std::string &e) { if (err) *err = e; return false; }; Loading Loading @@ -786,6 +823,9 @@ bool NetworkManager::saveNetDev(const NetDevConfig &in, const std::vector<std::s nd.name = old->name; } const ConfigSnapshot before; auto rollback = [&]() { before.restore(); return false; }; std::ostringstream f; f << "# Managed by syslite (sysbus)\n[NetDev]\nName=" << nd.ifname << "\nKind=" << nd.kind << "\n"; if (nd.kind == "bond") { Loading @@ -795,7 +835,7 @@ bool NetworkManager::saveNetDev(const NetDevConfig &in, const std::vector<std::s } else { f << "\n[Bridge]\nSTP=" << (nd.stp ? "yes" : "no") << "\n"; } if (!writeAtomically(base + nd.name + ".netdev", f.str(), err)) return false; if (!writeAtomically(base + nd.name + ".netdev", f.str(), err)) return rollback(); // members: the new ones get member configurations, the others lose theirs std::vector<NetworkConfig> configs = _configs; // writes don't touch _configs Loading @@ -809,7 +849,7 @@ bool NetworkManager::saveNetDev(const NetDevConfig &in, const std::vector<std::s } else { cfg.bond.clear(); cfg.bridge.clear(); if (!writeNetworkFile(cfg, err)) return false; if (!writeNetworkFile(cfg, err)) return rollback(); } } for (auto &m : members) { Loading @@ -824,7 +864,7 @@ bool NetworkManager::saveNetDev(const NetDevConfig &in, const std::vector<std::s cfg.dns.clear(); cfg.bond = nd.kind == "bond" ? nd.ifname : ""; cfg.bridge = nd.kind == "bridge" ? nd.ifname : ""; if (!writeNetworkFile(cfg, err)) return false; if (!writeNetworkFile(cfg, err)) return rollback(); } reloadConfigs(); return true; Loading Loading
src/network.cpp +43 −3 Changes for src/network.cpp: 43 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include <cctype> #include <cstdlib> #include <functional> #include <map> #include <unistd.h> #include <fcntl.h> Loading Loading @@ -754,6 +755,42 @@ static bool validIfname(const std::string &n) { // of configuration only loses its Bond=/Bridge=. static std::string memberConfigName(const std::string &ifname) { return "10-" + ifname; } // The .network/.netdev files in ConfigDir before a multi-file change, to put // back when a later write fails: a half-saved bond (its .netdev written, its // members not) would otherwise stay and be created on the next reload. namespace { struct ConfigSnapshot { std::map<std::string, std::string> files; // path -> contents ConfigSnapshot() { std::error_code ec; for (auto &e : std::filesystem::directory_iterator(NetworkManager::ConfigDir, ec)) { const std::string ext = e.path().extension().string(); if (ext != ".network" && ext != ".netdev") continue; std::ifstream in(e.path()); std::ostringstream text; text << in.rdbuf(); files[e.path().string()] = text.str(); } } void restore() const { std::error_code ec; for (auto &e : std::filesystem::directory_iterator(NetworkManager::ConfigDir, ec)) { const std::string ext = e.path().extension().string(); if ((ext == ".network" || ext == ".netdev") && !files.count(e.path().string())) std::filesystem::remove(e.path(), ec); } for (auto &[path, text] : files) { std::ifstream in(path); std::ostringstream now; now << in.rdbuf(); if (in.is_open() && now.str() == text) continue; std::ofstream out(path, std::ios::trunc); out << text; } } }; } bool NetworkManager::saveNetDev(const NetDevConfig &in, const std::vector<std::string> &members, std::string *err) { NetDevConfig nd = in; auto fail = [&](const std::string &e) { if (err) *err = e; return false; }; Loading Loading @@ -786,6 +823,9 @@ bool NetworkManager::saveNetDev(const NetDevConfig &in, const std::vector<std::s nd.name = old->name; } const ConfigSnapshot before; auto rollback = [&]() { before.restore(); return false; }; std::ostringstream f; f << "# Managed by syslite (sysbus)\n[NetDev]\nName=" << nd.ifname << "\nKind=" << nd.kind << "\n"; if (nd.kind == "bond") { Loading @@ -795,7 +835,7 @@ bool NetworkManager::saveNetDev(const NetDevConfig &in, const std::vector<std::s } else { f << "\n[Bridge]\nSTP=" << (nd.stp ? "yes" : "no") << "\n"; } if (!writeAtomically(base + nd.name + ".netdev", f.str(), err)) return false; if (!writeAtomically(base + nd.name + ".netdev", f.str(), err)) return rollback(); // members: the new ones get member configurations, the others lose theirs std::vector<NetworkConfig> configs = _configs; // writes don't touch _configs Loading @@ -809,7 +849,7 @@ bool NetworkManager::saveNetDev(const NetDevConfig &in, const std::vector<std::s } else { cfg.bond.clear(); cfg.bridge.clear(); if (!writeNetworkFile(cfg, err)) return false; if (!writeNetworkFile(cfg, err)) return rollback(); } } for (auto &m : members) { Loading @@ -824,7 +864,7 @@ bool NetworkManager::saveNetDev(const NetDevConfig &in, const std::vector<std::s cfg.dns.clear(); cfg.bond = nd.kind == "bond" ? nd.ifname : ""; cfg.bridge = nd.kind == "bridge" ? nd.ifname : ""; if (!writeNetworkFile(cfg, err)) return false; if (!writeNetworkFile(cfg, err)) return rollback(); } reloadConfigs(); return true; Loading