gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] 04/08: NAMESTORE: Use a per client database connection


From: gnunet
Subject: [gnunet] 04/08: NAMESTORE: Use a per client database connection
Date: Fri, 23 Sep 2022 06:01:08 +0200

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

commit 127ad07a3abaee00fb206aaf8b980f258d2933c8
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Fri Sep 23 01:06:59 2022 +0900

    NAMESTORE: Use a per client database connection
    
    Each connecting namestore client will now get a new database connection
    through any of the plugins. This will allow us to properly use locking
    in databases where available.
---
 src/namestore/gnunet-service-namestore.c  | 146 ++++++++++++++++--------------
 src/namestore/plugin_namestore_flat.c     |  16 ++--
 src/namestore/plugin_namestore_postgres.c |  16 ++--
 src/namestore/plugin_namestore_sqlite.c   |  32 +++----
 4 files changed, 107 insertions(+), 103 deletions(-)

diff --git a/src/namestore/gnunet-service-namestore.c 
b/src/namestore/gnunet-service-namestore.c
index 6d3cc45ec..a173e8927 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -131,6 +131,11 @@ struct NamestoreClient
    */
   struct GNUNET_SERVICE_Client *client;
 
+  /**
+   * Database handle
+   */
+  struct GNUNET_NAMESTORE_PluginFunctions *GSN_database;
+
   /**
    * Message queue for transmission to @e client
    */
@@ -352,11 +357,6 @@ static struct GNUNET_STATISTICS_Handle *statistics;
  */
 static struct GNUNET_NAMECACHE_Handle *namecache;
 
-/**
- * Database handle
- */
-static struct GNUNET_NAMESTORE_PluginFunctions *GSN_database;
-
 /**
  * Name of the database plugin
  */
@@ -436,7 +436,6 @@ cleanup_task (void *cls)
     GNUNET_NAMECACHE_disconnect (namecache);
     namecache = NULL;
   }
-  GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database));
   GNUNET_free (db_lib_name);
   db_lib_name = NULL;
   if (NULL != monitor_nc)
@@ -560,11 +559,13 @@ cache_nick (const struct GNUNET_IDENTITY_PrivateKey *zone,
 /**
  * Return the NICK record for the zone (if it exists).
  *
+ * @param nc the namestore client
  * @param zone private key for the zone to look for nick
  * @return NULL if no NICK record was found
  */
 static struct GNUNET_GNSRECORD_Data *
-get_nick_record (const struct GNUNET_IDENTITY_PrivateKey *zone)
+get_nick_record (const struct NamestoreClient *nc,
+                 const struct GNUNET_IDENTITY_PrivateKey *zone)
 {
   struct GNUNET_IDENTITY_PublicKey pub;
   struct GNUNET_GNSRECORD_Data *nick;
@@ -588,11 +589,11 @@ get_nick_record (const struct GNUNET_IDENTITY_PrivateKey 
*zone)
   }
 
   nick = NULL;
-  res = GSN_database->lookup_records (GSN_database->cls,
-                                      zone,
-                                      GNUNET_GNS_EMPTY_LABEL_AT,
-                                      &lookup_nick_it,
-                                      &nick);
+  res = nc->GSN_database->lookup_records (nc->GSN_database->cls,
+                                          zone,
+                                          GNUNET_GNS_EMPTY_LABEL_AT,
+                                          &lookup_nick_it,
+                                          &nick);
   if ((GNUNET_OK != res) || (NULL == nick))
   {
 #if ! defined(GNUNET_CULL_LOGGING)
@@ -735,7 +736,7 @@ send_lookup_response (struct NamestoreClient *nc,
   char *name_tmp;
   char *rd_ser;
 
-  nick = get_nick_record (zone_key);
+  nick = get_nick_record (nc, zone_key);
   GNUNET_assert (-1 != GNUNET_GNSRECORD_records_get_size (rd_count, rd));
 
   if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
@@ -936,7 +937,7 @@ refresh_block (struct NamestoreClient *nc,
     rd_clean[rd_count_clean++] = rd[i];
   }
 
-  nick = get_nick_record (zone_key);
+  nick = get_nick_record (nc, zone_key);
   res_count = rd_count_clean;
   res = (struct GNUNET_GNSRECORD_Data *) rd_clean;  /* fixme: a bit unclean... 
*/
   if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
@@ -1168,6 +1169,7 @@ client_disconnect_cb (void *cls,
   for (cop = cop_head; NULL != cop; cop = cop->next)
     if (nc == cop->nc)
       cop->nc = NULL;
+  GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, nc->GSN_database));
   GNUNET_free (nc);
 }
 
@@ -1186,12 +1188,35 @@ client_connect_cb (void *cls,
                    struct GNUNET_MQ_Handle *mq)
 {
   struct NamestoreClient *nc;
+  char *database;
+  char *db_lib_name;
 
   (void) cls;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
   nc = GNUNET_new (struct NamestoreClient);
   nc->client = client;
   nc->mq = mq;
+  /* Loading database plugin */
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (GSN_cfg,
+                                                          "namestore",
+                                                          "database",
+                                                          &database))
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
+  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Loading %s\n", db_lib_name);
+  nc->GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
+  GNUNET_free (database);
+  if (NULL == nc->GSN_database)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Could not load database backend `%s'\n",
+                db_lib_name);
+    GNUNET_free (db_lib_name);
+    GNUNET_free (nc);
+    return NULL;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Loaded %s\n", db_lib_name);
+  GNUNET_free (db_lib_name);
   return nc;
 }
 
@@ -1402,12 +1427,12 @@ handle_record_lookup (void *cls, const struct 
LabelLookupMessage *ll_msg)
   rlc.res_rd_count = 0;
   rlc.res_rd = NULL;
   rlc.rd_ser_len = 0;
-  rlc.nick = get_nick_record (&ll_msg->zone);
-  res = GSN_database->lookup_records (GSN_database->cls,
-                                      &ll_msg->zone,
-                                      conv_name,
-                                      &lookup_it,
-                                      &rlc);
+  rlc.nick = get_nick_record (nc, &ll_msg->zone);
+  res = nc->GSN_database->lookup_records (nc->GSN_database->cls,
+                                          &ll_msg->zone,
+                                          conv_name,
+                                          &lookup_it,
+                                          &rlc);
   env =
     GNUNET_MQ_msg_extra (llr_msg,
                          name_len + rlc.rd_ser_len,
@@ -1591,11 +1616,11 @@ handle_record_store (void *cls, const struct 
RecordStoreMessage *rp_msg)
                 "Creating %u records for name `%s'\n",
                 (unsigned int) rd_count,
                 conv_name);
