aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-06-29 12:52:14 +0000
committerNathan S. Evans <evans@in.tum.de>2010-06-29 12:52:14 +0000
commitb32f77fcf454a8f304486ba25bd1bc8b5f500cc5 (patch)
tree085d39d2306575586aaed3a8093c07d95a906809 /src
parentff12c387ccbf650427512dcb18cfbff0934c4edf (diff)
downloadgnunet-b32f77fcf454a8f304486ba25bd1bc8b5f500cc5.tar.gz
gnunet-b32f77fcf454a8f304486ba25bd1bc8b5f500cc5.zip
change to limit number of peers actually starting concurrently so as not to exceed max file descriptor limit
Diffstat (limited to 'src')
-rw-r--r--src/testing/testing.c2
-rw-r--r--src/testing/testing_group.c241
2 files changed, 148 insertions, 95 deletions
diff --git a/src/testing/testing.c b/src/testing/testing.c
index 61c97975c..0b70767f1 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -704,7 +704,7 @@ GNUNET_TESTING_daemon_start_stopped (struct GNUNET_TESTING_Daemon *daemon,
704 * generated for this peer, but it hasn't yet been started 704 * generated for this peer, but it hasn't yet been started
705 * (NULL to start immediately, otherwise waits on GNUNET_TESTING_daemon_continue_start) 705 * (NULL to start immediately, otherwise waits on GNUNET_TESTING_daemon_continue_start)
706 * @param hostkey_cls closure for hostkey callback 706 * @param hostkey_cls closure for hostkey callback
707 * @param cb function to call with the result 707 * @param cb function to call once peer is up, or failed to start
708 * @param cb_cls closure for cb 708 * @param cb_cls closure for cb
709 * @return handle to the daemon (actual start will be completed asynchronously) 709 * @return handle to the daemon (actual start will be completed asynchronously)
710 */ 710 */
diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c
index 6770cf446..c76f3b54d 100644
--- a/src/testing/testing_group.c
+++ b/src/testing/testing_group.c
@@ -52,6 +52,8 @@
52 52
53#define MAX_CONCURRENT_HOSTKEYS 16 53#define MAX_CONCURRENT_HOSTKEYS 16
54 54
55#define MAX_CONCURRENT_STARTING 50
56
55#define CONNECT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) 57#define CONNECT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
56 58
57#define CONNECT_ATTEMPTS 8 59#define CONNECT_ATTEMPTS 8
@@ -190,6 +192,44 @@ struct PeerConnection
190}; 192};
191#endif 193#endif
192 194
195struct InternalStartContext
196{
197 /**
198 * Pointer to peerdata
199 */
200 struct PeerData *peer;
201
202 /**
203 * Timeout for peer startup
204 */
205 struct GNUNET_TIME_Relative timeout;
206
207 /**
208 * Client callback for hostkey notification
209 */
210 GNUNET_TESTING_NotifyHostkeyCreated hostkey_callback;
211
212 /**
213 * Closure for hostkey_callback
214 */
215 void *hostkey_cls;
216
217 /**
218 * Client callback for peer start notification
219 */
220 GNUNET_TESTING_NotifyDaemonRunning start_cb;
221
222 /**
223 * Closure for cb
224 */
225 void *start_cb_cls;
226
227 /**
228 * Hostname, where to start the peer
229 */
230 const char *hostname;
231};
232
193/** 233/**
194 * Data we keep per peer. 234 * Data we keep per peer.
195 */ 235 */
@@ -214,10 +254,6 @@ struct PeerData
214 struct GNUNET_TESTING_PeerGroup *pg; 254 struct GNUNET_TESTING_PeerGroup *pg;
215 255
216 /** 256 /**
217 * Linked list of peer connections (pointers)
218 */
219 //struct PeerConnection *connected_peers;
220 /**
221 * Hash map of allowed peer connections (F2F created topology) 257 * Hash map of allowed peer connections (F2F created topology)
222 */ 258 */
223 struct GNUNET_CONTAINER_MultiHashMap *allowed_peers; 259 struct GNUNET_CONTAINER_MultiHashMap *allowed_peers;
@@ -242,6 +278,12 @@ struct PeerData
242 * creating any topology so the count is valid once finished. 278 * creating any topology so the count is valid once finished.
243 */ 279 */
244 int num_connections; 280 int num_connections;
281
282 /**
283 * Context to keep track of peers being started, to
284 * stagger hostkey generation and peer startup.
285 */
286 struct InternalStartContext internal_context;
245}; 287};
246 288
247 289
@@ -281,12 +323,12 @@ struct GNUNET_TESTING_PeerGroup
281 /** 323 /**
282 * Function to call on each started daemon. 324 * Function to call on each started daemon.
283 */ 325 */
284 GNUNET_TESTING_NotifyDaemonRunning cb; 326 //GNUNET_TESTING_NotifyDaemonRunning cb;
285 327
286 /** 328 /**
287 * Closure for cb. 329 * Closure for cb.
288 */ 330 */
289 void *cb_cls; 331 //void *cb_cls;
290 332
291 /* 333 /*
292 * Function to call on each topology connection created 334 * Function to call on each topology connection created
@@ -325,6 +367,24 @@ struct GNUNET_TESTING_PeerGroup
325 unsigned int starting; 367 unsigned int starting;
326}; 368};
327 369
370struct UpdateContext
371{
372 struct GNUNET_CONFIGURATION_Handle *ret;
373 const char *hostname;
374 unsigned int nport;
375 unsigned int upnum;
376};
377
378
379struct ConnectContext
380{
381 struct GNUNET_TESTING_Daemon *first;
382
383 struct GNUNET_TESTING_Daemon *second;
384
385 struct GNUNET_TESTING_PeerGroup *pg;
386};
387
328/** 388/**
329 * Convert unique ID to hash code. 389 * Convert unique ID to hash code.
330 * 390 *
@@ -351,24 +411,6 @@ uid_from_hash (const GNUNET_HashCode *hash, uint32_t *uid)
351 memcpy (uid, hash, sizeof(uint32_t)); 411 memcpy (uid, hash, sizeof(uint32_t));
352} 412}
353 413
354struct UpdateContext
355{
356 struct GNUNET_CONFIGURATION_Handle *ret;
357 const char *hostname;
358 unsigned int nport;
359 unsigned int upnum;
360};
361
362
363struct ConnectContext
364{
365 struct GNUNET_TESTING_Daemon *first;
366
367 struct GNUNET_TESTING_Daemon *second;
368
369 struct GNUNET_TESTING_PeerGroup *pg;
370};
371
372/** 414/**
373 * Number of connects we are waiting on, allows us to rate limit 415 * Number of connects we are waiting on, allows us to rate limit
374 * connect attempts. 416 * connect attempts.
@@ -1911,7 +1953,7 @@ static void schedule_connect(void *cls, const struct GNUNET_SCHEDULER_TaskContex
1911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1953 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1912 _("Delaying connect, we have too many outstanding connections!\n")); 1954 _("Delaying connect, we have too many outstanding connections!\n"));
1913#endif 1955#endif
1914 GNUNET_SCHEDULER_add_delayed(connect_context->pg->sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3), &schedule_connect, connect_context); 1956 GNUNET_SCHEDULER_add_delayed(connect_context->pg->sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 100), &schedule_connect, connect_context);
1915 } 1957 }
1916 else 1958 else
1917 { 1959 {
@@ -2792,55 +2834,65 @@ GNUNET_TESTING_connect_topology (struct GNUNET_TESTING_PeerGroup *pg,
2792} 2834}
2793 2835
2794/** 2836/**
2795 * Function which continues a peer group starting up 2837 * Callback that is called whenever a hostkey is generated
2796 * after successfully generating hostkeys for each peer. 2838 * for a peer. Call the real callback and decrement the
2797 * 2839 * starting counter for the peergroup.
2798 * @param pg the peer group to continue starting
2799 * 2840 *
2841 * @param cls closure
2842 * @param id identifier for the daemon, NULL on error
2843 * @param d handle for the daemon
2844 * @param emsg error message (NULL on success)
2800 */ 2845 */
2801void 2846static void internal_hostkey_callback (void *cls,
2802GNUNET_TESTING_daemons_continue_startup(struct GNUNET_TESTING_PeerGroup *pg) 2847 const struct GNUNET_PeerIdentity *id,
2848 struct GNUNET_TESTING_Daemon *d,
2849 const char *emsg)
2803{ 2850{
2804 unsigned int i; 2851 struct InternalStartContext *internal_context = cls;
2805 2852 internal_context->peer->pg->starting--;
2806 for (i = 0; i < pg->total; i++) 2853 internal_context->hostkey_callback(internal_context->hostkey_cls, id, d, emsg);
2807 {
2808 GNUNET_TESTING_daemon_continue_startup(pg->peers[i].daemon);
2809 }
2810} 2854}
2811 2855
2812struct InternalStartContext
2813{
2814 struct PeerData *peer;
2815 struct GNUNET_SCHEDULER_Handle *sched;
2816 const struct GNUNET_CONFIGURATION_Handle *pcfg;
2817 struct GNUNET_TIME_Relative timeout;
2818 GNUNET_TESTING_NotifyHostkeyCreated hostkey_callback;
2819 void *hostkey_cls;
2820 GNUNET_TESTING_NotifyDaemonRunning cb;
2821 void *cb_cls;
2822 const char *hostname;
2823};
2824
2825
2826/** 2856/**
2827 * Prototype of a function that will be called whenever 2857 * Callback that is called whenever a peer has finished starting.
2828 * a daemon was started by the testing library. 2858 * Call the real callback and decrement the starting counter
2859 * for the peergroup.
2829 * 2860 *
2830 * @param cls closure 2861 * @param cls closure
2831 * @param id identifier for the daemon, NULL on error 2862 * @param id identifier for the daemon, NULL on error
2832 * @param d handle for the daemon 2863 * @param d handle for the daemon
2833 * @param emsg error message (NULL on success) 2864 * @param emsg error message (NULL on success)
2834 */ 2865 */
2835static void internal_hostkey_callback (void *cls, 2866static void internal_startup_callback (void *cls,
2836 const struct GNUNET_PeerIdentity *id, 2867 const struct GNUNET_PeerIdentity *id,
2868 const struct GNUNET_CONFIGURATION_Handle *cfg,
2837 struct GNUNET_TESTING_Daemon *d, 2869 struct GNUNET_TESTING_Daemon *d,
2838 const char *emsg) 2870 const char *emsg)
2839{ 2871{
2840 struct InternalStartContext *internal_context = cls; 2872 struct InternalStartContext *internal_context = cls;
2841 internal_context->peer->pg->starting--; 2873 internal_context->peer->pg->starting--;
2842 internal_context->hostkey_callback(internal_context->hostkey_cls, id, d, emsg); 2874 internal_context->start_cb(internal_context->start_cb_cls, id, cfg, d, emsg);
2843 GNUNET_free(internal_context); 2875}
2876
2877static void
2878internal_continue_startup (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
2879{
2880 struct InternalStartContext *internal_context = cls;
2881
2882 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
2883 {
2884 return;
2885 }
2886
2887 if (internal_context->peer->pg->starting < MAX_CONCURRENT_STARTING)
2888 {
2889 internal_context->peer->pg->starting++;
2890 GNUNET_TESTING_daemon_continue_startup (internal_context->peer->daemon);
2891 }
2892 else
2893 {
2894 GNUNET_SCHEDULER_add_delayed(internal_context->peer->pg->sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 100), &internal_continue_startup, internal_context);
2895 }
2844} 2896}
2845 2897
2846static void 2898static void
@@ -2850,30 +2902,49 @@ internal_start (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
2850 2902
2851 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) 2903 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
2852 { 2904 {
2853 GNUNET_free(internal_context);
2854 return; 2905 return;
2855 } 2906 }
2856 2907
2857 if (internal_context->peer->pg->starting < MAX_CONCURRENT_HOSTKEYS) 2908 if (internal_context->peer->pg->starting < MAX_CONCURRENT_HOSTKEYS)
2858 { 2909 {
2859 internal_context->peer->pg->starting++; 2910 internal_context->peer->pg->starting++;
2860 internal_context->peer->daemon = GNUNET_TESTING_daemon_start (internal_context->sched, 2911 internal_context->peer->daemon = GNUNET_TESTING_daemon_start (internal_context->peer->pg->sched,
2861 internal_context->pcfg, 2912 internal_context->peer->cfg,
2862 internal_context->timeout, 2913 internal_context->timeout,
2863 internal_context->hostname, 2914 internal_context->hostname,
2864 &internal_hostkey_callback, 2915 &internal_hostkey_callback,
2865 internal_context, 2916 internal_context,
2866 internal_context->cb, 2917 &internal_startup_callback,
2867 internal_context->cb_cls); 2918 internal_context);
2868 } 2919 }
2869 else 2920 else
2870 { 2921 {
2871 GNUNET_SCHEDULER_add_delayed(internal_context->sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 100), &internal_start, internal_context); 2922 GNUNET_SCHEDULER_add_delayed(internal_context->peer->pg->sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 100), &internal_start, internal_context);
2923 }
2924}
2925
2926/**
2927 * Function which continues a peer group starting up
2928 * after successfully generating hostkeys for each peer.
2929 *
2930 * @param pg the peer group to continue starting
2931 *
2932 */
2933void
2934GNUNET_TESTING_daemons_continue_startup(struct GNUNET_TESTING_PeerGroup *pg)
2935{
2936 unsigned int i;
2937
2938 pg->starting = 0;
2939 for (i = 0; i < pg->total; i++)
2940 {
2941 GNUNET_SCHEDULER_add_now (pg->sched, &internal_continue_startup, &pg->peers[i].internal_context);
2942 //GNUNET_TESTING_daemon_continue_startup(pg->peers[i].daemon);
2872 } 2943 }
2873} 2944}
2874 2945
2875/** 2946/**
2876 * Start count gnunetd processes with the same set of transports and 2947 * Start count gnunet instances with the same set of transports and
2877 * applications. The port numbers (any option called "PORT") will be 2948 * applications. The port numbers (any option called "PORT") will be
2878 * adjusted to ensure that no two peers running on the same system 2949 * adjusted to ensure that no two peers running on the same system
2879 * have the same port(s) in their respective configurations. 2950 * have the same port(s) in their respective configurations.
@@ -2916,7 +2987,6 @@ GNUNET_TESTING_daemons_start (struct GNUNET_SCHEDULER_Handle *sched,
2916 char *baseservicehome; 2987 char *baseservicehome;
2917 char *newservicehome; 2988 char *newservicehome;
2918 char *tmpdir; 2989 char *tmpdir;
2919 struct InternalStartContext *internal_context;
2920 struct GNUNET_CONFIGURATION_Handle *pcfg; 2990 struct GNUNET_CONFIGURATION_Handle *pcfg;
2921 unsigned int off; 2991 unsigned int off;
2922 unsigned int hostcnt; 2992 unsigned int hostcnt;
@@ -2932,8 +3002,6 @@ GNUNET_TESTING_daemons_start (struct GNUNET_SCHEDULER_Handle *sched,
2932 pg = GNUNET_malloc (sizeof (struct GNUNET_TESTING_PeerGroup)); 3002 pg = GNUNET_malloc (sizeof (struct GNUNET_TESTING_PeerGroup));
2933 pg->sched = sched; 3003 pg->sched = sched;
2934 pg->cfg = cfg; 3004 pg->cfg = cfg;
2935 pg->cb = cb;
2936 pg->cb_cls = cb_cls;
2937 pg->notify_connection = connect_callback; 3005 pg->notify_connection = connect_callback;
2938 pg->notify_connection_cls = connect_callback_cls; 3006 pg->notify_connection_cls = connect_callback_cls;
2939 pg->total = total; 3007 pg->total = total;
@@ -3043,31 +3111,16 @@ GNUNET_TESTING_daemons_start (struct GNUNET_SCHEDULER_Handle *sched,
3043 pg->peers[off].connect_peers = GNUNET_CONTAINER_multihashmap_create(total); 3111 pg->peers[off].connect_peers = GNUNET_CONTAINER_multihashmap_create(total);
3044 pg->peers[off].blacklisted_peers = GNUNET_CONTAINER_multihashmap_create(total); 3112 pg->peers[off].blacklisted_peers = GNUNET_CONTAINER_multihashmap_create(total);
3045 pg->peers[off].pg = pg; 3113 pg->peers[off].pg = pg;
3046 internal_context = GNUNET_malloc(sizeof(struct InternalStartContext)); 3114
3047 internal_context->sched = sched; 3115 pg->peers[off].internal_context.peer = &pg->peers[off];
3048 internal_context->peer = &pg->peers[off]; 3116 pg->peers[off].internal_context.timeout = timeout;
3049 internal_context->pcfg = pcfg; 3117 pg->peers[off].internal_context.hostname = hostname;
3050 internal_context->timeout = timeout; 3118 pg->peers[off].internal_context.hostkey_callback = hostkey_callback;
3051 internal_context->hostname = hostname; 3119 pg->peers[off].internal_context.hostkey_cls = hostkey_cls;
3052 internal_context->hostkey_callback = hostkey_callback; 3120 pg->peers[off].internal_context.start_cb = cb;
3053 internal_context->hostkey_cls = hostkey_cls; 3121 pg->peers[off].internal_context.start_cb_cls = cb_cls;
3054 internal_context->cb = cb; 3122
3055 internal_context->cb_cls = cb_cls; 3123 GNUNET_SCHEDULER_add_now (sched, &internal_start, &pg->peers[off].internal_context);
3056
3057 GNUNET_SCHEDULER_add_now (sched, &internal_start, internal_context);
3058
3059 /*
3060 pg->peers[off].daemon = GNUNET_TESTING_daemon_start (sched,
3061 pcfg,
3062 timeout,
3063 hostname,
3064 hostkey_callback,
3065 hostkey_cls,
3066 cb, cb_cls);
3067 if (NULL == pg->peers[off].daemon)
3068 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3069 _("Could not start peer number %u!\n"), off);
3070 */
3071 3124
3072 } 3125 }
3073 return pg; 3126 return pg;
@@ -3513,7 +3566,7 @@ GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg,
3513 shutdown_cb = NULL; 3566 shutdown_cb = NULL;
3514 shutdown_ctx = NULL; 3567 shutdown_ctx = NULL;
3515 3568
3516 if (cb != NULL) 3569 if ((cb != NULL) && (pg->total > 0))
3517 { 3570 {
3518 shutdown_ctx = GNUNET_malloc(sizeof(struct ShutdownContext)); 3571 shutdown_ctx = GNUNET_malloc(sizeof(struct ShutdownContext));
3519 shutdown_ctx->cb = cb; 3572 shutdown_ctx->cb = cb;
@@ -3525,8 +3578,8 @@ GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg,
3525 3578
3526 for (off = 0; off < pg->total; off++) 3579 for (off = 0; off < pg->total; off++)
3527 { 3580 {
3528 if (NULL != pg->peers[off].daemon) 3581 GNUNET_assert(NULL != pg->peers[off].daemon);
3529 GNUNET_TESTING_daemon_stop (pg->peers[off].daemon, timeout, shutdown_cb, shutdown_ctx, GNUNET_YES, GNUNET_NO); 3582 GNUNET_TESTING_daemon_stop (pg->peers[off].daemon, timeout, shutdown_cb, shutdown_ctx, GNUNET_YES, GNUNET_NO);
3530 if (NULL != pg->peers[off].cfg) 3583 if (NULL != pg->peers[off].cfg)
3531 GNUNET_CONFIGURATION_destroy (pg->peers[off].cfg); 3584 GNUNET_CONFIGURATION_destroy (pg->peers[off].cfg);
3532 if (pg->peers[off].allowed_peers != NULL) 3585 if (pg->peers[off].allowed_peers != NULL)