GNUnet  0.10.x
testbed_api_statistics.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2008--2013 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"
29 #include "gnunet_testbed_service.h"
30 
31 #include "testbed_api_operations.h"
32 
33 
37 #define LOG(kind,...) \
38  GNUNET_log_from (kind, "testbed-api-statistics", __VA_ARGS__)
39 
43 #define LOG_DEBUG(...) \
44  LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
45 
46 
51 {
56 
62 
67 
71  char *subsystem;
72 
76  char *name;
77 
82 
88 
92  void *cb_cls;
93 
98 
103  unsigned int num_peers;
104 
108  unsigned int num_completed;
109 
110 };
111 
112 
117 {
122 
127 
132 
136  unsigned int peer_index;
137 };
138 
139 
144 
145 
154 static void
156 {
157  struct GetStatsContext *sc = cls;
158 
160  sc->call_completion_task_id = NULL;
161  LOG_DEBUG ("Calling get_statistics() continuation callback\n");
162  sc->cont (sc->cb_cls, sc->main_op, NULL);
163 }
164 
165 
172 static void
173 op_done_task (void *cls)
174 {
175  struct PeerGetStatsContext *peer_sc = cls;
176  struct GetStatsContext *sc;
177  struct GNUNET_TESTBED_Operation **op;
178 
179  sc = peer_sc->sc;
180  peer_sc->op_done_task_id = NULL;
181  op = &sc->ops[peer_sc->peer_index];
182  GNUNET_assert (NULL != *op);
184  *op = NULL;
185 }
186 
187 
195 static void
196 iteration_completion_cb (void *cls, int success)
197 {
198  struct PeerGetStatsContext *peer_sc = cls;
199  struct GetStatsContext *sc;
200 
201  GNUNET_break (GNUNET_OK == success);
202  sc = peer_sc->sc;
203  peer_sc->get_handle = NULL;
204  sc->num_completed++;
206  if (sc->num_completed == sc->num_peers)
207  {
208  LOG_DEBUG ("Scheduling to call iteration completion callback\n");
211  }
212 }
213 
214 
225 static int
226 iterator_cb (void *cls, const char *subsystem,
227  const char *name, uint64_t value,
228  int is_persistent)
229 {
230  struct PeerGetStatsContext *peer_sc = cls;
231  struct GetStatsContext *sc;
232  struct GNUNET_TESTBED_Peer *peer;
233  int ret;
234 
235  sc = peer_sc->sc;
236  peer = sc->peers[peer_sc->peer_index];
237  LOG_DEBUG ("Peer %u: [%s,%s] -> %lu\n", peer_sc->peer_index,
238  subsystem, name, (unsigned long) value);
239  ret = sc->proc (sc->cb_cls, peer,
240  subsystem, name, value, is_persistent);
241  if (GNUNET_SYSERR == ret)
242  LOG_DEBUG ("Aborting iteration for peer %u\n", peer_sc->peer_index);
243  return ret;
244 }
245 
246 
256 static void
259  void *ca_result,
260  const char *emsg)
261 {
262  struct PeerGetStatsContext *peer_sc = cls;
263  struct GNUNET_STATISTICS_Handle *h = ca_result;
264 
265  LOG_DEBUG ("Retrieving statistics of peer %u\n",
266  peer_sc->peer_index);
267  peer_sc->get_handle =
268  GNUNET_STATISTICS_get (h, peer_sc->sc->subsystem,
269  peer_sc->sc->name,
271  iterator_cb, peer_sc);
272 }
273 
274 
285 static void *
287 {
288  struct PeerGetStatsContext *peer_sc = cls;
289 
290  LOG_DEBUG ("Connecting to statistics service of peer %u\n",
291  peer_sc->peer_index);
292  return GNUNET_STATISTICS_create ("<testbed-api>", cfg);
293 }
294 
295 
302 static void
303 statistics_da (void *cls, void *op_result)
304 {
305  struct PeerGetStatsContext *peer_sc = cls;
307 
308  if (NULL != peer_sc->get_handle)
309  {
311  peer_sc->get_handle = NULL;
312  }
314  if (NULL != peer_sc->op_done_task_id)
316  GNUNET_free (peer_sc);
317 }
318 
319 
325 static void
326 opstart_get_stats (void *cls)
327 {
328  struct GetStatsContext *sc = cls;
329  struct PeerGetStatsContext *peer_sc;
330  unsigned int peer;
331 
332  LOG_DEBUG ("Starting get_statistics operation\n");
333  sc->ops = GNUNET_malloc (sc->num_peers *
334  sizeof (struct GNUNET_TESTBED_Operation *));
335  for (peer = 0; peer < sc->num_peers; peer++)
336  {
337  if (NULL == sc->peers[peer])
338  {
339  GNUNET_break (0);
340  continue;
341  }
342  peer_sc = GNUNET_new (struct PeerGetStatsContext);
343  peer_sc->sc = sc;
344  peer_sc->peer_index = peer;
345  sc->ops[peer] =
346  GNUNET_TESTBED_service_connect (sc, sc->peers[peer], "statistics",
348  peer_sc,
349  &statistics_ca,
350  &statistics_da,
351  peer_sc);
352  }
353 }
354 
355 
361 static void
363 {
364  struct GetStatsContext *sc = cls;
365  unsigned int peer;
366 
367  LOG_DEBUG ("Cleaning up get_statistics operation\n");
368  if (NULL != sc->call_completion_task_id)
370  if (NULL != sc->ops)
371  {
372  for (peer = 0; peer < sc->num_peers; peer++)
373  {
374  if (NULL != sc->ops[peer])
375  {
377  sc->ops[peer] = NULL;
378  }
379  }
380  GNUNET_free (sc->ops);
381  }
384  GNUNET_free (sc);
385  if (GNUNET_YES ==
387  no_wait_queue = NULL;
388 }
389 
390 
406  struct GNUNET_TESTBED_Peer **peers,
407  const char *subsystem, const char *name,
410  void *cls)
411 {
412  struct GetStatsContext *sc;
413 
414  GNUNET_assert (NULL != proc);
415  GNUNET_assert (NULL != cont);
416  if (NULL == no_wait_queue)
418  (OPERATION_QUEUE_TYPE_FIXED, UINT_MAX);
419  sc = GNUNET_new (struct GetStatsContext);
420  sc->peers = peers;
421  sc->subsystem = (NULL == subsystem) ? NULL : GNUNET_strdup (subsystem);
422  sc->name = (NULL == name) ? NULL : GNUNET_strdup (name);
423  sc->proc = proc;
424  sc->cont = cont;
425  sc->cb_cls = cls;
426  sc->num_peers = num_peers;
427  sc->main_op =
430  GNUNET_TESTBED_operation_queue_insert_ (no_wait_queue, sc->main_op);
432  return sc->main_op;
433 }
434 
435 
436 /* end of testbed_api_statistics.c */
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_get_statistics(unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, const char *subsystem, const char *name, GNUNET_TESTBED_StatisticsIterator proc, GNUNET_TESTBED_OperationCompletionCallback cont, void *cls)
Convenience method that iterates over all (running) peers and retrieves all statistics from each peer...
unsigned int peer_index
The index of this peer in the peers array of GetStatsContext.
internal API to access the &#39;operations&#39; subsystem
GNUNET_TESTBED_StatisticsIterator proc
The iterator to call with statistics information.
static struct OperationQueue * no_wait_queue
A no-wait operation queue.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
struct GNUNET_SCHEDULER_Task * op_done_task_id
Task to mark the statistics service connect operation as done.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GetStatsContext * sc
The GetStatsContext which is associated with this context.
static int op_result(struct GNUNET_OP_Handle *h, uint64_t op_id, int64_t result_code, const void *data, uint16_t data_size, void **ctx, uint8_t cancel)
Remove an operation, and call its result callback (unless it was cancelled).
Definition: op.c:244
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_operation_create_(void *cls, OperationStart start, OperationRelease release)
Create an &#39;operation&#39; to be performed.
void GNUNET_STATISTICS_get_cancel(struct GNUNET_STATISTICS_GetHandle *gh)
Cancel a GNUNET_STATISTICS_get request.
unsigned int num_completed
How many peers&#39; statistics have we iterated through.
Operation queue which permits a fixed maximum number of operations to be active at any time...
Linked list of things we still need to do.
#define GNUNET_NO
Definition: gnunet_common.h:81
#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.
void GNUNET_TESTBED_operation_queue_insert_(struct OperationQueue *queue, struct GNUNET_TESTBED_Operation *op)
Add an operation to a queue.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
char * subsystem
The subsystem of peers for which statistics are requested.
static int ret
Final status code.
Definition: gnunet-arm.c:89
Handle for the service.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_STATISTICS_GetHandle * get_handle
The handle from GNUNET_STATISTICS_get()
static void statistics_da(void *cls, void *op_result)
Adapter function called to destroy statistics connection.
struct OperationQueue * GNUNET_TESTBED_operation_queue_create_(enum OperationQueueType type, unsigned int max_active)
Create an operation queue.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
Opaque handle to an abstract operation to be executed by the testing framework.
GNUNET_TESTBED_OperationCompletionCallback cont
The callback to call when we are done iterating through all peers&#39; statistics services.
static void iteration_completion_cb(void *cls, int success)
Continuation called by the "get_all" and "get" functions.
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_service_connect(void *op_cls, struct GNUNET_TESTBED_Peer *peer, const char *service_name, GNUNET_TESTBED_ServiceConnectCompletionCallback cb, void *cb_cls, GNUNET_TESTBED_ConnectAdapter ca, GNUNET_TESTBED_DisconnectAdapter da, void *cada_cls)
Connect to a service offered by the given peer.
struct GNUNET_TESTBED_Peer ** peers
The array of peers whose statistics services are to be accessed.
static char * value
Value of the record to add/remove.
static void opstart_get_stats(void *cls)
Function called when get_statistics operation is ready.
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
static struct SolverHandle * sh
static void * statistics_ca(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Adapter function called to establish a connection to the statistics service of a peer.
static void oprelease_get_stats(void *cls)
Function called when get_statistics operation is cancelled or marked as done.
void GNUNET_TESTBED_operation_done(struct GNUNET_TESTBED_Operation *operation)
This function is used to signal that the event information (struct GNUNET_TESTBED_EventInformation) f...
Definition: testbed_api.c:2046
int GNUNET_TESTBED_operation_queue_destroy_empty_(struct OperationQueue *queue)
Destroys the operation queue if it is empty.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
#define LOG_DEBUG(...)
Debug logging shorthand.
static void call_completion_task(void *cls)
Call statistics operation completion.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
struct GNUNET_SCHEDULER_Task * call_completion_task_id
The task for calling the continuation callback.
static struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:37
Context information for use in GNUNET_TESTBED_get_statistics()
Context information with respect to a particular peer.
void(* GNUNET_TESTBED_OperationCompletionCallback)(void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
Callback to be called when an operation is completed.
Queue of operations where we can only support a certain number of concurrent operations of a particul...
unsigned int num_peers
The number of peers present in the peers array.
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.
void GNUNET_TESTBED_operation_begin_wait_(struct GNUNET_TESTBED_Operation *op)
Marks the given operation as waiting on the queues.
char * name
The particular statistics value of interest.
configuration data
Definition: configuration.c:85
Entry in list of pending tasks.
Definition: scheduler.c:134
static void service_connect_comp(void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
Called after opening a connection to the statistics service of a peer.
void * cb_cls
The closure for the above callbacks.
static int iterator_cb(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Callback function to process statistic values.
#define GNUNET_YES
Definition: gnunet_common.h:80
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
A peer controlled by the testing framework.
static void op_done_task(void *cls)
Task to mark statistics service connect operation as done.
int(* GNUNET_TESTBED_StatisticsIterator)(void *cls, const struct GNUNET_TESTBED_Peer *peer, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Callback function to process statistic values from all peers.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_TESTBED_Operation ** ops
The service connect operations we create to open connection to the statistics service of each given p...
struct GNUNET_TESTBED_Operation * main_op
The main operation we generate while creating this context.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965