-    if ((GNUNET_NO == GSN_database->lookup_records (GSN_database->cls,
-                                                    &rp_msg->private_key,
-                                                    conv_name,
-                                                    &get_block_exp_existing,
-                                                    &existing_block_exp)) &&
+    if ((GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls,
+                                                        &rp_msg->private_key,
+                                                        conv_name,
+                                                        
&get_block_exp_existing,
+                                                        &existing_block_exp)) 
&&
         (rd_count == 0))
     {
       /* This name does not exist, so cannot be removed */
@@ -1676,11 +1701,11 @@ handle_record_store (void *cls, const struct 
RecordStoreMessage *rp_msg)
         /* remove nick record from cache, in case we have one there */
         cache_nick (&rp_msg->private_key, NULL);
       }
-      res = GSN_database->store_records (GSN_database->cls,
-                                         &rp_msg->private_key,
-                                         conv_name,
-                                         rd_nf_count,
-                                         rd_nf);
+      res = nc->GSN_database->store_records (nc->GSN_database->cls,
+                                             &rp_msg->private_key,
+                                             conv_name,
+                                             rd_nf_count,
+                                             rd_nf);
     }
 
     if (GNUNET_OK != res)
@@ -1817,11 +1842,11 @@ handle_zone_to_name (void *cls, const struct 
ZoneToNameMessage *ztn_msg)
   ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
   ztn_ctx.nc = nc;
   ztn_ctx.success = GNUNET_NO;
