]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Zap tmp files; use random suffix and fix leak by using smart pointer.
authorOtto <otto.moerbeek@open-xchange.com>
Mon, 29 Mar 2021 09:49:34 +0000 (11:49 +0200)
committerOtto <otto.moerbeek@open-xchange.com>
Mon, 29 Mar 2021 09:49:34 +0000 (11:49 +0200)
pdns/nod.cc
pdns/nod.hh
pdns/recursordist/stable-bloom.hh

index cc0b2761e2458e2a2501bf0389bd41373147c747..63733a65fca56175135621ec165b3b37e3181796 100644 (file)
@@ -40,6 +40,17 @@ using namespace boost::filesystem;
 
 std::mutex PersistentSBF::d_cachedir_mutex;
 
+void PersistentSBF::remove_tmp_files()
+{
+  path p(d_cachedir);
+  Regex file_regex(d_prefix + ".*\\." + bf_suffix + "\\.[[:xdigit:]]{8}$");
+  for (directory_iterator i(p); i != directory_iterator(); ++i) {
+    if (is_regular_file(i->path()) && file_regex.match(i->path().filename().string())) {
+      remove(*i);
+    }
+  }
+}
+
 // This looks for an old (per-thread) snapshot. The first one it finds,
 // it restores from that. Then immediately snapshots with the current thread id,// before removing the old snapshot
 // In this way, we can have per-thread SBFs, but still snapshot and restore.
@@ -54,6 +65,7 @@ bool PersistentSBF::init(bool ignore_pid) {
     path p(d_cachedir);
     try {
       if (exists(p) && is_directory(p)) {
+        remove_tmp_files();
         path newest_file;
         std::time_t newest_time=time(nullptr);
         Regex file_regex(d_prefix + ".*\\." + bf_suffix + "$");
@@ -126,8 +138,7 @@ bool PersistentSBF::snapshotCurrent(std::thread::id tid)
     std::stringstream ss;
     ss << d_prefix << "_" << tid;
     f /= ss.str() + "_" + std::to_string(getpid()) + "." + bf_suffix;
-    path ftmp = f;
-    ftmp += ".tmp";
+    path ftmp(unique_path(f.string() + ".%%%%%%%%"));
     if (exists(p) && is_directory(p)) {
       try {
         std::ofstream ofile;
@@ -147,7 +158,14 @@ bool PersistentSBF::snapshotCurrent(std::thread::id tid)
           throw std::runtime_error("Failed to write to file:" + ftmp.string());
         }
         ofile.close();
-        rename(ftmp, f);
+        try {
+          rename(ftmp, f);
+        }
+        catch (const std::runtime_error& e) {
+          g_log<<Logger::Warning<<"NODDB snapshot: Cannot rename file: " << e.what() << endl;
+          remove(ftmp);
+          throw;
+        }
         return true;
       }
       catch (const std::runtime_error& e) {
index ce32f12d2503f7cd3e4550ba553c973106be1980..a801b1a0e5cdebbed9f8041d52f7405f7af5412e 100644 (file)
@@ -59,6 +59,8 @@ namespace nod {
       return d_sbf.testAndAdd(data); 
     }
   private:
+    void remove_tmp_files();
+
     bool d_init{false};
     bf::stableBF d_sbf; // Stable Bloom Filter
     std::string d_cachedir;
index a6cc5720f6321927ffebd49f8e132cc8d7d97ce4..9fc343f88b34ea72f0872ca9c10a015e3e7fe233 100644 (file)
@@ -123,13 +123,12 @@ public:
       throw std::runtime_error("SBF: read failed (file too short?)");
     }
     bitstr_len = ntohl(bitstr_len);
-    char* bitcstr = new char[bitstr_len];
-    is.read((char*)bitcstr, bitstr_len);
+    unique_ptr<char[]> bitcstr = make_unique<char[]>(bitstr_len);
+    is.read(bitcstr.get(), bitstr_len);
     if (is.fail()) {
       throw std::runtime_error("SBF: read failed (file too short?)");
     }
-    std::string bitstr(bitcstr, bitstr_len);
-    delete[] bitcstr;
+    std::string bitstr(bitcstr.get(), bitstr_len);
     stableBF tempbf(k, num_cells, p, bitstr);
     swap(tempbf);
   }