aboutsummaryrefslogtreecommitdiff
path: root/src/datastore/gnunet-service-datastore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datastore/gnunet-service-datastore.c')
-rw-r--r--src/datastore/gnunet-service-datastore.c143
1 files changed, 140 insertions, 3 deletions
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index 40ea153de..01778b1b7 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -42,6 +42,13 @@
42 */ 42 */
43#define MAX_EXPIRE_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) 43#define MAX_EXPIRE_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
44 44
45#define QUOTA_STAT_NAME gettext_noop ("# bytes used in file-sharing datastore")
46
47/**
48 * After how many payload-changing operations
49 * do we sync our statistics?
50 */
51#define MAX_STAT_SYNC_LAG 50
45 52
46 53
47/** 54/**
@@ -109,6 +116,7 @@ struct ReservationList
109}; 116};
110 117
111 118
119
112/** 120/**
113 * Our datastore plugin (NULL if not available). 121 * Our datastore plugin (NULL if not available).
114 */ 122 */
@@ -141,6 +149,24 @@ static unsigned long long cache_size;
141 * How much space have we currently reserved? 149 * How much space have we currently reserved?
142 */ 150 */
143static unsigned long long reserved; 151static unsigned long long reserved;
152
153/**
154 * How much data are we currently storing
155 * in the database?
156 */
157static unsigned long long payload;
158
159/**
160 * Number of updates that were made to the
161 * payload value since we last synchronized
162 * it with the statistics service.
163 */
164static unsigned int lastSync;
165
166/**
167 * Did we get an answer from statistics?
168 */
169static int stats_worked;
144 170
145/** 171/**
146 * Identity of the task that is used to delete 172 * Identity of the task that is used to delete
@@ -165,6 +191,23 @@ static struct GNUNET_STATISTICS_Handle *stats;
165 191
166 192
167/** 193/**
194 * Synchronize our utilization statistics with the
195 * statistics service.
196 */
197static void
198sync_stats ()
199{
200 GNUNET_STATISTICS_set (stats,
201 QUOTA_STAT_NAME,
202 payload,
203 GNUNET_YES);
204 lastSync = 0;
205}
206
207
208
209
210/**
168 * Function called once the transmit operation has 211 * Function called once the transmit operation has
169 * either failed or succeeded. 212 * either failed or succeeded.
170 * 213 *
@@ -242,6 +285,12 @@ static struct TransmitCallbackContext *tcc_tail;
242static int cleaning_done; 285static int cleaning_done;
243 286
244/** 287/**
288 * Handle for pending get request.
289 */
290static struct GNUNET_STATISTICS_GetHandle *stat_get;
291
292
293/**
245 * Task that is used to remove expired entries from 294 * Task that is used to remove expired entries from
246 * the datastore. This task will schedule itself 295 * the datastore. This task will schedule itself
247 * again automatically to always delete all expired 296 * again automatically to always delete all expired
@@ -731,7 +780,7 @@ handle_reserve (void *cls,
731#endif 780#endif
732 amount = GNUNET_ntohll(msg->amount); 781 amount = GNUNET_ntohll(msg->amount);
733 entries = ntohl(msg->entries); 782 entries = ntohl(msg->entries);
734 used = plugin->api->get_size (plugin->api->cls) + reserved; 783 used = payload + reserved;
735 req = amount + ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * entries; 784 req = amount + ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * entries;
736 if (used + req > quota) 785 if (used + req > quota)
737 { 786 {
@@ -931,13 +980,13 @@ execute_put (struct GNUNET_SERVER_Client *client,
931 (GNUNET_SYSERR == ret) ? GNUNET_SYSERR : GNUNET_OK, 980 (GNUNET_SYSERR == ret) ? GNUNET_SYSERR : GNUNET_OK,
932 msg); 981 msg);
933 GNUNET_free_non_null (msg); 982 GNUNET_free_non_null (msg);
934 if (quota - reserved - cache_size < plugin->api->get_size (plugin->api->cls)) 983 if (quota - reserved - cache_size < payload)
935 { 984 {
936 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 985 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
937 _("Need %llu bytes more space (%llu allowed, using %llu)\n"), 986 _("Need %llu bytes more space (%llu allowed, using %llu)\n"),
938 (unsigned long long) size + GNUNET_DATASTORE_ENTRY_OVERHEAD, 987 (unsigned long long) size + GNUNET_DATASTORE_ENTRY_OVERHEAD,
939 (unsigned long long) (quota - reserved - cache_size), 988 (unsigned long long) (quota - reserved - cache_size),
940 (unsigned long long) plugin->api->get_size (plugin->api->cls)); 989 (unsigned long long) payload);
941 manage_space (size + GNUNET_DATASTORE_ENTRY_OVERHEAD); 990 manage_space (size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
942 } 991 }
943} 992}
@@ -1351,6 +1400,78 @@ handle_drop (void *cls,
1351 1400
1352 1401
1353/** 1402/**
1403 * Function called by plugins to notify us about a
1404 * change in their disk utilization.
1405 *
1406 * @param cls closure (NULL)
1407 * @param delta change in disk utilization,
1408 * 0 for "reset to empty"
1409 */
1410static void
1411disk_utilization_change_cb (void *cls,
1412 int delta)
1413{
1414 if ( (delta < 0) &&
1415 (payload < -delta) )
1416 {
1417 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1418 _("Datastore payload inaccurate (%lld < %lld). Trying to fix.\n"),
1419 (long long) payload,
1420 (long long) -delta);
1421 payload = plugin->api->get_size (plugin->api->cls);
1422 sync_stats ();
1423 return;
1424 }
1425 payload += delta;
1426 lastSync++;
1427 if (lastSync >= MAX_STAT_SYNC_LAG)
1428 sync_stats ();
1429}
1430
1431
1432/**
1433 * Callback function to process statistic values.
1434 *
1435 * @param cls closure (struct Plugin*)
1436 * @param subsystem name of subsystem that created the statistic
1437 * @param name the name of the datum
1438 * @param value the current value
1439 * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
1440 * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
1441 */
1442static int
1443process_stat_in (void *cls,
1444 const char *subsystem,
1445 const char *name,
1446 uint64_t value,
1447 int is_persistent)
1448{
1449 GNUNET_assert (stats_worked == GNUNET_NO);
1450 stats_worked = GNUNET_YES;
1451 payload += value;
1452#if DEBUG_SQLITE
1453 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1454 "Notification from statistics about existing payload (%llu), new payload is %llu\n",
1455 value,
1456 payload);
1457#endif
1458 return GNUNET_OK;
1459}
1460
1461
1462static void
1463process_stat_done (void *cls,
1464 int success)
1465{
1466 struct DatastorePlugin *plugin = cls;
1467
1468 stat_get = NULL;
1469 if (stats_worked == GNUNET_NO)
1470 payload = plugin->api->get_size (plugin->api->cls);
1471}
1472
1473
1474/**
1354 * Load the datastore plugin. 1475 * Load the datastore plugin.
1355 */ 1476 */
1356static struct DatastorePlugin * 1477static struct DatastorePlugin *
@@ -1373,6 +1494,8 @@ load_plugin ()
1373 ret = GNUNET_malloc (sizeof(struct DatastorePlugin)); 1494 ret = GNUNET_malloc (sizeof(struct DatastorePlugin));
1374 ret->env.cfg = cfg; 1495 ret->env.cfg = cfg;
1375 ret->env.sched = sched; 1496 ret->env.sched = sched;
1497 ret->env.duc = &disk_utilization_change_cb;
1498 ret->env.cls = NULL;
1376 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1499 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1377 _("Loading `%s' datastore plugin\n"), name); 1500 _("Loading `%s' datastore plugin\n"), name);
1378 GNUNET_asprintf (&libname, "libgnunet_plugin_datastore_%s", name); 1501 GNUNET_asprintf (&libname, "libgnunet_plugin_datastore_%s", name);
@@ -1426,6 +1549,13 @@ unload_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1426 GNUNET_CONTAINER_bloomfilter_free (filter); 1549 GNUNET_CONTAINER_bloomfilter_free (filter);
1427 filter = NULL; 1550 filter = NULL;
1428 } 1551 }
1552 if (lastSync > 0)
1553 sync_stats ();
1554 if (stat_get != NULL)
1555 {
1556 GNUNET_STATISTICS_get_cancel (stat_get);
1557 stat_get = NULL;
1558 }
1429 if (stats != NULL) 1559 if (stats != NULL)
1430 { 1560 {
1431 GNUNET_STATISTICS_destroy (stats, GNUNET_YES); 1561 GNUNET_STATISTICS_destroy (stats, GNUNET_YES);
@@ -1614,6 +1744,13 @@ run (void *cls,
1614 } 1744 }
1615 return; 1745 return;
1616 } 1746 }
1747 stat_get = GNUNET_STATISTICS_get (stats,
1748 "datastore",
1749 QUOTA_STAT_NAME,
1750 GNUNET_TIME_UNIT_SECONDS,
1751 &process_stat_done,
1752 &process_stat_in,
1753 plugin);
1617 GNUNET_SERVER_disconnect_notify (server, &cleanup_reservations, NULL); 1754 GNUNET_SERVER_disconnect_notify (server, &cleanup_reservations, NULL);
1618 GNUNET_SERVER_add_handlers (server, handlers); 1755 GNUNET_SERVER_add_handlers (server, handlers);
1619 expired_kill_task 1756 expired_kill_task