GNUnet  0.10.x
gnunet-statistics.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001, 2002, 2004-2007, 2009, 2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
20 
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
30 #include "statistics.h"
31 
32 
36 static int ret;
37 
41 static char *subsystem;
42 
46 static char *path_testbed;
47 
51 static char *name;
52 
56 static int persistent;
57 
61 static int watch;
62 
66 static int quiet;
67 
71 static char *csv_separator;
72 
76 static char *remote_host;
77 
81 static unsigned long long remote_port;
82 
86 static unsigned long long set_val;
87 
91 static int set_value;
92 
96 static struct Node
97 {
101  unsigned index_node;
102 
107 
112 
121 } * nodes;
122 
126 static unsigned num_nodes;
127 
131 struct ValueSet
132 {
136  char *subsystem;
137 
141  char *name;
142 
146  uint64_t *values;
147 
152 };
153 
158 
162 static int num_nodes_ready;
163 
168 
179 static struct ValueSet *
181  const char *name,
182  unsigned num_values,
183  int is_persistent)
184 {
185  struct ValueSet *value_set;
186 
187  value_set = GNUNET_new (struct ValueSet);
188  value_set->subsystem = GNUNET_strdup (subsystem);
189  value_set->name = GNUNET_strdup (name);
190  value_set->values = GNUNET_new_array (num_values, uint64_t);
191  value_set->is_persistent = persistent;
192  return value_set;
193 }
194 
207 static int
208 printer (void *cls, const struct GNUNET_HashCode *key, void *value)
209 {
211  const char *now_str;
212  struct ValueSet *value_set = value;
213 
214  if (quiet == GNUNET_NO)
215  {
216  if (GNUNET_YES == watch)
217  {
219  FPRINTF (stdout,
220  "%24s%s %s%s%12s%s %s%50s%s%s ",
221  now_str,
223  value_set->is_persistent ? "!" : " ",
225  value_set->subsystem,
227  (0 == strlen (csv_separator) ? "" : "\""), /* quotes if csv */
228  _ (value_set->name),
229  (0 == strlen (csv_separator) ? "" : "\""), /* quotes if csv */
230  (0 == strlen (csv_separator) ? ":" : csv_separator));
231  }
232  else
233  {
234  FPRINTF (stdout,
235  "%s%s%12s%s %s%50s%s%s ",
236  value_set->is_persistent ? "!" : " ",
238  value_set->subsystem,
240  (0 == strlen (csv_separator) ? "" : "\""), /* quotes if csv */
241  _ (value_set->name),
242  (0 == strlen (csv_separator) ? "" : "\""), /* quotes if csv */
243  (0 == strlen (csv_separator) ? ":" : csv_separator));
244  }
245  }
246  for (unsigned i = 0; i < num_nodes; i++)
247  {
248  FPRINTF (stdout,
249  "%16llu%s",
250  (unsigned long long) value_set->values[i],
251  csv_separator);
252  }
253  FPRINTF (stdout, "\n");
254  GNUNET_free (value_set->subsystem);
255  GNUNET_free (value_set->name);
256  GNUNET_free (value_set->values);
257  GNUNET_free (value_set);
258  return GNUNET_YES;
259 }
260 
271 static int
272 printer_watch (void *cls,
273  const char *subsystem,
274  const char *name,
275  uint64_t value,
276  int is_persistent)
277 {
279  const char *now_str;
280 
281  if (quiet == GNUNET_NO)
282  {
283  if (GNUNET_YES == watch)
284  {
286  FPRINTF (stdout,
287  "%24s%s %s%s%12s%s %s%50s%s%s %16llu\n",
288  now_str,
290  is_persistent ? "!" : " ",
292  subsystem,
294  (0 == strlen (csv_separator) ? "" : "\""), /* quotes if csv */
295  _ (name),
296  (0 == strlen (csv_separator) ? "" : "\""), /* quotes if csv */
297  (0 == strlen (csv_separator) ? ":" : csv_separator),
298  (unsigned long long) value);
299  }
300  else
301  {
302  FPRINTF (stdout,
303  "%s%s%12s%s %s%50s%s%s %16llu\n",
304  is_persistent ? "!" : " ",
306  subsystem,
308  (0 == strlen (csv_separator) ? "" : "\""), /* quotes if csv */
309  _ (name),
310  (0 == strlen (csv_separator) ? "" : "\""), /* quotes if csv */
311  (0 == strlen (csv_separator) ? ":" : csv_separator),
312  (unsigned long long) value);
313  }
314  }
315  else
316  FPRINTF (stdout, "%llu\n", (unsigned long long) value);
317 
318  return GNUNET_OK;
319 }
320 
328 static void
329 clean_node (void *cls)
330 {
331  const unsigned index_node = *(unsigned *) cls;
332  struct GNUNET_STATISTICS_Handle *h;
334 
335  if ((NULL != path_testbed) && /* were issued with -t <testbed-path> option */
336  (NULL != nodes[index_node].conf))
337  {
339  nodes[index_node].conf = NULL;
340  }
341 
342  h = nodes[index_node].handle;
343  gh = nodes[index_node].gh;
344 
345  if (NULL != gh)
346  {
348  gh = NULL;
349  }
350  if (GNUNET_YES == watch)
351  {
352  GNUNET_assert (
353  GNUNET_OK ==
355  subsystem,
356  name,
357  &printer_watch,
358  &nodes[index_node].index_node));
359  }
360 
361  if (NULL != h)
362  {
364  h = NULL;
365  }
366 
369  {
372  }
373 }
374 
380 static void
382 {
385 }
386 
395 static void
396 continuation_print (void *cls, int success)
397 {
398  const unsigned index_node = *(unsigned *) cls;
399 
400  nodes[index_node].gh = NULL;
401  if (GNUNET_OK != success)
402  {
403  if (NULL == remote_host)
404  FPRINTF (stderr, "%s", _ ("Failed to obtain statistics.\n"));
405  else
406  FPRINTF (stderr,
407  _ ("Failed to obtain statistics from host `%s:%llu'\n"),
408  remote_host,
409  remote_port);
410  ret = 1;
411  }
412  if (NULL != nodes[index_node].shutdown_task)
413  {
414  GNUNET_SCHEDULER_cancel (nodes[index_node].shutdown_task);
416  }
417  GNUNET_SCHEDULER_add_now (clean_node, &nodes[index_node].index_node);
418  num_nodes_ready++;
419  if (num_nodes_ready == num_nodes)
420  {
422  }
423 }
424 
432 static void
433 cleanup (void *cls, int success)
434 {
435  for (unsigned i = 0; i < num_nodes; i++)
436  {
437  nodes[i].gh = NULL;
438  }
439  if (GNUNET_OK != success)
440  {
441  if (NULL == remote_host)
442  FPRINTF (stderr, "%s", _ ("Failed to obtain statistics.\n"));
443  else
444  FPRINTF (stderr,
445  _ ("Failed to obtain statistics from host `%s:%llu'\n"),
446  remote_host,
447  remote_port);
448  ret = 1;
449  }
451 }
452 
465 static int
466 collector (void *cls,
467  const char *subsystem,
468  const char *name,
469  uint64_t value,
470  int is_persistent)
471 {
472  const unsigned index_node = *(unsigned *) cls;
473  struct GNUNET_HashCode *key;
474  struct GNUNET_HashCode hc;
475  char *subsys_name;
476  unsigned len_subsys_name;
477  struct ValueSet *value_set;
478 
479  len_subsys_name = strlen (subsystem) + 3 + strlen (name) + 1;
480  subsys_name = GNUNET_malloc (len_subsys_name);
481  SPRINTF (subsys_name, "%s---%s", subsystem, name);
482  key = &hc;
483  GNUNET_CRYPTO_hash (subsys_name, len_subsys_name, key);
484  GNUNET_free (subsys_name);
486  {
487  value_set = GNUNET_CONTAINER_multihashmap_get (values, key);
488  }
489  else
490  {
491  value_set = new_value_set (subsystem, name, num_nodes, is_persistent);
492  }
493  value_set->values[index_node] = value;
496  values,
497  key,
498  value_set,
500  return GNUNET_OK;
501 }
502 
508 static void
509 main_task (void *cls)
510 {
511  unsigned index_node = *(unsigned *) cls;
513 
514  if (set_value)
515  {
516  if (NULL == subsystem)
517  {
518  FPRINTF (stderr, "%s", _ ("Missing argument: subsystem \n"));
519  ret = 1;
520  return;
521  }
522  if (NULL == name)
523  {
524  FPRINTF (stderr, "%s", _ ("Missing argument: name\n"));
525  ret = 1;
526  return;
527  }
529  if (NULL == nodes[index_node].handle)
530  {
531  ret = 1;
532  return;
533  }
534  GNUNET_STATISTICS_set (nodes[index_node].handle,
535  name,
536  (uint64_t) set_val,
537  persistent);
538  GNUNET_STATISTICS_destroy (nodes[index_node].handle, GNUNET_YES);
539  nodes[index_node].handle = NULL;
540  return;
541  }
542  if (NULL == (nodes[index_node].handle =
543  GNUNET_STATISTICS_create ("gnunet-statistics", cfg)))
544  {
545  ret = 1;
546  return;
547  }
548  if (GNUNET_NO == watch)
549  {
550  if (NULL == (nodes[index_node].gh =
551  GNUNET_STATISTICS_get (nodes[index_node].handle,
552  subsystem,
553  name,
555  &collector,
556  &nodes[index_node].index_node)))
557  cleanup (nodes[index_node].handle, GNUNET_SYSERR);
558  }
559  else
560  {
561  if ((NULL == subsystem) || (NULL == name))
562  {
563  printf (_ ("No subsystem or name given\n"));
565  nodes[index_node].handle = NULL;
566  ret = 1;
567  return;
568  }
569  if (GNUNET_OK != GNUNET_STATISTICS_watch (nodes[index_node].handle,
570  subsystem,
571  name,
572  &printer_watch,
573  &nodes[index_node].index_node))
574  {
575  fprintf (stderr, _ ("Failed to initialize watch routine\n"));
577  GNUNET_SCHEDULER_add_now (&clean_node, &nodes[index_node].index_node);
578  return;
579  }
580  }
582  GNUNET_SCHEDULER_add_shutdown (&clean_node, &nodes[index_node].index_node);
583 }
584 
596 static int
597 iter_check_config (void *cls, const char *filename)
598 {
599  if (0 == strncmp (GNUNET_STRINGS_get_short_name (filename), "config", 6))
600  {
601  /* Found the config - stop iteration successfully */
604  nodes[num_nodes - 1].index_node = num_nodes - 1;
605  if (GNUNET_OK !=
607  {
608  FPRINTF (stderr, "Failed loading config `%s'\n", filename);
609  return GNUNET_SYSERR;
610  }
611  return GNUNET_NO;
612  }
613  else
614  {
615  /* Continue iteration */
616  return GNUNET_OK;
617  }
618 }
619 
633 static int
634 iter_testbed_path (void *cls, const char *filename)
635 {
636  unsigned index_node;
637 
638  GNUNET_assert (NULL != filename);
639  if (1 == SSCANF (GNUNET_STRINGS_get_short_name (filename), "%u", &index_node))
640  {
641  if (-1 == GNUNET_DISK_directory_scan (filename, iter_check_config, NULL))
642  {
643  /* This is probably no directory for a testbed node
644  * Go on with iteration */
645  return GNUNET_OK;
646  }
647  return GNUNET_OK;
648  }
649  return GNUNET_OK;
650 }
651 
659 static int
661 {
662  int num_dir_entries;
663 
664  num_dir_entries =
665  GNUNET_DISK_directory_scan (path_testbed, iter_testbed_path, NULL);
666  if (-1 == num_dir_entries)
667  {
668  FPRINTF (stderr, "Failure during scanning directory `%s'\n", path_testbed);
669  return -1;
670  }
671  return 0;
672 }
673 
682 static void
683 run (void *cls,
684  char *const *args,
685  const char *cfgfile,
686  const struct GNUNET_CONFIGURATION_Handle *cfg)
687 {
688  struct GNUNET_CONFIGURATION_Handle *c;
689 
690  c = (struct GNUNET_CONFIGURATION_Handle *) cfg;
692  if (NULL == csv_separator)
693  csv_separator = "";
694  if (NULL != args[0])
695  {
696  if (1 != SSCANF (args[0], "%llu", &set_val))
697  {
698  FPRINTF (stderr, _ ("Invalid argument `%s'\n"), args[0]);
699  ret = 1;
700  return;
701  }
703  }
704  if (NULL != remote_host)
705  {
706  if (0 == remote_port)
707  {
709  "statistics",
710  "PORT",
711  &remote_port))
712  {
713  FPRINTF (stderr,
714  _ ("A port is required to connect to host `%s'\n"),
715  remote_host);
716  return;
717  }
718  }
719  else if (65535 <= remote_port)
720  {
721  FPRINTF (stderr,
722  _ (
723  "A port has to be between 1 and 65535 to connect to host `%s'\n"),
724  remote_host);
725  return;
726  }
727 
728  /* Manipulate configuration */
729  GNUNET_CONFIGURATION_set_value_string (c, "statistics", "UNIXPATH", "");
731  "statistics",
732  "HOSTNAME",
733  remote_host);
735  "statistics",
736  "PORT",
737  remote_port);
738  }
739  if (NULL == path_testbed)
740  {
743  nodes[0].index_node = 0;
744  nodes[0].conf = c;
746  }
747  else
748  {
749  if (GNUNET_YES == watch)
750  {
751  printf (
752  _ ("Not able to watch testbed nodes (yet - feel free to implement)\n"));
753  ret = 1;
754  return;
755  }
758  {
759  return;
760  }
761  /* For each config/node collect statistics */
762  for (unsigned i = 0; i < num_nodes; i++)
763  {
765  }
766  }
767 }
768 
769 
777 int
778 main (int argc, char *const *argv)
779 {
780  struct GNUNET_GETOPT_CommandLineOption options[] =
782  'n',
783  "name",
784  "NAME",
785  gettext_noop ("limit output to statistics for the given NAME"),
786  &name),
787 
789  "persistent",
790  gettext_noop (
791  "make the value being set persistent"),
792  &persistent),
793 
795  "subsystem",
796  "SUBSYSTEM",
797  gettext_noop (
798  "limit output to the given SUBSYSTEM"),
799  &subsystem),
800 
802  "csv-separator",
803  "CSV_SEPARATOR",
804  gettext_noop ("use as csv separator"),
805  &csv_separator),
806 
808  't',
809  "testbed",
810  "TESTBED",
811  gettext_noop ("path to the folder containing the testbed data"),
812  &path_testbed),
813 
815  "quiet",
816  gettext_noop (
817  "just print the statistics value"),
818  &quiet),
819 
821  "watch",
822  gettext_noop ("watch value continuously"),
823  &watch),
824 
826  "remote",
827  "REMOTE",
828  gettext_noop ("connect to remote host"),
829  &remote_host),
830 
832  "port",
833  "PORT",
834  gettext_noop ("port for remote host"),
835  &remote_port),
836 
838  remote_port = 0;
839  remote_host = NULL;
840  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
841  return 2;
842 
843  ret = (GNUNET_OK ==
844  GNUNET_PROGRAM_run (argc,
845  argv,
846  "gnunet-statistics [options [value]]",
847  gettext_noop (
848  "Print statistics about GNUnet operations."),
849  options,
850  &run,
851  NULL))
852  ? ret
853  : 1;
855  GNUNET_free ((void *) argv);
856  return ret;
857 }
858 
859 /* end of gnunet-statistics.c */
char * subsystem
Subsystem of the valueset.
static char * remote_host
Remote host.
static unsigned long long remote_port
Remote host&#39;s port.
static char * subsystem
Set to subsystem that we&#39;re going to get stats for (or NULL for all).
Set of values for a combination of subsystem and name.
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
static int collector(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Iterate over statistics values and store them in values.
static struct GNUNET_CONTAINER_MultiHashMap * values
Collection of all values (represented with ValueSet).
#define FPRINTF
Definition: plibc.h:683
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1521
static char * csv_separator
Separator string for csv.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_STATISTICS_get_cancel(struct GNUNET_STATISTICS_GetHandle *gh)
Cancel a GNUNET_STATISTICS_get request.
static int iter_check_config(void *cls, const char *filename)
Iter over content of a node&#39;s directory to check for existence of a config file.
Representation of all (testbed) nodes.
int is_persistent
Persistence of the values.
void GNUNET_CONFIGURATION_set_value_number(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long number)
Set a configuration value that should be a number.
struct GNUNET_STATISTICS_GetHandle * gh
Handle for pending GET operation.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_HashMapIterator it, void *it_cls)
Iterate over all entries in the map.
Linked list of things we still need to do.
#define GNUNET_NO
Definition: gnunet_common.h:81
static unsigned long long set_val
Value to set.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
static char * path_testbed
The path of the testbed data.
static void print_finish(void *cls)
Print and shutdown.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:1233
static unsigned int num_values
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run by the scheduler.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
Handle for the service.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
Internal representation of the hash map.
uint64_t * values
The values.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
static char * name
Set to the specific stat value that we are after (or NULL for all).
int GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
static int ret
Final status code.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
static void continuation_print(void *cls, int success)
Called once all statistic values are available.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_filename(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a filename (automatically path expanded).
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
static char * value
Value of the record to add/remove.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
int main(int argc, char *const *argv)
The main function to obtain statistics in GNUnet.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
static char * filename
struct GNUNET_CONFIGURATION_Handle * conf
Configuration handle for this node.
void GNUNET_CONFIGURATION_set_value_string(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Set a configuration value that should be a string.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
const char * GNUNET_STRINGS_get_short_name(const char *filename)
"man basename" Returns a pointer to a part of filename (allocates nothing)!
Definition: strings.c:845
There must only be one value per key; storing a value should fail if a value under the same key alrea...
static unsigned num_nodes
Number of configurations of all (testbed) nodes.
struct GNUNET_HashCode key
The key used in the DHT.
static int watch
Watch value continuously.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static struct Node * nodes
static void cleanup(void *cls, int success)
Function called last by the statistics code.
static int set_value
Set operation.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_ulong(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned long long *val)
Allow user to specify an unsigned long long.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
unsigned index_node
Index of the node in this array.
#define SPRINTF
Definition: plibc.h:689
static struct ValueSet * new_value_set(const char *subsystem, const char *name, unsigned num_values, int is_persistent)
Create a new ValueSet.
static int persistent
Make the value that is being set persistent.
static int printer(void *cls, const struct GNUNET_HashCode *key, void *value)
Print the (collected) values.
struct GNUNET_SCHEDULER_Task * shutdown_task
Identifier for shutdown task for this node.
int GNUNET_STATISTICS_watch_cancel(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Iterator proc, void *proc_cls)
Stop watching statistics from the peer.
struct GNUNET_STATISTICS_GetHandle * GNUNET_STATISTICS_get(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Callback cont, GNUNET_STATISTICS_Iterator proc, void *cls)
Get statistic from the peer.
#define SSCANF
Definition: plibc.h:691
configuration data
Definition: configuration.c:85
static int iter_testbed_path(void *cls, const char *filename)
Iterates over filenames in testbed directory.
int GNUNET_STATISTICS_watch(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Iterator proc, void *proc_cls)
Watch statistics from the peer (be notified whenever they change).
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
void * cls
Closure for proc and cont.
Entry in list of pending tasks.
Definition: scheduler.c:134
static int num_nodes_ready
Number of nodes that have their values ready.
static void clean_node(void *cls)
Clean all data structures related to given node.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:361
static int num_nodes_ready_shutdown
Number of nodes that have their values ready.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_STATISTICS_Handle * handle
Statistics handle nodes.
static void main_task(void *cls)
Main task that does the actual work.
static int quiet
Quiet mode.
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:792
static int discover_testbed_nodes(const char *path_testbed)
Count the number of nodes running in the testbed.
char * name
Name of the valueset.
#define GNUNET_malloc(size)
Wrapper around malloc.
static int printer_watch(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Callback function to process statistic values.
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965