diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-03-08 20:22:09 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-03-08 20:22:09 +0000 |
commit | dea5357ffb0892e6b17ff1fa3eb3c1f94bb454f5 (patch) | |
tree | dd9b43cc9a266f5ed2e80967b8e8600f4e47cc26 | |
parent | b5c6d2a78683e5ba002ca226c2bae280a1877bac (diff) | |
download | gnunet-dea5357ffb0892e6b17ff1fa3eb3c1f94bb454f5.tar.gz gnunet-dea5357ffb0892e6b17ff1fa3eb3c1f94bb454f5.zip |
drq clean up
-rw-r--r-- | src/fs/Makefile.am | 4 | ||||
-rw-r--r-- | src/fs/fs_download.c | 2 | ||||
-rw-r--r-- | src/fs/fs_search.c | 2 | ||||
-rw-r--r-- | src/fs/fs_test_lib_data.conf | 2 | ||||
-rw-r--r-- | src/fs/gnunet-service-fs_drq.c | 335 | ||||
-rw-r--r-- | src/fs/test_fs_test_lib.c | 6 |
6 files changed, 138 insertions, 213 deletions
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index ee476e6e0..48b53ef88 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am | |||
@@ -138,8 +138,8 @@ TESTS = \ | |||
138 | test_fs_start_stop \ | 138 | test_fs_start_stop \ |
139 | test_fs_unindex \ | 139 | test_fs_unindex \ |
140 | test_fs_uri \ | 140 | test_fs_uri \ |
141 | test_fs_test_lib | 141 | test_fs_test_lib \ |
142 | # test_gnunet_service_fs_p2p | 142 | test_gnunet_service_fs_p2p |
143 | # $(check_PROGRAMS) | 143 | # $(check_PROGRAMS) |
144 | 144 | ||
145 | 145 | ||
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 7776f4b8b..1cd10f830 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include "fs.h" | 36 | #include "fs.h" |
37 | #include "fs_tree.h" | 37 | #include "fs_tree.h" |
38 | 38 | ||
39 | #define DEBUG_DOWNLOAD GNUNET_YES | 39 | #define DEBUG_DOWNLOAD GNUNET_NO |
40 | 40 | ||
41 | /** | 41 | /** |
42 | * We're storing the IBLOCKS after the | 42 | * We're storing the IBLOCKS after the |
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index 3229733de..90a28052f 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include "gnunet_protocols.h" | 38 | #include "gnunet_protocols.h" |
39 | #include "fs.h" | 39 | #include "fs.h" |
40 | 40 | ||
41 | #define DEBUG_SEARCH GNUNET_YES | 41 | #define DEBUG_SEARCH GNUNET_NO |
42 | 42 | ||
43 | 43 | ||
44 | 44 | ||
diff --git a/src/fs/fs_test_lib_data.conf b/src/fs/fs_test_lib_data.conf index a901d2be3..70b47a9d8 100644 --- a/src/fs/fs_test_lib_data.conf +++ b/src/fs/fs_test_lib_data.conf | |||
@@ -40,7 +40,7 @@ PORT = 43470 | |||
40 | HOSTNAME = localhost | 40 | HOSTNAME = localhost |
41 | #TOTAL_QUOTA_IN = 3932160 | 41 | #TOTAL_QUOTA_IN = 3932160 |
42 | #TOTAL_QUOTA_OUT = 3932160 | 42 | #TOTAL_QUOTA_OUT = 3932160 |
43 | DEBUG = YES | 43 | #DEBUG = YES |
44 | 44 | ||
45 | [fs] | 45 | [fs] |
46 | PORT = 43471 | 46 | PORT = 43471 |
diff --git a/src/fs/gnunet-service-fs_drq.c b/src/fs/gnunet-service-fs_drq.c index fd5614606..dc9560be6 100644 --- a/src/fs/gnunet-service-fs_drq.c +++ b/src/fs/gnunet-service-fs_drq.c | |||
@@ -55,17 +55,22 @@ struct DatastoreRequestQueue | |||
55 | struct DatastoreRequestQueue *prev; | 55 | struct DatastoreRequestQueue *prev; |
56 | 56 | ||
57 | /** | 57 | /** |
58 | * Function to call (will issue the request). | 58 | * Function to call for each entry. |
59 | */ | ||
60 | GNUNET_DATASTORE_Iterator iter; | ||
61 | |||
62 | /** | ||
63 | * Closure for iter. | ||
59 | */ | 64 | */ |
60 | RequestFunction req; | 65 | void *iter_cls; |
61 | 66 | ||
62 | /** | 67 | /** |
63 | * Closure for req. | 68 | * Key we are doing the 'get' for. |
64 | */ | 69 | */ |
65 | void *req_cls; | 70 | GNUNET_HashCode key; |
66 | 71 | ||
67 | /** | 72 | /** |
68 | * When should this request time-out because we don't care anymore? | 73 | * Timeout for this operation. |
69 | */ | 74 | */ |
70 | struct GNUNET_TIME_Absolute timeout; | 75 | struct GNUNET_TIME_Absolute timeout; |
71 | 76 | ||
@@ -75,6 +80,11 @@ struct DatastoreRequestQueue | |||
75 | GNUNET_SCHEDULER_TaskIdentifier task; | 80 | GNUNET_SCHEDULER_TaskIdentifier task; |
76 | 81 | ||
77 | /** | 82 | /** |
83 | * Datastore entry type we are doing the 'get' for. | ||
84 | */ | ||
85 | uint32_t type; | ||
86 | |||
87 | /** | ||
78 | * Is this request at the head of the queue irrespective of its | 88 | * Is this request at the head of the queue irrespective of its |
79 | * timeout value? | 89 | * timeout value? |
80 | */ | 90 | */ |
@@ -115,21 +125,62 @@ static struct DatastoreRequestQueue *drq_running; | |||
115 | 125 | ||
116 | 126 | ||
117 | /** | 127 | /** |
118 | * A datastore request had to be timed out. | 128 | * Run the next DS request in our queue, we're done with the current |
129 | * one. | ||
130 | */ | ||
131 | static void | ||
132 | next_ds_request (); | ||
133 | |||
134 | |||
135 | /** | ||
136 | * Wrapper for the datastore get operation. Makes sure to trigger the | ||
137 | * next datastore operation in the queue once the operation is | ||
138 | * complete. | ||
119 | * | 139 | * |
120 | * @param cls closure (unused) | 140 | * @param cls our 'struct DatastoreRequestQueue*' |
121 | * @param tc task context, unused | 141 | * @param key key for the content |
142 | * @param size number of bytes in data | ||
143 | * @param data content stored | ||
144 | * @param type type of the content | ||
145 | * @param priority priority of the content | ||
146 | * @param anonymity anonymity-level for the content | ||
147 | * @param expiration expiration time for the content | ||
148 | * @param uid unique identifier for the datum; | ||
149 | * maybe 0 if no unique identifier is available | ||
122 | */ | 150 | */ |
123 | static void | 151 | static void |
124 | timeout_ds_request (void *cls, | 152 | get_iterator (void *cls, |
125 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 153 | const GNUNET_HashCode * key, |
154 | uint32_t size, | ||
155 | const void *data, | ||
156 | uint32_t type, | ||
157 | uint32_t priority, | ||
158 | uint32_t anonymity, | ||
159 | struct GNUNET_TIME_Absolute | ||
160 | expiration, | ||
161 | uint64_t uid) | ||
126 | { | 162 | { |
127 | struct DatastoreRequestQueue *e = cls; | 163 | struct DatastoreRequestQueue *gc = cls; |
128 | 164 | ||
129 | e->task = GNUNET_SCHEDULER_NO_TASK; | 165 | if (gc->iter == NULL) |
130 | GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, e); | 166 | { |
131 | e->req (e->req_cls, GNUNET_NO); | 167 | /* stop the iteration */ |
132 | GNUNET_free (e); | 168 | if (key != NULL) |
169 | GNUNET_DATASTORE_get_next (dsh, GNUNET_NO); | ||
170 | } | ||
171 | else | ||
172 | { | ||
173 | gc->iter (gc->iter_cls, | ||
174 | key, size, data, type, | ||
175 | priority, anonymity, expiration, uid); | ||
176 | } | ||
177 | if (key == NULL) | ||
178 | { | ||
179 | GNUNET_assert (gc == drq_running); | ||
180 | GNUNET_free (gc); | ||
181 | drq_running = NULL; | ||
182 | next_ds_request (); | ||
183 | } | ||
133 | } | 184 | } |
134 | 185 | ||
135 | 186 | ||
@@ -143,9 +194,13 @@ static void | |||
143 | run_next_request (void *cls, | 194 | run_next_request (void *cls, |
144 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 195 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
145 | { | 196 | { |
146 | struct DatastoreRequestQueue *e = cls; | 197 | struct DatastoreRequestQueue *gc = cls; |
147 | 198 | ||
148 | e->req (e->req_cls, GNUNET_YES); | 199 | gc->task = GNUNET_SCHEDULER_NO_TASK; |
200 | GNUNET_DATASTORE_get (dsh, &gc->key, gc->type, | ||
201 | &get_iterator, | ||
202 | gc, | ||
203 | GNUNET_TIME_absolute_get_remaining(gc->timeout)); | ||
149 | } | 204 | } |
150 | 205 | ||
151 | 206 | ||
@@ -173,65 +228,24 @@ next_ds_request () | |||
173 | 228 | ||
174 | 229 | ||
175 | /** | 230 | /** |
176 | * Remove a pending request from the request queue. | 231 | * A datastore request had to be timed out. |
177 | * | 232 | * |
178 | * @param req request to remove | 233 | * @param cls closure (unused) |
234 | * @param tc task context, unused | ||
179 | */ | 235 | */ |
180 | static void | 236 | static void |
181 | dequeue_ds_request (struct DatastoreRequestQueue *req) | 237 | timeout_ds_request (void *cls, |
182 | { | 238 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
183 | GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, req); | ||
184 | GNUNET_SCHEDULER_cancel (sched, req->task); | ||
185 | GNUNET_free (req); | ||
186 | } | ||
187 | |||
188 | |||
189 | /** | ||
190 | * Queue a request for the datastore. | ||
191 | * | ||
192 | * @param deadline by when the request should run | ||
193 | * @param fun function to call once the request can be run | ||
194 | * @param fun_cls closure for fun | ||
195 | * @param immediate should this be queued immediately at | ||
196 | * the head of the queue (irrespecitive of the deadline)? | ||
197 | * @return handle that can be used to dequeue the request | ||
198 | */ | ||
199 | static struct DatastoreRequestQueue * | ||
200 | queue_ds_request (struct GNUNET_TIME_Relative deadline, | ||
201 | RequestFunction fun, | ||
202 | void *fun_cls, | ||
203 | int immediate) | ||
204 | { | 239 | { |
205 | struct DatastoreRequestQueue *e; | 240 | struct DatastoreRequestQueue *e = cls; |
206 | struct DatastoreRequestQueue *bef; | ||
207 | 241 | ||
208 | e = GNUNET_malloc (sizeof (struct DatastoreRequestQueue)); | 242 | e->task = GNUNET_SCHEDULER_NO_TASK; |
209 | e->timeout = GNUNET_TIME_relative_to_absolute (deadline); | 243 | GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, e); |
210 | e->req = fun; | 244 | if (e->iter != NULL) |
211 | e->req_cls = fun_cls; | 245 | e->iter (e->iter_cls, |
212 | e->forced_head = immediate; | 246 | NULL, 0, NULL, 0, 0, 0, |
213 | if (GNUNET_YES == immediate) | 247 | GNUNET_TIME_UNIT_ZERO_ABS, 0); |
214 | { | 248 | GNUNET_free (e); |
215 | /* local request, highest prio, put at head of queue | ||
216 | regardless of deadline */ | ||
217 | bef = NULL; | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | bef = drq_tail; | ||
222 | while ( (NULL != bef) && | ||
223 | (e->timeout.value < bef->timeout.value) && | ||
224 | (GNUNET_YES != e->forced_head) ) | ||
225 | bef = bef->prev; | ||
226 | } | ||
227 | GNUNET_CONTAINER_DLL_insert_after (drq_head, drq_tail, bef, e); | ||
228 | e->task = GNUNET_SCHEDULER_add_delayed (sched, | ||
229 | deadline, | ||
230 | &timeout_ds_request, | ||
231 | e); | ||
232 | if (drq_running == NULL) | ||
233 | next_ds_request (); | ||
234 | return e; | ||
235 | } | 249 | } |
236 | 250 | ||
237 | 251 | ||
@@ -255,7 +269,10 @@ shutdown_task (void *cls, | |||
255 | { | 269 | { |
256 | drq_head = drq->next; | 270 | drq_head = drq->next; |
257 | GNUNET_SCHEDULER_cancel (sched, drq->task); | 271 | GNUNET_SCHEDULER_cancel (sched, drq->task); |
258 | drq->req (drq->req_cls, GNUNET_NO); | 272 | if (drq->iter != NULL) |
273 | drq->iter (drq->iter_cls, | ||
274 | NULL, 0, NULL, 0, 0, 0, | ||
275 | GNUNET_TIME_UNIT_ZERO_ABS, 0); | ||
259 | GNUNET_free (drq); | 276 | GNUNET_free (drq); |
260 | } | 277 | } |
261 | drq_tail = NULL; | 278 | drq_tail = NULL; |
@@ -263,119 +280,6 @@ shutdown_task (void *cls, | |||
263 | 280 | ||
264 | 281 | ||
265 | /** | 282 | /** |
266 | * Closure for 'do_get' and 'get_iterator'. | ||
267 | */ | ||
268 | struct GetClosure | ||
269 | { | ||
270 | /** | ||
271 | * Key we are doing the 'get' for. | ||
272 | */ | ||
273 | GNUNET_HashCode key; | ||
274 | |||
275 | /** | ||
276 | * Datastore entry type we are doing the 'get' for. | ||
277 | */ | ||
278 | uint32_t type; | ||
279 | |||
280 | /** | ||
281 | * Function to call for each entry. | ||
282 | */ | ||
283 | GNUNET_DATASTORE_Iterator iter; | ||
284 | |||
285 | /** | ||
286 | * Closure for iter. | ||
287 | */ | ||
288 | void *iter_cls; | ||
289 | |||
290 | /** | ||
291 | * Timeout for this operation. | ||
292 | */ | ||
293 | struct GNUNET_TIME_Absolute timeout; | ||
294 | }; | ||
295 | |||
296 | |||
297 | /** | ||
298 | * Wrapper for the datastore get operation. Makes sure to trigger the | ||
299 | * next datastore operation in the queue once the operation is | ||
300 | * complete. | ||
301 | * | ||
302 | * @param cls our 'struct GetClosure*' | ||
303 | * @param key key for the content | ||
304 | * @param size number of bytes in data | ||
305 | * @param data content stored | ||
306 | * @param type type of the content | ||
307 | * @param priority priority of the content | ||
308 | * @param anonymity anonymity-level for the content | ||
309 | * @param expiration expiration time for the content | ||
310 | * @param uid unique identifier for the datum; | ||
311 | * maybe 0 if no unique identifier is available | ||
312 | */ | ||
313 | static void | ||
314 | get_iterator (void *cls, | ||
315 | const GNUNET_HashCode * key, | ||
316 | uint32_t size, | ||
317 | const void *data, | ||
318 | uint32_t type, | ||
319 | uint32_t priority, | ||
320 | uint32_t anonymity, | ||
321 | struct GNUNET_TIME_Absolute | ||
322 | expiration, | ||
323 | uint64_t uid) | ||
324 | { | ||
325 | struct GetClosure *gc = cls; | ||
326 | |||
327 | if (gc->iter == NULL) | ||
328 | { | ||
329 | /* stop the iteration */ | ||
330 | if (key != NULL) | ||
331 | GNUNET_DATASTORE_get_next (dsh, GNUNET_NO); | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | gc->iter (gc->iter_cls, | ||
336 | key, size, data, type, | ||
337 | priority, anonymity, expiration, uid); | ||
338 | } | ||
339 | if (key == NULL) | ||
340 | { | ||
341 | next_ds_request (); | ||
342 | GNUNET_free (gc); | ||
343 | } | ||
344 | } | ||
345 | |||
346 | |||
347 | /** | ||
348 | * We're at the head of the reqeust queue, execute the | ||
349 | * get operation (or signal error). | ||
350 | * | ||
351 | * @param cls the 'struct GetClosure' | ||
352 | * @param ok GNUNET_OK if we can run the GET, otherwise | ||
353 | * we need to time out | ||
354 | */ | ||
355 | static void | ||
356 | do_get (void *cls, | ||
357 | int ok) | ||
358 | { | ||
359 | struct GetClosure *gc = cls; | ||
360 | |||
361 | if (ok != GNUNET_OK) | ||
362 | { | ||
363 | if (gc->iter != NULL) | ||
364 | gc->iter (gc->iter_cls, | ||
365 | NULL, 0, NULL, 0, 0, 0, | ||
366 | GNUNET_TIME_UNIT_ZERO_ABS, 0); | ||
367 | GNUNET_free (gc); | ||
368 | next_ds_request (); | ||
369 | return; | ||
370 | } | ||
371 | GNUNET_DATASTORE_get (dsh, &gc->key, gc->type, | ||
372 | &get_iterator, | ||
373 | gc, | ||
374 | GNUNET_TIME_absolute_get_remaining(gc->timeout)); | ||
375 | } | ||
376 | |||
377 | |||
378 | /** | ||
379 | * Iterate over the results for a particular key | 283 | * Iterate over the results for a particular key |
380 | * in the datastore. The iterator will only be called | 284 | * in the datastore. The iterator will only be called |
381 | * once initially; if the first call did contain a | 285 | * once initially; if the first call did contain a |
@@ -399,18 +303,39 @@ GNUNET_FS_drq_get (const GNUNET_HashCode * key, | |||
399 | struct GNUNET_TIME_Relative timeout, | 303 | struct GNUNET_TIME_Relative timeout, |
400 | int immediate) | 304 | int immediate) |
401 | { | 305 | { |
402 | struct GetClosure *gc; | 306 | struct DatastoreRequestQueue *e; |
403 | 307 | struct DatastoreRequestQueue *bef; | |
404 | gc = GNUNET_malloc (sizeof (struct GetClosure)); | 308 | |
405 | gc->key = *key; | 309 | e = GNUNET_malloc (sizeof (struct DatastoreRequestQueue)); |
406 | gc->type = type; | 310 | e->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
407 | gc->iter = iter; | 311 | e->forced_head = immediate; |
408 | gc->iter_cls = iter_cls; | 312 | e->key = *key; |
409 | gc->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 313 | e->type = type; |
410 | return queue_ds_request (timeout, | 314 | e->iter = iter; |
411 | &do_get, | 315 | e->iter_cls = iter_cls; |
412 | gc, | 316 | e->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
413 | immediate); | 317 | if (GNUNET_YES == immediate) |
318 | { | ||
319 | /* local request, highest prio, put at head of queue | ||
320 | regardless of deadline */ | ||
321 | bef = NULL; | ||
322 | } | ||
323 | else | ||
324 | { | ||
325 | bef = drq_tail; | ||
326 | while ( (NULL != bef) && | ||
327 | (e->timeout.value < bef->timeout.value) && | ||
328 | (GNUNET_YES != e->forced_head) ) | ||
329 | bef = bef->prev; | ||
330 | } | ||
331 | GNUNET_CONTAINER_DLL_insert_after (drq_head, drq_tail, bef, e); | ||
332 | e->task = GNUNET_SCHEDULER_add_delayed (sched, | ||
333 | timeout, | ||
334 | &timeout_ds_request, | ||
335 | e); | ||
336 | if (drq_running == NULL) | ||
337 | next_ds_request (); | ||
338 | return e; | ||
414 | } | 339 | } |
415 | 340 | ||
416 | 341 | ||
@@ -423,20 +348,20 @@ GNUNET_FS_drq_get (const GNUNET_HashCode * key, | |||
423 | void | 348 | void |
424 | GNUNET_FS_drq_get_cancel (struct DatastoreRequestQueue *drq) | 349 | GNUNET_FS_drq_get_cancel (struct DatastoreRequestQueue *drq) |
425 | { | 350 | { |
426 | struct GetClosure *gc; | ||
427 | if (drq == drq_running) | 351 | if (drq == drq_running) |
428 | { | 352 | { |
429 | /* 'DATASTORE_get' has already been started (and this call might | 353 | /* 'DATASTORE_get' has already been started (and this call might |
430 | actually be be legal since it is possible that the client has | 354 | actually be be legal since it is possible that the client has |
431 | not yet received any calls to its the iterator; so we need | 355 | not yet received any calls to its the iterator; so we need to |
432 | to cancel somehow; we do this by getting to the 'GetClosure' | 356 | cancel somehow; we do this by zeroing the 'iter' field, which |
433 | and zeroing the 'iter' field, which stops the iteration */ | 357 | stops the iteration */ |
434 | gc = drq_running->req_cls; | 358 | drq_running->iter = NULL; |
435 | gc->iter = NULL; | ||
436 | } | 359 | } |
437 | else | 360 | else |
438 | { | 361 | { |
439 | dequeue_ds_request (drq); | 362 | GNUNET_CONTAINER_DLL_remove (drq_head, drq_tail, drq); |
363 | GNUNET_SCHEDULER_cancel (sched, drq->task); | ||
364 | GNUNET_free (drq); | ||
440 | } | 365 | } |
441 | } | 366 | } |
442 | 367 | ||
diff --git a/src/fs/test_fs_test_lib.c b/src/fs/test_fs_test_lib.c index d35a91825..0abb539d6 100644 --- a/src/fs/test_fs_test_lib.c +++ b/src/fs/test_fs_test_lib.c | |||
@@ -132,7 +132,7 @@ int | |||
132 | main (int argc, char *argv[]) | 132 | main (int argc, char *argv[]) |
133 | { | 133 | { |
134 | char *const argvx[] = { | 134 | char *const argvx[] = { |
135 | "test-gnunet-service-fs-p2p", | 135 | "test-fs-test-lib", |
136 | "-c", | 136 | "-c", |
137 | "fs_test_lib_data.conf", | 137 | "fs_test_lib_data.conf", |
138 | #if VERBOSE | 138 | #if VERBOSE |
@@ -145,7 +145,7 @@ main (int argc, char *argv[]) | |||
145 | }; | 145 | }; |
146 | 146 | ||
147 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); | 147 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); |
148 | GNUNET_log_setup ("test_gnunet_service_fs_p2p", | 148 | GNUNET_log_setup ("test_fs_test_lib", |
149 | #if VERBOSE | 149 | #if VERBOSE |
150 | "DEBUG", | 150 | "DEBUG", |
151 | #else | 151 | #else |
@@ -153,7 +153,7 @@ main (int argc, char *argv[]) | |||
153 | #endif | 153 | #endif |
154 | NULL); | 154 | NULL); |
155 | GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, | 155 | GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, |
156 | argvx, "test-gnunet-service-fs-p2p", | 156 | argvx, "test-fs-test-lib", |
157 | "nohelp", options, &run, NULL); | 157 | "nohelp", options, &run, NULL); |
158 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); | 158 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); |
159 | return 0; | 159 | return 0; |