aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-daemon-fsprofiler.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-12-07 16:05:22 +0000
committerChristian Grothoff <christian@grothoff.org>2012-12-07 16:05:22 +0000
commitf6afaac108cefb138fa9b38db7fdc68382a55731 (patch)
tree3ada7c0237a179644e64a3313b1f8a64ea56cbe2 /src/fs/gnunet-daemon-fsprofiler.c
parent0d45e157a134a01ec59e8fc564918a1caa5070c4 (diff)
downloadgnunet-f6afaac108cefb138fa9b38db7fdc68382a55731.tar.gz
gnunet-f6afaac108cefb138fa9b38db7fdc68382a55731.zip
-more work on FS profiler
Diffstat (limited to 'src/fs/gnunet-daemon-fsprofiler.c')
-rw-r--r--src/fs/gnunet-daemon-fsprofiler.c304
1 files changed, 301 insertions, 3 deletions
diff --git a/src/fs/gnunet-daemon-fsprofiler.c b/src/fs/gnunet-daemon-fsprofiler.c
index fa9bfd3b2..e83b3e6f2 100644
--- a/src/fs/gnunet-daemon-fsprofiler.c
+++ b/src/fs/gnunet-daemon-fsprofiler.c
@@ -28,6 +28,59 @@
28#include "gnunet_statistics_service.h" 28#include "gnunet_statistics_service.h"
29 29
30/** 30/**
31 * We use 'patterns' of the form (x,y,t) to specify desired download/publish
32 * activities of a peer. They are stored in a DLL.
33 */
34struct Pattern
35{
36 /**
37 * Kept in a DLL.
38 */
39 struct Pattern *next;
40
41 /**
42 * Kept in a DLL.
43 */
44 struct Pattern *prev;
45
46 /**
47 * Execution context for the pattern (FS-handle to the operation).
48 */
49 void *ctx;
50
51 /**
52 * Secondary execution context for the pattern (FS-handle to the operation).
53 */
54 void *sctx;
55
56 /**
57 * When did the operation start?
58 */
59 struct GNUNET_TIME_Absolute start_time;
60
61 /**
62 * With how much delay should this operation be started?
63 */
64 struct GNUNET_TIME_Relative delay;
65
66 /**
67 * Task to run the operation.
68 */
69 GNUNET_SCHEDULER_TaskIdentifier task;
70
71 /**
72 * X-value.
73 */
74 unsigned long long x;
75
76 /**
77 * Y-value.
78 */
79 unsigned long long y;
80};
81
82
83/**
31 * Return value from 'main'. 84 * Return value from 'main'.
32 */ 85 */
33static int global_ret; 86static int global_ret;
@@ -52,8 +105,140 @@ static struct GNUNET_FS_Handle *fs_handle;
52 */ 105 */
53static unsigned long long my_peerid; 106static unsigned long long my_peerid;
54 107
108/**
109 * Desired anonymity level.
110 */
111static unsigned long long anonymity_level;
112
113/**
114 * Desired replication level.
115 */
116static unsigned long long replication_level;
117
118/**
119 * String describing which publishing operations this peer should
120 * perform. The format is "(SIZE,SEED,TIME)*", for example:
121 * "(1,5,0)(7,3,13)" means to publish a file with 1 byte and
122 * seed/keyword 5 immediately and another file with 7 bytes and
123 * seed/keyword 3 after 13 ms.
124 */
125static char *publish_pattern;
126
127/**
128 * Head of the DLL of publish patterns.
129 */
130static struct Pattern *publish_head;
131
132/**
133 * Tail of the DLL of publish patterns.
134 */
135static struct Pattern *publish_tail;
136
137/**
138 * String describing which download operations this peer should
139 * perform. The format is "(KEYWORD,SIZE,DELAY)*"; for example,
140 * "(1,7,3)(3,8,8)" means to download one file of 7 bytes under
141 * keyword "1" starting the search after 3 ms; and another one of 8
142 * bytes under keyword '3' starting after 8 ms. The file size is
143 * used to determine which search result(s) should be used or ignored.
144 */
145static char *download_pattern;
55 146
147/**
148 * Head of the DLL of publish patterns.
149 */
150static struct Pattern *download_head;
56 151
152/**
153 * Tail of the DLL of publish patterns.
154 */
155static struct Pattern *download_tail;
156
157
158/**
159 * Parse a pattern string and store the corresponding
160 * 'struct Pattern' in the given head/tail.
161 *
162 * @param head where to store the head
163 * @param tail where to store the tail
164 * @param pattern pattern to parse
165 * @return GNUNET_OK on success
166 */
167static int
168parse_pattern (struct Pattern **head,
169 struct Pattern **tail,
170 const char *pattern)
171{
172 struct Pattern *p;
173 unsigned long long x;
174 unsigned long long y;
175 unsigned long long t;
176
177 while (3 == sscanf (pattern,
178 "(%llu,%llu,%llu)",
179 &x, &y, &t))
180 {
181 p = GNUNET_malloc (sizeof (struct Pattern));
182 p->x = x;
183 p->y = y;
184 p->delay.rel_value = (uint64_t) t;
185 GNUNET_CONTAINER_DLL_insert (*head, *tail, p);
186 pattern = strstr (pattern, ")");
187 GNUNET_assert (NULL != pattern);
188 pattern++;
189 }
190 return (0 == strlen (pattern)) ? GNUNET_OK : GNUNET_SYSERR;
191}
192
193
194/**
195 * Create a file of the given length with a deterministic amount
196 * of data to be published under keyword 'kval'.
197 *
198 * @param length number of bytes in the file
199 * @param kval keyword value and seed for the data of the file
200 * @param ctx context to pass to 'fi'
201 * @return file information handle for the file
202 */
203static struct GNUNET_FS_FileInformation *
204make_file (uint64_t length,
205 uint64_t kval,
206 void *ctx)
207{
208 struct GNUNET_FS_FileInformation *fi;
209 struct GNUNET_FS_BlockOptions bo;
210 char *data;
211 struct GNUNET_FS_Uri *keywords;
212 char kw[128];
213 unsigned long long i;
214 uint64_t xor;
215
216 data = NULL; /* to make compilers happy */
217 if ( (0 != length) &&
218 (NULL == (data = GNUNET_malloc_large ((size_t) length))) )
219 return NULL;
220 /* initialize data with 'unique' data only depending on 'kval' and 'size',
221 making sure that blocks do not repeat */
222 for (i=0;i<length; i+=8)
223 {
224 xor = length ^ kval ^ (uint64_t) (i / 32 / 1024);
225 memcpy (&data[i], &xor, GNUNET_MIN (length - i, sizeof (uint64_t)));
226 }
227 bo.expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_DAYS);
228 bo.anonymity_level = (uint32_t) anonymity_level;
229 bo.content_priority = 128;
230 bo.replication_level = (uint32_t) replication_level;
231 GNUNET_snprintf (kw, sizeof (kw),
232 "%llu", (unsigned long long) kval);
233 keywords = GNUNET_FS_uri_ksk_create (kw, NULL);
234 fi = GNUNET_FS_file_information_create_from_data (fs_handle,
235 ctx,
236 length,
237 data, keywords,
238 NULL, GNUNET_NO, &bo);
239 GNUNET_FS_uri_destroy (keywords);
240 return fi;
241}
57 242
58 243
59/** 244/**
@@ -65,12 +250,33 @@ static unsigned long long my_peerid;
65static void 250static void
66shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 251shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
67{ 252{
253 struct Pattern *p;
254
255 while (NULL != (p = publish_head))
256 {
257 if (GNUNET_SCHEDULER_NO_TASK != p->task)
258 GNUNET_SCHEDULER_cancel (p->task);
259 if (NULL != p->ctx)
260 GNUNET_FS_publish_stop (p->ctx);
261 GNUNET_CONTAINER_DLL_remove (publish_head, publish_tail, p);
262 GNUNET_free (p);
263 }
264 while (NULL != (p = download_head))
265 {
266 if (GNUNET_SCHEDULER_NO_TASK != p->task)
267 GNUNET_SCHEDULER_cancel (p->task);
268 if (NULL != p->ctx)
269 GNUNET_FS_download_stop (p->ctx, GNUNET_YES);
270 if (NULL != p->sctx)
271 GNUNET_FS_search_stop (p->sctx);
272 GNUNET_CONTAINER_DLL_remove (download_head, download_tail, p);
273 GNUNET_free (p);
274 }
68 if (NULL != fs_handle) 275 if (NULL != fs_handle)
69 { 276 {
70 GNUNET_FS_stop (fs_handle); 277 GNUNET_FS_stop (fs_handle);
71 fs_handle = NULL; 278 fs_handle = NULL;
72 } 279 }
73
74 if (NULL != stats_handle) 280 if (NULL != stats_handle)
75 { 281 {
76 GNUNET_STATISTICS_destroy (stats_handle, GNUNET_YES); 282 GNUNET_STATISTICS_destroy (stats_handle, GNUNET_YES);
@@ -98,11 +304,60 @@ static void *
98progress_cb (void *cls, 304progress_cb (void *cls,
99 const struct GNUNET_FS_ProgressInfo *info) 305 const struct GNUNET_FS_ProgressInfo *info)
100{ 306{
307 // FIXME:
308 // - search result => start download
309 // - publishing done => staitstic, terminate 'struct Pattern'
310 // - download done => statistic, terminate 'struct Pattern'
311 // => all patterns done => then what!? (how do we tell the
312 // drive that we are done!?)
101 return NULL; 313 return NULL;
102} 314}
103 315
104 316
105/** 317/**
318 * Start publish operation.
319 *
320 * @param cls the 'struct Pattern' specifying the operation to perform
321 * @param tc scheduler context
322 */
323static void
324start_publish (void *cls,
325 const struct GNUNET_SCHEDULER_TaskContext *tc)
326{
327 struct Pattern *p = cls;
328 struct GNUNET_FS_FileInformation *fi;
329
330 p->task = GNUNET_SCHEDULER_NO_TASK;
331 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
332 return;
333 fi = make_file (p->x, p->y, p);
334 p->ctx = GNUNET_FS_publish_start (fs_handle,
335 fi,
336 NULL, NULL, NULL,
337 GNUNET_FS_PUBLISH_OPTION_NONE);
338}
339
340
341/**
342 * Start download operation.
343 *
344 * @param cls the 'struct Pattern' specifying the operation to perform
345 * @param tc scheduler context
346 */
347static void
348start_download (void *cls,
349 const struct GNUNET_SCHEDULER_TaskContext *tc)
350{
351 struct Pattern *p = cls;
352
353 p->task = GNUNET_SCHEDULER_NO_TASK;
354 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
355 return;
356 // FIXME: start search operation
357}
358
359
360/**
106 * @brief Main function that will be run by the scheduler. 361 * @brief Main function that will be run by the scheduler.
107 * 362 *
108 * @param cls closure 363 * @param cls closure
@@ -115,6 +370,9 @@ run (void *cls, char *const *args GNUNET_UNUSED,
115 const char *cfgfile GNUNET_UNUSED, 370 const char *cfgfile GNUNET_UNUSED,
116 const struct GNUNET_CONFIGURATION_Handle *cfg_) 371 const struct GNUNET_CONFIGURATION_Handle *cfg_)
117{ 372{
373 char myoptname[128];
374 struct Pattern *p;
375
118 cfg = cfg_; 376 cfg = cfg_;
119 /* Scheduled the task to clean up when shutdown is called */ 377 /* Scheduled the task to clean up when shutdown is called */
120 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, 378 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
@@ -131,6 +389,42 @@ run (void *cls, char *const *args GNUNET_UNUSED,
131 GNUNET_SCHEDULER_shutdown (); 389 GNUNET_SCHEDULER_shutdown ();
132 return; 390 return;
133 } 391 }
392 if (GNUNET_OK !=
393 GNUNET_CONFIGURATION_get_value_number (cfg,
394 "FSPROFILER", "ANONYMITY_LEVEL",
395 &anonymity_level))
396 anonymity_level = 1;
397 if (GNUNET_OK !=
398 GNUNET_CONFIGURATION_get_value_number (cfg,
399 "FSPROFILER", "REPLICATION_LEVEL",
400 &replication_level))
401 replication_level = 1;
402 GNUNET_snprintf (myoptname, sizeof (myoptname),
403 "DOWNLOAD-PATTERN-%u", my_peerid);
404 if (GNUNET_OK !=
405 GNUNET_CONFIGURATION_get_value_string (cfg,
406 "FSPROFILER", myoptname,
407 &download_pattern))
408 download_pattern = GNUNET_strdup ("");
409 GNUNET_snprintf (myoptname, sizeof (myoptname),
410 "PUBLISH-PATTERN-%u", my_peerid);
411 if (GNUNET_OK !=
412 GNUNET_CONFIGURATION_get_value_string (cfg,
413 "FSPROFILER", myoptname,
414 &publish_pattern))
415 publish_pattern = GNUNET_strdup ("");
416 if ( (GNUNET_OK !=
417 parse_pattern (&download_head,
418 &download_tail,
419 download_pattern)) ||
420 (GNUNET_OK !=
421 parse_pattern (&publish_head,
422 &publish_tail,
423 publish_pattern)) )
424 {
425 GNUNET_SCHEDULER_shutdown ();
426 return;
427 }
134 428
135 stats_handle = GNUNET_STATISTICS_create ("fsprofiler", cfg); 429 stats_handle = GNUNET_STATISTICS_create ("fsprofiler", cfg);
136 fs_handle = 430 fs_handle =
@@ -141,7 +435,6 @@ run (void *cls, char *const *args GNUNET_UNUSED,
141 GNUNET_FS_OPTIONS_DOWNLOAD_PARALLELISM, 1, 435 GNUNET_FS_OPTIONS_DOWNLOAD_PARALLELISM, 1,
142 GNUNET_FS_OPTIONS_REQUEST_PARALLELISM, 1, 436 GNUNET_FS_OPTIONS_REQUEST_PARALLELISM, 1,
143 GNUNET_FS_OPTIONS_END); 437 GNUNET_FS_OPTIONS_END);
144
145 if (NULL == fs_handle) 438 if (NULL == fs_handle)
146 { 439 {
147 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not acquire FS handle. Exiting.\n"); 440 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not acquire FS handle. Exiting.\n");
@@ -149,7 +442,12 @@ run (void *cls, char *const *args GNUNET_UNUSED,
149 GNUNET_SCHEDULER_shutdown (); 442 GNUNET_SCHEDULER_shutdown ();
150 return; 443 return;
151 } 444 }
152 445 for (p = publish_head; NULL != p; p = p->next)
446 p->task = GNUNET_SCHEDULER_add_delayed (p->delay,
447 &start_publish, p);
448 for (p = download_head; NULL != p; p = p->next)
449 p->task = GNUNET_SCHEDULER_add_delayed (p->delay,
450 &start_download, p);
153} 451}
154 452
155 453