Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package snapper for openSUSE:Factory checked in at 2022-05-05 23:05:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/snapper (Old) and /work/SRC/openSUSE:Factory/.snapper.new.1538 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "snapper" Thu May 5 23:05:19 2022 rev:137 rq:974532 version:0.10.1 Changes: -------- --- /work/SRC/openSUSE:Factory/snapper/snapper.changes 2022-04-23 00:25:41.179764937 +0200 +++ /work/SRC/openSUSE:Factory/.snapper.new.1538/snapper.changes 2022-05-05 23:05:53.681519946 +0200 @@ -1,0 +2,6 @@ +Tue May 03 08:46:28 CEST 2022 - aschn...@suse.com + +- fixed error handling when reading configs + (gh#openSUSE/snapper#715) + +------------------------------------------------------------------- New: ---- snapper-xUbuntu_22.04.dsc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ debian.tar.gz ++++++ ++++++ snapper-0.10.1.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/LIBVERSION new/snapper-0.10.1/LIBVERSION --- old/snapper-0.10.1/LIBVERSION 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/LIBVERSION 2022-05-03 02:00:00.000000000 +0200 @@ -1 +1 @@ -6.0.0 +6.0.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/Makefile.am new/snapper-0.10.1/Makefile.am --- old/snapper-0.10.1/Makefile.am 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/Makefile.am 2022-05-03 02:00:00.000000000 +0200 @@ -14,23 +14,24 @@ snapper-$(VERSION).tar.bz2: dist-bzip2 DEBIAN_FLAVOURS = \ - Debian_10.0 \ - Debian_11.0 \ - Debian_Unstable + Debian_10.0 \ + Debian_11.0 \ + Debian_Unstable UBUNTU_FLAVOURS = \ - xUbuntu_18.04 \ - xUbuntu_18.10 \ - xUbuntu_19.04 \ - xUbuntu_19.10 \ - xUbuntu_20.04 \ - xUbuntu_20.10 \ - xUbuntu_21.04 \ - xUbuntu_21.10 + xUbuntu_18.04 \ + xUbuntu_18.10 \ + xUbuntu_19.04 \ + xUbuntu_19.10 \ + xUbuntu_20.04 \ + xUbuntu_20.10 \ + xUbuntu_21.04 \ + xUbuntu_21.10 \ + xUbuntu_22.04 RASPBIAN_FLAVOURS = \ - Raspbian_10 \ - Raspbian_11 + Raspbian_10 \ + Raspbian_11 show-debian: @echo "Debian flavors: $(DEBIAN_FLAVOURS)" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/Makefile.in new/snapper-0.10.1/Makefile.in --- old/snapper-0.10.1/Makefile.in 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/Makefile.in 2022-05-03 02:00:00.000000000 +0200 @@ -405,23 +405,24 @@ doc_DATA = AUTHORS COPYING EXTRA_DIST = $(doc_DATA) VERSION LIBVERSION DEBIAN_FLAVOURS = \ - Debian_10.0 \ - Debian_11.0 \ - Debian_Unstable + Debian_10.0 \ + Debian_11.0 \ + Debian_Unstable UBUNTU_FLAVOURS = \ - xUbuntu_18.04 \ - xUbuntu_18.10 \ - xUbuntu_19.04 \ - xUbuntu_19.10 \ - xUbuntu_20.04 \ - xUbuntu_20.10 \ - xUbuntu_21.04 \ - xUbuntu_21.10 + xUbuntu_18.04 \ + xUbuntu_18.10 \ + xUbuntu_19.04 \ + xUbuntu_19.10 \ + xUbuntu_20.04 \ + xUbuntu_20.10 \ + xUbuntu_21.04 \ + xUbuntu_21.10 \ + xUbuntu_22.04 RASPBIAN_FLAVOURS = \ - Raspbian_10 \ - Raspbian_11 + Raspbian_10 \ + Raspbian_11 # Run `make coverage` after all the tests have been run. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/doc/snapper.xml.in new/snapper-0.10.1/doc/snapper.xml.in --- old/snapper-0.10.1/doc/snapper.xml.in 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/doc/snapper.xml.in 2022-05-03 02:00:00.000000000 +0200 @@ -98,7 +98,7 @@ <para>Next to manual snapshot creation, snapshots are also created automatically.</para> <itemizedlist> <listitem> - <para>A cron-job creates hourly snapshots.</para> + <para>A cronjob or systemd timer creates hourly snapshots, if TIMELINE_CREATE is enabled for a config.</para> </listitem> <listitem> <para>Certain programs like YaST and zypper create pre/post @@ -111,7 +111,7 @@ <title>Cleanup Algorithms</title> <para>Snapper provides several algorithms to clean up old snapshots. The - algorithms are executed in a daily cron-job. This can be configured in the + algorithms are executed in a daily cronjob or systemd timer. This can be configured in the corresponding configurations files along with parameters for every algorithm.</para> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/snapper/AsciiFile.cc new/snapper-0.10.1/snapper/AsciiFile.cc --- old/snapper-0.10.1/snapper/AsciiFile.cc 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/snapper/AsciiFile.cc 2022-05-03 02:00:00.000000000 +0200 @@ -48,6 +48,9 @@ case Compression::GZIP: return true; + + case Compression::ZSTD: + return false; } return false; @@ -64,6 +67,9 @@ case Compression::GZIP: return name + ".gz"; + + case Compression::ZSTD: + return name + ".zst"; } SN_THROW(LogicErrorException("unknown or unsupported compression")); @@ -77,6 +83,7 @@ class None; class Gzip; + class Zstd; template <typename T> static std::unique_ptr<AsciiFileReader::Impl> factory(T t, Compression compression); @@ -118,7 +125,7 @@ { fin = fdopen(fd, "r"); if (!fin) - SN_THROW(IOErrorException(sformat("fdopen failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("fdopen failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); } @@ -133,8 +140,8 @@ { fin = fopen(name.c_str(), "re"); if (!fin) - SN_THROW(IOErrorException(sformat("fopen failed errno:%d (%s)", errno, - stringerror(errno).c_str()))); + SN_THROW(IOErrorException(sformat("fopen '%s' for reading failed, errno:%d (%s)", + name.c_str(), errno, stringerror(errno).c_str()))); } @@ -181,7 +188,7 @@ fin = nullptr; if (fclose(tmp) != 0) - SN_THROW(IOErrorException(sformat("fclose failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("fclose failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); } @@ -226,7 +233,7 @@ { gz_file = gzdopen(fd, "r"); if (!gz_file) - SN_THROW(IOErrorException(sformat("gzdopen failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("gzdopen failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); } @@ -236,17 +243,17 @@ { int fd = fileno(fin); if (fd < 0) - SN_THROW(IOErrorException(sformat("fileno failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("fileno failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); fd = dup(fd); if (fd < 0) - SN_THROW(IOErrorException(sformat("dup failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("dup failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); gz_file = gzdopen(fd, "r"); if (!gz_file) - SN_THROW(IOErrorException(sformat("gzdopen failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("gzdopen failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); fclose(fin); @@ -258,12 +265,12 @@ { int fd = open(name.c_str(), O_RDONLY | O_CLOEXEC | O_LARGEFILE); if (fd < 0) - SN_THROW(IOErrorException(sformat("open failed errno:%d (%s)", errno, - stringerror(errno).c_str()))); + SN_THROW(IOErrorException(sformat("open '%s' for reading failed, errno:%d (%s)", + name.c_str(), errno, stringerror(errno).c_str()))); gz_file = gzdopen(fd, "r"); if (!gz_file) - SN_THROW(IOErrorException(sformat("gzdopen failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("gzdopen failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); } @@ -294,7 +301,7 @@ int r = gzclose(tmp); if (r != Z_OK) - SN_THROW(IOErrorException(sformat("gzclose failed errnum:%d", r))); + SN_THROW(IOErrorException(sformat("gzclose failed, errnum:%d", r))); } @@ -309,7 +316,7 @@ int errnum = 0; const char* msg = gzerror(gz_file, &errnum); - SN_THROW(IOErrorException(sformat("gzread failed errno:%d (%s)", errnum, msg))); + SN_THROW(IOErrorException(sformat("gzread failed, errnum:%d (%s)", errnum, msg))); } buffer_read = 0; @@ -362,6 +369,9 @@ case Compression::GZIP: return unique_ptr<Impl::Gzip>(new Impl::Gzip(t)); + + case Compression::ZSTD: + break; } SN_THROW(LogicErrorException("unknown or unsupported compression")); @@ -412,6 +422,7 @@ class None; class Gzip; + class Zstd; template <typename T> static std::unique_ptr<AsciiFileWriter::Impl> factory(T t, Compression compression); @@ -450,7 +461,7 @@ { fout = fdopen(fd, "w"); if (!fout) - SN_THROW(IOErrorException(sformat("fdopen failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("fdopen failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); } @@ -465,8 +476,8 @@ { fout = fopen(name.c_str(), "we"); if (!fout) - SN_THROW(IOErrorException(sformat("fopen failed errno:%d (%s)", errno, - stringerror(errno).c_str()))); + SN_THROW(IOErrorException(sformat("fopen '%s' for writing failed, errno:%d (%s)", + name.c_str(), errno, stringerror(errno).c_str()))); } @@ -489,7 +500,7 @@ AsciiFileWriter::Impl::None::write_line(const string& line) { if (fprintf(fout, "%s\n", line.c_str()) != (int)(line.size() + 1)) - SN_THROW(IOErrorException(sformat("fprintf failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("fprintf failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); } @@ -504,7 +515,7 @@ fout = nullptr; if (fclose(tmp) != 0) - SN_THROW(IOErrorException(sformat("fclose failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("fclose failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); } @@ -530,7 +541,7 @@ gzFile gz_file = nullptr; vector<char> buffer; - size_t buffer_fill = 0; // position to which the buffer is full + size_t buffer_fill = 0; // position to which the buffer is filled void write_buffer(); @@ -548,7 +559,7 @@ { gz_file = gzdopen(fd, "w"); if (!gz_file) - SN_THROW(IOErrorException(sformat("gzdopen failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("gzdopen failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); } @@ -558,17 +569,17 @@ { int fd = fileno(fout); if (fd < 0) - SN_THROW(IOErrorException(sformat("fileno failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("fileno failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); fd = dup(fd); if (fd < 0) - SN_THROW(IOErrorException(sformat("dup failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("dup failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); gz_file = gzdopen(fd, "w"); if (!gz_file) - SN_THROW(IOErrorException(sformat("gzdopen failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("gzdopen failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); fclose(fout); @@ -580,12 +591,12 @@ { int fd = open(name.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_LARGEFILE, 0666); if (fd < 0) - SN_THROW(IOErrorException(sformat("open failed errno:%d (%s)", errno, - stringerror(errno).c_str()))); + SN_THROW(IOErrorException(sformat("open '%s' for writing failed, errno:%d (%s)", + name.c_str(), errno, stringerror(errno).c_str()))); gz_file = gzdopen(fd, "w"); if (!gz_file) - SN_THROW(IOErrorException(sformat("gzdopen failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("gzdopen failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); } @@ -618,19 +629,22 @@ int r = gzclose(tmp); if (r != Z_OK) - SN_THROW(IOErrorException(sformat("gzclose failed errnum:%d", r))); + SN_THROW(IOErrorException(sformat("gzclose failed, errnum:%d", r))); } void AsciiFileWriter::Impl::Gzip::write_buffer() { + if (buffer_fill == 0) + return; + int r = gzwrite(gz_file, buffer.data(), buffer_fill); - if (r <= 0) + if (r < (int)(buffer_fill)) { int errnum = 0; const char* msg = gzerror(gz_file, &errnum); - SN_THROW(IOErrorException(sformat("gzwrite failed errno:%d (%s)", errnum, msg))); + SN_THROW(IOErrorException(sformat("gzwrite failed, errnum:%d (%s)", errnum, msg))); } buffer_fill = 0; @@ -644,23 +658,193 @@ while (!tmp.empty()) { + // still available in buffer + size_t avail = buffer.size() - buffer_fill; + + // how much to copy into buffer + size_t to_copy = min(avail, tmp.size()); + + // copy into buffer and erase in tmp + memcpy(buffer.data() + buffer_fill, tmp.data(), to_copy); + buffer_fill += to_copy; + tmp.erase(0, to_copy); + + // if buffer is full, compress it and write to disk + if (buffer_fill == buffer.size()) + write_buffer(); + } + } + + +#if 0 + + // Needs libzstd >= 1.4. So unfortunately currently not suitable. + + class AsciiFileWriter::Impl::Zstd : public AsciiFileWriter::Impl + { + public: + + Zstd(int fd); + Zstd(FILE* fout); + Zstd(const string& name); + + virtual ~Zstd(); + + virtual void write_line(const string& line) override; + + virtual void close() override; + + private: + + Zstd(); + + FILE* fout = nullptr; + + ZSTD_CCtx* cctx = nullptr; + + vector<char> in_buffer; + size_t in_buffer_fill = 0; // position to which in_buffer is filled + + vector<char> out_buffer; + + void write_buffer(bool last); + + }; + + + AsciiFileWriter::Impl::Zstd::Zstd() + { + cctx = ZSTD_createCCtx(); + if (!cctx) + SN_THROW(Exception("ZSTD_createCCtx failed")); + + size_t r1 = ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 8); + if (ZSTD_isError(r1)) + SN_THROW(Exception("ZSTD_CCtx_setParameter with ZSTD_c_compressionLevel failed")); + + size_t r2 = ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1); + if (ZSTD_isError(r2)) + SN_THROW(Exception("ZSTD_CCtx_setParameter with ZSTD_c_checksumFlag failed")); + + in_buffer.resize(ZSTD_CStreamInSize()); + out_buffer.resize(ZSTD_CStreamOutSize()); + } + + + AsciiFileWriter::Impl::Zstd::Zstd(int fd) + : Zstd() + { + fout = fdopen(fd, "w"); + if (!fout) + SN_THROW(IOErrorException(sformat("fdopen failed, errno:%d (%s)", errno, + stringerror(errno).c_str()))); + } + + + AsciiFileWriter::Impl::Zstd::Zstd(FILE* fout) + : Zstd() + { + Zstd::fout = fout; + } + + + AsciiFileWriter::Impl::Zstd::Zstd(const string& name) + : Zstd() + { + fout = fopen(name.c_str(), "we"); + if (!fout) + SN_THROW(IOErrorException(sformat("fopen '%s' for writing failed, errno:%d (%s)", + name.c_str(), errno, stringerror(errno).c_str()))); + } + + + AsciiFileWriter::Impl::Zstd::~Zstd() + { + try + { + close(); + } + catch (const Exception& e) + { + SN_CAUGHT(e); + + y2err("exception ignored"); + } + + ZSTD_freeCCtx(cctx); + } + + + void + AsciiFileWriter::Impl::Zstd::close() + { + if (!fout) + return; + + write_buffer(true); + + FILE* tmp = fout; + fout = nullptr; + + if (fclose(tmp) != 0) + SN_THROW(IOErrorException(sformat("fclose failed, errno:%d (%s)", errno, + stringerror(errno).c_str()))); + } + + + void + AsciiFileWriter::Impl::Zstd::write_buffer(bool last) + { + ZSTD_EndDirective mode = last ? ZSTD_e_end : ZSTD_e_continue; + + ZSTD_inBuffer input = { in_buffer.data(), in_buffer_fill, 0 }; + + while (true) + { + ZSTD_outBuffer output = { out_buffer.data(), out_buffer.size(), 0 }; + + size_t remaining = ZSTD_compressStream2(cctx, &output, &input, mode); + if (ZSTD_isError(remaining)) + SN_THROW(Exception("ZSTD_compressStream2 failed")); + + size_t written = fwrite(output.dst, 1, output.pos, fout); + if (written != output.pos) + SN_THROW(IOErrorException("")); + + if (last ? (remaining == 0) : (input.pos == input.size)) + break; + } + + in_buffer_fill = 0; + } + + + void + AsciiFileWriter::Impl::Zstd::write_line(const string& line) + { + string tmp = line + "\n"; + + while (!tmp.empty()) + { // still available in input buffer - size_t in_avail = buffer.size() - buffer_fill; + size_t in_avail = in_buffer.size() - in_buffer_fill; // how much to copy into input buffer size_t to_copy = min(in_avail, tmp.size()); // copy into input buffer and erase in tmp - memcpy(buffer.data() + buffer_fill, tmp.data(), to_copy); - buffer_fill += to_copy; + memcpy(in_buffer.data() + in_buffer_fill, tmp.data(), to_copy); + in_buffer_fill += to_copy; tmp.erase(0, to_copy); // if input buffer is full, compress it and write to disk - if (buffer_fill == buffer.size()) - write_buffer(); + if (in_buffer_fill == in_buffer.size()) + write_buffer(false); } } +#endif + template <typename T> std::unique_ptr<AsciiFileWriter::Impl> @@ -673,6 +857,9 @@ case Compression::GZIP: return unique_ptr<Impl::Gzip>(new Impl::Gzip(t)); + + case Compression::ZSTD: + break; } SN_THROW(LogicErrorException("unknown or unsupported compression")); @@ -757,7 +944,7 @@ return; if (unlink(name.c_str()) != 0) - SN_THROW(IOErrorException(sformat("unlink failed errno:%d (%s)", errno, + SN_THROW(IOErrorException(sformat("unlink failed, errno:%d (%s)", errno, stringerror(errno).c_str()))); } else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/snapper/AsciiFile.h new/snapper-0.10.1/snapper/AsciiFile.h --- old/snapper-0.10.1/snapper/AsciiFile.h 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/snapper/AsciiFile.h 2022-05-03 02:00:00.000000000 +0200 @@ -40,7 +40,7 @@ using std::map; - enum class Compression { NONE, GZIP }; + enum class Compression { NONE, GZIP, ZSTD }; bool diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/snapper/FileUtils.cc new/snapper-0.10.1/snapper/FileUtils.cc --- old/snapper-0.10.1/snapper/FileUtils.cc 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/snapper/FileUtils.cc 2022-05-03 02:00:00.000000000 +0200 @@ -866,7 +866,8 @@ : base_dir(base_dir), name(name_template) { if (!base_dir.mkdtemp(name)) - throw runtime_error_with_errno("mkdtemp failed", errno); + SN_THROW(IOErrorException(sformat("mkdtmp failed errno:%d (%s)", errno, + stringerror(errno).c_str()))); } @@ -891,7 +892,8 @@ { SDir subdir(base_dir, name); if (!subdir.mount(device, mount_type, mount_flags, mount_data)) - throw runtime_error_with_errno("mount failed", errno); + SN_THROW(IOErrorException(sformat("mount failed errno:%d (%s)", errno, + stringerror(errno).c_str()))); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/snapper/LvmUtils.cc new/snapper-0.10.1/snapper/LvmUtils.cc --- old/snapper-0.10.1/snapper/LvmUtils.cc 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/snapper/LvmUtils.cc 2022-05-03 02:00:00.000000000 +0200 @@ -41,7 +41,7 @@ std::smatch match; if (!regex_match(name, match, rx)) - throw std::runtime_error("faild to split device name into volume group and " + throw std::runtime_error("failed to split device name into volume group and " "logical volume name"); string vg_name = boost::replace_all_copy(match[1].str(), "--", "-"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/snapper/Selinux.cc new/snapper-0.10.1/snapper/Selinux.cc --- old/snapper-0.10.1/snapper/Selinux.cc 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/snapper/Selinux.cc 2022-05-03 02:00:00.000000000 +0200 @@ -32,9 +32,12 @@ namespace snapper { + using std::map; + + SnapperContexts::SnapperContexts() { - std::map<string,string> snapperd_contexts; + map<string, string> snapperd_contexts; try { @@ -59,13 +62,13 @@ } } } - catch (const FileNotFoundException& e) + catch (const Exception& e) { SN_CAUGHT(e); SN_THROW(SelinuxException("Failed to parse contexts file")); } - std::map<string,string>::const_iterator cit = snapperd_contexts.find(selinux_snapperd_data); + map<string, string>::const_iterator cit = snapperd_contexts.find(selinux_snapperd_data); if (cit == snapperd_contexts.end()) { SN_THROW(SelinuxException("Snapperd data context not found")); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/snapper/Snapper.cc new/snapper-0.10.1/snapper/Snapper.cc --- old/snapper-0.10.1/snapper/Snapper.cc 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/snapper/Snapper.cc 2022-05-03 02:00:00.000000000 +0200 @@ -82,6 +82,8 @@ } catch (const InvalidKeyException& e) { + SN_CAUGHT(e); + SN_THROW(InvalidConfigdataException()); } } @@ -109,8 +111,10 @@ { config_info = new ConfigInfo(config_name, root_prefix); } - catch (const FileNotFoundException& e) + catch (const Exception& e) { + SN_CAUGHT(e); + SN_THROW(ConfigNotFoundException()); } @@ -145,6 +149,7 @@ } catch (const UmountSnapshotFailedException& e) { + SN_CAUGHT(e); } } @@ -302,25 +307,25 @@ vector<string> config_names; sysconfig.get_value("SNAPPER_CONFIGS", config_names); - for (vector<string>::const_iterator it = config_names.begin(); it != config_names.end(); ++it) + for (const string& config_name : config_names) { try { - config_infos.push_back(getConfig(*it, root_prefix)); - } - catch (const FileNotFoundException& e) - { - y2err("config '" << *it << "' not found"); + config_infos.push_back(getConfig(config_name, root_prefix)); } - catch (const InvalidConfigException& e) + catch (const Exception& e) { - y2err("config '" << *it << "' is invalid"); + SN_CAUGHT(e); + + y2err("reading config '" << config_name << "' failed"); } } } - catch (const FileNotFoundException& e) + catch (const Exception& e) { - SN_THROW(ListConfigsFailedException("sysconfig-file not found")); + SN_CAUGHT(e); + + SN_THROW(ListConfigsFailedException("reading sysconfig-file failed")); } return config_infos; @@ -374,10 +379,14 @@ } catch (const InvalidConfigException& e) { + SN_CAUGHT(e); + SN_THROW(CreateConfigFailedException("invalid filesystem type")); } catch (const ProgramNotInstalledException& e) { + SN_CAUGHT(e); + SN_THROW(CreateConfigFailedException(e.what())); } @@ -393,9 +402,13 @@ config_names.push_back(config_name); sysconfig.set_value("SNAPPER_CONFIGS", config_names); + + sysconfig.save(); } - catch (const FileNotFoundException& e) + catch (const Exception& e) { + SN_CAUGHT(e); + SN_THROW(CreateConfigFailedException("sysconfig-file not found")); } @@ -407,9 +420,13 @@ config.set_value(KEY_SUBVOLUME, subvolume); config.set_value(KEY_FSTYPE, filesystem->fstype()); + + config.save(); } - catch (const FileNotFoundException& e) + catch (const Exception& e) { + SN_CAUGHT(e); + SN_THROW(CreateConfigFailedException("modifying config failed")); } @@ -428,6 +445,8 @@ config_names.end()); sysconfig.set_value("SNAPPER_CONFIGS", config_names); + sysconfig.save(); + SystemCmd cmd(RMBIN " " + quote(CONFIGS_DIR "/" + config_name)); SN_RETHROW(e); @@ -465,6 +484,8 @@ } catch (const DeleteSnapshotFailedException& e) { + SN_CAUGHT(e); + // ignore, Filesystem->deleteConfig will fail anyway } } @@ -475,6 +496,8 @@ } catch (const DeleteConfigFailedException& e) { + SN_CAUGHT(e); + SN_THROW(DeleteConfigFailedException("deleting snapshot failed")); } @@ -492,10 +515,14 @@ config_names.erase(remove(config_names.begin(), config_names.end(), config_name), config_names.end()); sysconfig.set_value("SNAPPER_CONFIGS", config_names); + + sysconfig.save(); } - catch (const FileNotFoundException& e) + catch (const Exception& e) { - SN_THROW(DeleteConfigFailedException("sysconfig-file not found")); + SN_CAUGHT(e); + + SN_THROW(DeleteConfigFailedException("modifying sysconfig-file failed")); } } @@ -1025,6 +1052,8 @@ compression = Compression::NONE; else if (tmp == "gzip") compression = Compression::GZIP; + else if (tmp == "zstd") + compression = Compression::ZSTD; } if (!is_available(compression)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/snapper/Snapshot.cc new/snapper-0.10.1/snapper/Snapshot.cc --- old/snapper-0.10.1/snapper/Snapshot.cc 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/snapper/Snapshot.cc 2022-05-03 02:00:00.000000000 +0200 @@ -210,6 +210,9 @@ { SDir info_dir(infos_dir, *it1); int fd = info_dir.open("info.xml", O_NOFOLLOW | O_CLOEXEC); + if (fd < 0) + SN_THROW(IOErrorException("open info.xml failed")); + XmlFile file(fd, ""); const xmlNode* node = file.getRootElement(); @@ -272,8 +275,10 @@ entries.push_back(snapshot); } - catch (const IOErrorException& e) + catch (const Exception& e) { + SN_CAUGHT(e); + y2err("loading " << *it1 << " failed"); } } @@ -370,6 +375,8 @@ } catch (const IOErrorException& e) { + SN_CAUGHT(e); + y2err("reading failed"); } @@ -496,12 +503,29 @@ SDir info_dir = openInfoDir(); - xml.save(info_dir.mktemp(tmp_name)); + int fd = info_dir.mktemp(tmp_name); + if (fd < 0) + SN_THROW(IOErrorException("mktemp failed")); + + try + { + xml.save(fd); + } + catch (const Exception& e) + { + SN_CAUGHT(e); + + info_dir.unlink(tmp_name, 0); + + SN_RETHROW(e); + } if (info_dir.rename(tmp_name, file_name) != 0) + { SN_THROW(IOErrorException(sformat("rename info.xml failed infoDir:%s errno:%d (%s)", info_dir.fullname().c_str(), errno, stringerror(errno).c_str()))); + } info_dir.fsync(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/snapper/Version.h new/snapper-0.10.1/snapper/Version.h --- old/snapper-0.10.1/snapper/Version.h 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/snapper/Version.h 2022-05-03 02:00:00.000000000 +0200 @@ -26,7 +26,7 @@ #define LIBSNAPPER_MAJOR="6" #define LIBSNAPPER_MINOR="0" -#define LIBSNAPPER_PATCHLEVEL="0" +#define LIBSNAPPER_PATCHLEVEL="1" #define LIBSNAPPER_VERSION ( LIBSNAPPER_MAJOR * 10000 + \\ LIBSNAPPER_MINOR * 100 + \\ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/snapper-0.10.1/snapper/XmlFile.cc new/snapper-0.10.1/snapper/XmlFile.cc --- old/snapper-0.10.1/snapper/XmlFile.cc 2022-04-22 02:00:00.000000000 +0200 +++ new/snapper-0.10.1/snapper/XmlFile.cc 2022-05-03 02:00:00.000000000 +0200 @@ -1,6 +1,6 @@ /* * Copyright (c) [2010-2012] Novell, Inc. - * Copyright (c) 2020 SUSE LLC + * Copyright (c) [2020-2022] SUSE LLC * * All Rights Reserved. * @@ -35,7 +35,7 @@ : doc(xmlNewDoc((const xmlChar*) "1.0")) { if (!doc) - throw BadAllocException(); + SN_THROW(BadAllocException()); } @@ -45,7 +45,7 @@ close(fd); if (!doc) - throw IOErrorException("xmlReadFd failed"); + SN_THROW(IOErrorException("xmlReadFd failed")); } @@ -53,7 +53,7 @@ : doc(xmlReadFile(filename.c_str(), NULL, XML_PARSE_NOBLANKS | XML_PARSE_NONET)) { if (!doc) - throw IOErrorException("xmlReadFile failed"); + SN_THROW(IOErrorException("xmlReadFile failed")); } @@ -69,17 +69,22 @@ { FILE* f = fdopen(fd, "w"); if (!f) - throw IOErrorException("fdopen"); + { + close(fd); + SN_THROW(IOErrorException("fdopen")); + } if (xmlDocFormatDump(f, doc, 1) == -1) { fclose(f); - throw IOErrorException("xmlDocFormatDump failed"); + SN_THROW(IOErrorException("xmlDocFormatDump failed")); } fflush(f); fsync(fileno(f)); - fclose(f); + + if (fclose(f) != 0) + SN_THROW(IOErrorException("fclose failed")); } @@ -87,7 +92,7 @@ XmlFile::save(const string& filename) { if (xmlSaveFormatFile(filename.c_str(), doc, 1) == -1) - throw IOErrorException("xmlSaveFormatFile failed"); + SN_THROW(IOErrorException("xmlSaveFormatFile failed")); } ++++++ snapper-Debian_10.0.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.221521869 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.225521873 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-Debian_11.0.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.245521899 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.249521903 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-Debian_Unstable.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.277521938 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.281521944 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-xUbuntu_18.04.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.345522023 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.349522029 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-xUbuntu_18.10.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.369522053 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.373522059 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-xUbuntu_19.04.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.393522084 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.397522088 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-xUbuntu_19.10.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.417522114 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.421522118 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-xUbuntu_20.04.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.441522144 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.449522154 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-xUbuntu_20.10.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.473522183 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.477522188 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-xUbuntu_21.04.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.497522213 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.501522219 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-xUbuntu_21.10.dsc ++++++ --- /var/tmp/diff_new_pack.txQUqk/_old 2022-05-05 23:05:55.521522243 +0200 +++ /var/tmp/diff_new_pack.txQUqk/_new 2022-05-05 23:05:55.525522249 +0200 @@ -11,5 +11,5 @@ # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: -7d5278400ef75e36903c1afe4fa0afba 665846 snapper-0.10.1.tar.bz2 +fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2 ++++++ snapper-xUbuntu_22.04.dsc ++++++ Format: 1.0 Source: snapper Version: 0.10.1-1 Binary: snapper Maintainer: Arvin Schnell <aschn...@suse.com> Architecture: any Build-Depends: debhelper (>= 4.1.16), acl-dev, dbus, g++, libboost-dev, libboost-thread-dev, libboost-system-dev, libboost-test-dev, libxml2-dev, libz-dev, libdbus-1-dev, libjson-c-dev, libpam-dev, xsltproc, docbook-xsl, language-pack-en, language-pack-de, language-pack-fr, ncurses-dev # # The 'Files' line is generated during 'make package': # Files: # 423a20ae6e882d44e65a4eff97f2269f 630905 snapper-0.2.8.tar.gz # Files: fef3bc444369b4b5fd6480348c1ee464 666213 snapper-0.10.1.tar.bz2