gnunet-fs-profiler.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2012 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file fs/gnunet-fs-profiler.c
  18. * @brief tool to benchmark/profile file-sharing
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include "gnunet_util_lib.h"
  23. #include "gnunet_testbed_service.h"
  24. /**
  25. * Final status code.
  26. */
  27. static int ret;
  28. /**
  29. * Data file with the hosts for the testbed.
  30. */
  31. static char *host_filename;
  32. /**
  33. * Number of peers to run in the experiment.
  34. */
  35. static unsigned int num_peers;
  36. /**
  37. * After how long do we abort the test?
  38. */
  39. static struct GNUNET_TIME_Relative timeout;
  40. /**
  41. * Handle to the task run during termination.
  42. */
  43. static struct GNUNET_SCHEDULER_Task *terminate_taskid;
  44. /**
  45. * Function called after we've collected the statistics.
  46. *
  47. * @param cls NULL
  48. * @param op the operation that has been finished
  49. * @param emsg error message in case the operation has failed; will be NULL if
  50. * operation has executed successfully.
  51. */
  52. static void
  53. shutdown_task (void *cls,
  54. struct GNUNET_TESTBED_Operation *op,
  55. const char *emsg)
  56. {
  57. if (NULL != emsg)
  58. fprintf (stderr,
  59. "Error collecting statistics: %s\n",
  60. emsg);
  61. GNUNET_SCHEDULER_shutdown ();
  62. }
  63. /**
  64. * Callback function to process statistic values from all peers.
  65. * Prints them out.
  66. *
  67. * @param cls closure
  68. * @param peer the peer the statistic belong to
  69. * @param subsystem name of subsystem that created the statistic
  70. * @param name the name of the datum
  71. * @param value the current value
  72. * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
  73. * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
  74. */
  75. static int
  76. process_stats (void *cls,
  77. const struct GNUNET_TESTBED_Peer *peer,
  78. const char *subsystem,
  79. const char *name,
  80. uint64_t value,
  81. int is_persistent)
  82. {
  83. fprintf (stdout,
  84. "%p-%s: %s = %llu\n",
  85. peer,
  86. subsystem,
  87. name,
  88. (unsigned long long) value);
  89. return GNUNET_OK;
  90. }
  91. /**
  92. * Task run on shutdown to terminate. Triggers printing out
  93. * all statistics.
  94. *
  95. * @param cls NULL
  96. */
  97. static void
  98. terminate_task (void *cls)
  99. {
  100. if (NULL != terminate_taskid)
  101. {
  102. GNUNET_SCHEDULER_cancel (terminate_taskid);
  103. terminate_taskid = NULL;
  104. }
  105. GNUNET_TESTBED_get_statistics (0, NULL,
  106. NULL, NULL,
  107. &process_stats,
  108. &shutdown_task,
  109. NULL);
  110. }
  111. /**
  112. * Task run on timeout to terminate. Triggers printing out
  113. * all statistics.
  114. *
  115. * @param cls NULL
  116. */
  117. static void
  118. timeout_task (void *cls)
  119. {
  120. terminate_taskid = NULL;
  121. GNUNET_SCHEDULER_shutdown ();
  122. }
  123. /**
  124. * Signature of a main function for a testcase.
  125. *
  126. * @param cls closure
  127. * @param h the run handle
  128. * @param num_peers number of peers in 'peers'
  129. * @param peers handle to peers run in the testbed
  130. * @param links_succeeded the number of overlay link connection attempts that
  131. * succeeded
  132. * @param links_failed the number of overlay link connection attempts that
  133. * failed
  134. */
  135. static void
  136. test_master (void *cls,
  137. struct GNUNET_TESTBED_RunHandle *h,
  138. unsigned int num_peers,
  139. struct GNUNET_TESTBED_Peer **peers,
  140. unsigned int links_succeeded,
  141. unsigned int links_failed)
  142. {
  143. // const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
  144. // FIXME: enable clients to signal 'completion' before timeout;
  145. // in that case, run the 'terminate_task' "immediately"
  146. if (0 != timeout.rel_value_us)
  147. terminate_taskid = GNUNET_SCHEDULER_add_delayed (timeout,
  148. &timeout_task,
  149. NULL);
  150. GNUNET_SCHEDULER_add_shutdown (&terminate_task,
  151. NULL);
  152. }
  153. /**
  154. * Main function that will be run by the scheduler.
  155. *
  156. * @param cls closure
  157. * @param args remaining command-line arguments
  158. * @param cfgfile name of the configuration file used (for saving, can be NULL!)
  159. * @param cfg configuration
  160. */
  161. static void
  162. run (void *cls, char *const *args, const char *cfgfile,
  163. const struct GNUNET_CONFIGURATION_Handle *cfg)
  164. {
  165. GNUNET_TESTBED_run (host_filename,
  166. cfg,
  167. num_peers,
  168. 0, NULL, NULL,
  169. &test_master, (void *) cfg);
  170. }
  171. /**
  172. * Program to run a file-sharing testbed.
  173. *
  174. * @param argc number of arguments from the command line
  175. * @param argv command line arguments
  176. * @return 0 ok, 1 on error
  177. */
  178. int
  179. main (int argc, char *const *argv)
  180. {
  181. struct GNUNET_GETOPT_CommandLineOption options[] = {
  182. GNUNET_GETOPT_option_uint ('n',
  183. "num-peers",
  184. "COUNT",
  185. gettext_noop (
  186. "run the experiment with COUNT peers"),
  187. &num_peers),
  188. GNUNET_GETOPT_option_string ('H',
  189. "hosts",
  190. "HOSTFILE",
  191. gettext_noop (
  192. "specifies name of a file with the HOSTS the testbed should use"),
  193. &host_filename),
  194. GNUNET_GETOPT_option_relative_time ('t',
  195. "timeout",
  196. "DELAY",
  197. gettext_noop (
  198. "automatically terminate experiment after DELAY"),
  199. &timeout),
  200. GNUNET_GETOPT_OPTION_END
  201. };
  202. if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
  203. return 2;
  204. ret = (GNUNET_OK ==
  205. GNUNET_PROGRAM_run (argc, argv, "gnunet-fs-profiler",
  206. gettext_noop (
  207. "run a testbed to measure file-sharing performance"),
  208. options, &run,
  209. NULL)) ? ret : 1;
  210. GNUNET_free ((void*) argv);
  211. return ret;
  212. }
  213. /* end of gnunet-fs-profiler.c */