-  if (GNUNET_SYSERR == GSN_database->zone_to_name (GSN_database->cls,
-                                                   &ztn_msg->zone,
-                                                   &ztn_msg->value_zone,
-                                                   &handle_zone_to_name_it,
-                                                   &ztn_ctx))
+  if (GNUNET_SYSERR == nc->GSN_database->zone_to_name (nc->GSN_database->cls,
+                                                       &ztn_msg->zone,
+                                                       &ztn_msg->value_zone,
+                                                       &handle_zone_to_name_it,
+                                                       &ztn_ctx))
   {
     /* internal error, hang up instead of signalling something
        that might be wrong */
@@ -1935,6 +1960,7 @@ run_zone_iteration_round (struct ZoneIteration *zi, 
uint64_t limit)
   struct ZoneIterationProcResult proc;
   struct GNUNET_TIME_Absolute start;
   struct GNUNET_TIME_Relative duration;
+  struct NamestoreClient *nc = zi->nc;
 
   memset (&proc, 0, sizeof(proc));
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1945,15 +1971,16 @@ run_zone_iteration_round (struct ZoneIteration *zi, 
uint64_t limit)
   proc.limit = limit;
   start = GNUNET_TIME_absolute_get ();
   GNUNET_break (GNUNET_SYSERR !=
-                GSN_database->iterate_records (GSN_database->cls,
-                                               (GNUNET_YES == GNUNET_is_zero (
-                                                  &zi->zone))
+                nc->GSN_database->iterate_records (nc->GSN_database->cls,
+                                                   (GNUNET_YES ==
+                                                    GNUNET_is_zero (
+                                                      &zi->zone))
                                                ? NULL
                                                : &zi->zone,
-                                               zi->seq,
-                                               limit,
-                                               &zone_iterate_proc,
-                                               &proc));
+                                                   zi->seq,
+                                                   limit,
+                                                   &zone_iterate_proc,
+                                                   &proc));
   duration = GNUNET_TIME_absolute_get_duration (start);
   duration = GNUNET_TIME_relative_divide (duration, limit - proc.limit);
   GNUNET_STATISTICS_set (statistics,
@@ -2212,6 +2239,7 @@ static void
 monitor_iteration_next (void *cls)
 {
   struct ZoneMonitor *zm = cls;
+  struct NamestoreClient *nc = zm->nc;
   int ret;
 
   zm->task = NULL;
@@ -2220,15 +2248,13 @@ monitor_iteration_next (void *cls)
     zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
   else
     zm->iteration_cnt = zm->limit; /* use it all */
-  ret = GSN_database->iterate_records (GSN_database->cls,
-                                       (GNUNET_YES == GNUNET_is_zero (
-                                          &zm->zone))
-                                       ? NULL
-                                       : &zm->zone,
-                                       zm->seq,
-                                       zm->iteration_cnt,
-                                       &monitor_iterate_cb,
-                                       zm);
+  ret = nc->GSN_database->iterate_records (nc->GSN_database->cls,
+                                           (GNUNET_YES == GNUNET_is_zero (
+                                              &zm->zone)) ? NULL : &zm->zone,
+                                           zm->seq,
+                                           zm->iteration_cnt,
+                                           &monitor_iterate_cb,
+                                           zm);
   if (GNUNET_SYSERR == ret)
   {
     GNUNET_SERVICE_client_drop (zm->nc->client);
@@ -2330,26 +2356,8 @@ run (void *cls,
     namecache = GNUNET_NAMECACHE_connect (cfg);
     GNUNET_assert (NULL != namecache);
   }
-  /* Loading database plugin */
-  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
-                                                          "namestore",
-                                                          "database",
-                                                          &database))
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
-
-  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
-  GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
-  GNUNET_free (database);
   statistics = GNUNET_STATISTICS_create ("namestore", cfg);
   GNUNET_SCHEDULER_add_shutdown (&cleanup_task, NULL);
-  if (NULL == GSN_database)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Could not load database backend `%s'\n",
-                db_lib_name);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
 }
 
 
diff --git a/src/namestore/plugin_namestore_flat.c 
b/src/namestore/plugin_namestore_flat.c
index 3576b14e0..3feac60d8 100644
--- a/src/namestore/plugin_namestore_flat.c
+++ b/src/namestore/plugin_namestore_flat.c
@@ -767,19 +767,16 @@ namestore_flat_zone_to_name (void *cls,
 void *
 libgnunet_plugin_namestore_flat_init (void *cls)
 {
-  static struct Plugin plugin;
+  struct Plugin *plugin;
   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
   struct GNUNET_NAMESTORE_PluginFunctions *api;
 
-  if (NULL != plugin.cfg)
-    return NULL;                /* can only initialize once! */
-  memset (&plugin,
-          0,
-          sizeof(struct Plugin));
-  plugin.cfg = cfg;
-  if (GNUNET_OK != database_setup (&plugin))
+  plugin = GNUNET_new (struct Plugin);
+  plugin->cfg = cfg;
+  if (GNUNET_OK != database_setup (plugin))
   {
-    database_shutdown (&plugin);
+    database_shutdown (plugin);
+    GNUNET_free (plugin);
     return NULL;
   }
   api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
@@ -808,6 +805,7 @@ libgnunet_plugin_namestore_flat_done (void *cls)
 
   database_shutdown (plugin);
   plugin->cfg = NULL;
+  GNUNET_free (plugin);
   GNUNET_free (api);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Flat file plugin is finished\n");
diff --git a/src/namestore/plugin_namestore_postgres.c 
b/src/namestore/plugin_namestore_postgres.c
index bdbaf96b3..54a19794f 100644
--- a/src/namestore/plugin_namestore_postgres.c
+++ b/src/namestore/plugin_namestore_postgres.c
@@ -577,21 +577,20 @@ database_shutdown (struct Plugin *plugin)
 void *
 libgnunet_plugin_namestore_postgres_init (void *cls)
 {
-  static struct Plugin plugin;
+  struct Plugin *plugin;
   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
   struct GNUNET_NAMESTORE_PluginFunctions *api;
 
-  if (NULL != plugin.cfg)
-    return NULL;                /* can only initialize once! */
-  memset (&plugin, 0, sizeof(struct Plugin));
-  plugin.cfg = cfg;
-  if (GNUNET_OK != database_setup (&plugin))
+  plugin = GNUNET_new (struct Plugin);
+  plugin->cfg = cfg;
+  if (GNUNET_OK != database_setup (plugin))
   {
-    database_shutdown (&plugin);
+    database_shutdown (plugin);
+    GNUNET_free (plugin);
     return NULL;
   }
   api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
-  api->cls = &plugin;
+  api->cls = plugin;
   api->store_records = &namestore_postgres_store_records;
   api->iterate_records = &namestore_postgres_iterate_records;
   api->zone_to_name = &namestore_postgres_zone_to_name;
@@ -616,6 +615,7 @@ libgnunet_plugin_namestore_postgres_done (void *cls)
 
   database_shutdown (plugin);
   plugin->cfg = NULL;
+  GNUNET_free (plugin);
   GNUNET_free (api);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Postgres namestore plugin is finished\n");
diff --git a/src/namestore/plugin_namestore_sqlite.c 
b/src/namestore/plugin_namestore_sqlite.c
index f2017b695..fd81780fb 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -129,7 +129,7 @@ database_setup (struct Plugin *plugin)
     GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"),
     GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
     GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
-    GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=EXCLUSIVE"),
+    GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=NORMAL"),
     GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
     GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
     GNUNET_SQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records ("
@@ -201,17 +201,16 @@ database_setup (struct Plugin *plugin)
       return GNUNET_SYSERR;
     }
   }
-  /* sqlite_filename should be UTF-8-encoded. If it isn't, it's a bug */
-  plugin->fn = sqlite_filename;
 
   /* Open database and precompile statements */
   if (SQLITE_OK !=
-      sqlite3_open (plugin->fn,
+      sqlite3_open (sqlite_filename,
                     &plugin->dbh))
   {
     LOG (GNUNET_ERROR_TYPE_ERROR,
          _ ("Unable to initialize SQLite: %s.\n"),
          sqlite3_errmsg (plugin->dbh));
+    GNUNET_free (sqlite_filename);
     return GNUNET_SYSERR;
   }
   GNUNET_break (SQLITE_OK ==
@@ -224,7 +223,8 @@ database_setup (struct Plugin *plugin)
     GNUNET_break (0);
     LOG (GNUNET_ERROR_TYPE_ERROR,
          _ ("Failed to setup database at `%s'\n"),
-         plugin->fn);
+         sqlite_filename);
+    GNUNET_free (sqlite_filename);
     return GNUNET_SYSERR;
   }
 
