diff options
author | RageLtMan <rageltman [at] sempervictus> | 2022-08-13 11:34:08 -0400 |
---|---|---|
committer | RageLtMan <rageltman [at] sempervictus> | 2022-08-13 19:35:09 -0400 |
commit | 28cf6fee14d3bc5f6eda2099c7eb36e43297a8a8 (patch) | |
tree | c02cb3a288f67987cb200f95856258eebc7b313d /src/cstore | |
parent | c8dad45c8afa4fd4a784ae6cdffb84a2e804084e (diff) | |
download | vyatta-cfg-28cf6fee14d3bc5f6eda2099c7eb36e43297a8a8.tar.gz vyatta-cfg-28cf6fee14d3bc5f6eda2099c7eb36e43297a8a8.zip |
Fallthrough to binstream copy when copy_file fails
Kernel 5.15, and probably newer, present an EXEDEV error when the
vyatta-cfg code tries to boost::filesystem::copy_file on UnionFS
FUSE mounts. This completely breaks operation on newer kernels, and
is therefore a blocker to the rest of the project moving on to new
Linux LTS versions.
Boost is complex and fraught, this code behaves inconsistently in
verious operating environments, and can be a nightmare to debug.
Handle the concerns above using binary streaming in C++ to copy the
source to the destination if an exception occurs during the
existing Boost copy_file operation.
Testing:
Built ISO (cloud target), packer install, booted in OpenStack on
KVM, booted in AWS on Xen, verified configurations are committed in
both cases and that error logs are being generated to inform users
about the fall-through being utilized to write-out configurations.
Notes:
Logging may be dropped to avoid flooding storage on often-updated
systems. It is left in-place to aid developers in debugging the root
concern underpinning Boot breakage (which may impact other areas of
the code).
Diffstat (limited to 'src/cstore')
-rw-r--r-- | src/cstore/unionfs/cstore-unionfs.cpp | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/cstore/unionfs/cstore-unionfs.cpp b/src/cstore/unionfs/cstore-unionfs.cpp index e713dbd..e9aa7b2 100644 --- a/src/cstore/unionfs/cstore-unionfs.cpp +++ b/src/cstore/unionfs/cstore-unionfs.cpp @@ -167,6 +167,14 @@ _unescape_path_name(const string& path) return npath; } +// Fall-through for Boost's filesystem::copy_file "complexity" +void stream_file( const char* srce_file, const char* dest_file ) +{ + std::ifstream srce( srce_file, std::ios::binary ) ; + std::ofstream dest( dest_file, std::ios::binary ) ; + dest << srce.rdbuf() ; +} + vector<int> getActiveCommits() { string process_name = "vbash"; @@ -322,7 +330,6 @@ UnionfsCstore::~UnionfsCstore() { } - ////// public virtual functions declared in base class bool UnionfsCstore::markSessionUnsaved() @@ -750,7 +757,12 @@ UnionfsCstore::sync_dir(const FsPath& src, const FsPath& dst, try { if (path_is_regular(s)) { // it's file - b_fs::copy_file(s.path_cstr(), d.path_cstr()); + try { + b_fs::copy_file(s.path_cstr(), d.path_cstr()); + } catch (const boost::filesystem::filesystem_error& e) { + output_internal("syncdir failed due to %s in copy_file. Falling back to internal stream_file\n", e.what()); + stream_file(s.path_cstr(), d.path_cstr()); + } } else { // dir recursive_copy_dir(s, d, true); @@ -1592,7 +1604,12 @@ UnionfsCstore::recursive_copy_dir(const FsPath& src, const FsPath& dst, } } } - b_fs::copy_file(di->path(), nname); + try { + b_fs::copy_file(di->path(), nname); + } catch (const b_fs::filesystem_error& e) { + output_internal("recursive_copy_dir failed due to %s in copy_file. Falling back to internal stream_file\n", e.what()); + stream_file(di->path().string().c_str(), nname.c_str()); + } } } } |