]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
libcephsqlite: register atexit handler for cleanup 42035/head
authorPatrick Donnelly <pdonnell@redhat.com>
Sat, 26 Jun 2021 18:26:41 +0000 (11:26 -0700)
committerPatrick Donnelly <pdonnell@redhat.com>
Sun, 27 Jun 2021 02:29:21 +0000 (19:29 -0700)
We need to tear down the ceph vfs when sqlite3 (or other binaries) call
exit(). Otherwise global state gets destructed which can cause library
threads to segfault or raise exceptions.

Also pull vfs struct out of appdata. We need to be able to detect double
calls to the atexit handler which, sadly, can happen.

Fixes: https://tracker.ceph.com/issues/50503
Fixes: https://tracker.ceph.com/issues/51372
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
src/libcephsqlite.cc

index ccc4316b8fb4487771482646453604d6a0fc0531..346cd3f1bc4df9b49405885964e072cb852dee5a 100644 (file)
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <cstdlib>
 #include <iomanip>
 #include <iostream>
 #include <regex>
@@ -137,7 +138,6 @@ struct cephsqlite_appdata {
   std::unique_ptr<PerfCounters> logger;
   std::shared_ptr<PerfCounters> striper_logger;
   librados::Rados cluster;
-  struct sqlite3_vfs vfs{};
 };
 
 struct cephsqlite_fileloc {
@@ -790,14 +790,25 @@ static int autoreg(sqlite3* db, char** err, const struct sqlite3_api_routines* t
   return SQLITE_OK;
 }
 
+static void cephsqlite_atexit()
+{
+  if (auto vfs = sqlite3_vfs_find("ceph"); vfs) {
+    if (vfs->pAppData) {
+      auto&& appd = getdata(vfs);
+      delete &appd;
+      vfs->pAppData = nullptr;
+    }
+  }
+}
+
 LIBCEPHSQLITE_API int sqlite3_cephsqlite_init(sqlite3* db, char** err, const sqlite3_api_routines* api)
 {
   SQLITE_EXTENSION_INIT2(api);
 
   auto vfs = sqlite3_vfs_find("ceph");
   if (!vfs) {
+    vfs = (sqlite3_vfs*) calloc(1, sizeof(sqlite3_vfs));
     auto appd = new cephsqlite_appdata;
-    vfs = &appd->vfs;
     vfs->iVersion = 2;
     vfs->szOsFile = sizeof(struct cephsqlite_file);
     vfs->mxPathname = 4096;
@@ -808,8 +819,15 @@ LIBCEPHSQLITE_API int sqlite3_cephsqlite_init(sqlite3* db, char** err, const sql
     vfs->xAccess = Access;
     vfs->xFullPathname = FullPathname;
     vfs->xCurrentTimeInt64 = CurrentTime;
-    appd->cct = nullptr;
-    sqlite3_vfs_register(vfs, 0);
+    if (int rc = sqlite3_vfs_register(vfs, 0); rc) {
+      delete appd;
+      free(vfs);
+      return rc;
+    }
+  }
+
+  if (int rc = std::atexit(cephsqlite_atexit); rc) {
+    return SQLITE_INTERNAL;
   }
 
   if (int rc = sqlite3_auto_extension((void(*)(void))autoreg); rc) {