@@ -235,7 +235,8 @@ database_setup (struct Plugin *plugin)
     GNUNET_break (0);
     LOG (GNUNET_ERROR_TYPE_ERROR,
          _ ("Failed to setup database at `%s'\n"),
-         plugin->fn);
+         sqlite_filename);
+    GNUNET_free (sqlite_filename);
     return GNUNET_SYSERR;
   }
   return GNUNET_OK;
@@ -296,7 +297,6 @@ database_shutdown (struct Plugin *plugin)
                 GNUNET_ERROR_TYPE_ERROR,
                 "sqlite3_close");
 
-  GNUNET_free (plugin->fn);
 }
 
 
@@ -802,23 +802,20 @@ namestore_sqlite_transaction_commit (void *cls,
 void *
 libgnunet_plugin_namestore_sqlite_init (void *cls)
 {
-  static struct Plugin plugin;
+  struct Plugin *plugin;
   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
   struct GNUNET_NAMESTORE_PluginFunctions *api;
 
-  if (NULL != plugin.cfg)
-    return NULL;                /* can only initialize once! */
-  memset (&plugin,
-          0,
-          sizeof(struct Plugin));
-  plugin.cfg = cfg;
-  if (GNUNET_OK != database_setup (&plugin))
+  plugin = GNUNET_new (struct Plugin);
+  plugin->cfg = cfg;
+  if (GNUNET_OK != database_setup (plugin))
   {
-    database_shutdown (&plugin);
+    database_shutdown (plugin);
+    GNUNET_free (plugin);
     return NULL;
   }
   api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
-  api->cls = &plugin;
+  api->cls = plugin;
   api->store_records = &namestore_sqlite_store_records;
   api->iterate_records = &namestore_sqlite_iterate_records;
   api->zone_to_name = &namestore_sqlite_zone_to_name;
@@ -846,6 +843,7 @@ libgnunet_plugin_namestore_sqlite_done (void *cls)
 
   database_shutdown (plugin);
   plugin->cfg = NULL;
+  GNUNET_free (plugin);
   GNUNET_free (api);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "sqlite plugin is finished\n");

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]