summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Harpin <development@landsofshadow.co.uk>2015-01-11 19:20:17 +0000
committerAlex Harpin <development@landsofshadow.co.uk>2015-01-11 19:47:05 +0000
commitd033d4e6ade03d67d2ca3cc3515a0b81a4b4ef81 (patch)
treeb2d75ef71ce9f034811ff060d24fcb7f1d790f0b
parent2fdd8a58d8b7d8c8f00a8ca658f46fd733c0d2e1 (diff)
downloadvyatta-cfg-d033d4e6ade03d67d2ca3cc3515a0b81a4b4ef81.tar.gz
vyatta-cfg-d033d4e6ade03d67d2ca3cc3515a0b81a4b4ef81.zip
vyatta-cfg: fix for "failed to generate commited config"
When changes are made to the system by more than one user, only the first user after a reboot is able to commit successfully, the others fail with "Failed to generate committed config". This is caused as a result of the underlying unionfs-fuse mount used for the system configuration and the fact that a .unionfs directory if left in the active configuration with permissions set such that only the original committing user can change them. Bug #403 http://bugzilla.vyos.net/show_bug.cgi?id=403
-rw-r--r--src/cstore/unionfs/cstore-unionfs.cpp17
-rw-r--r--src/cstore/unionfs/cstore-unionfs.hpp1
2 files changed, 18 insertions, 0 deletions
diff --git a/src/cstore/unionfs/cstore-unionfs.cpp b/src/cstore/unionfs/cstore-unionfs.cpp
index 2e6f4ad..f253454 100644
--- a/src/cstore/unionfs/cstore-unionfs.cpp
+++ b/src/cstore/unionfs/cstore-unionfs.cpp
@@ -62,6 +62,7 @@ const string UnionfsCstore::C_MARKER_DEF_VALUE = "def";
const string UnionfsCstore::C_MARKER_DEACTIVATE = ".disable";
const string UnionfsCstore::C_MARKER_CHANGED = ".modified";
const string UnionfsCstore::C_MARKER_UNSAVED = ".unsaved";
+const string UnionfsCstore::C_MARKER_UNIONFS = ".unionfs";
const string UnionfsCstore::C_COMMITTED_MARKER_FILE = ".changes";
const string UnionfsCstore::C_COMMENT_FILE = ".comment";
const string UnionfsCstore::C_TAG_NAME = "node.tag";
@@ -640,6 +641,9 @@ UnionfsCstore::sync_dir(const FsPath& src, const FsPath& dst,
bool
UnionfsCstore::commitConfig(commit::PrioNode& node)
{
+ FsPath active_unionfs = active_root;
+ active_unionfs.push(C_MARKER_UNIONFS);
+
// make a copy of current "work" dir
try {
if (path_exists(tmp_work_root)) {
@@ -651,6 +655,7 @@ UnionfsCstore::commitConfig(commit::PrioNode& node)
}
output_internal("cp[%s]->[%s]\n", work_root.path_cstr(),
tmp_work_root.path_cstr());
+
recursive_copy_dir(work_root, tmp_work_root, true);
} catch (const b_fs::filesystem_error& e) {
output_internal("cp w->tw failed[%s]\n", e.what());
@@ -700,6 +705,18 @@ UnionfsCstore::commitConfig(commit::PrioNode& node)
output_user("failed to remove temp directories\n");
return false;
}
+ try {
+ b_fs::remove_all(active_unionfs.path_cstr());
+ } catch (const b_fs::filesystem_error& e) {
+ output_internal("rm active unionfs failed[%s]\n", e.what());
+ return false;
+ } catch (...) {
+ output_internal("rm active unionfs[unknown exception]\n");
+ return false;
+ }
+ if (path_exists(active_unionfs)) {
+ output_internal("failed to remove unionfs directories from active config\n");
+ }
// all done
return true;
}
diff --git a/src/cstore/unionfs/cstore-unionfs.hpp b/src/cstore/unionfs/cstore-unionfs.hpp
index 4edcfa7..fa504ab 100644
--- a/src/cstore/unionfs/cstore-unionfs.hpp
+++ b/src/cstore/unionfs/cstore-unionfs.hpp
@@ -78,6 +78,7 @@ private:
static const string C_MARKER_DEACTIVATE;
static const string C_MARKER_CHANGED;
static const string C_MARKER_UNSAVED;
+ static const string C_MARKER_UNIONFS;
static const string C_COMMITTED_MARKER_FILE;
static const string C_COMMENT_FILE;
static const string C_TAG_NAME;