GNUnet  0.19.4
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 
116 {
121 
126 
131 
135  unsigned int peer_index;
136 };
137 
138 
143 
144 
153 static void
155 {
156  struct GetStatsContext *sc = cls;
157 
158  GNUNET_assert (sc->call_completion_task_id != NULL);
159  sc->call_completion_task_id = NULL;
160  LOG_DEBUG ("Calling get_statistics() continuation callback\n");
161  sc->cont (sc->cb_cls, sc->main_op, NULL);
162 }
163 
164 
171 static void
172 op_done_task (void *cls)
173 {
174  struct PeerGetStatsContext *peer_sc = cls;
175  struct GetStatsContext *sc;
176  struct GNUNET_TESTBED_Operation **op;
177 
178  sc = peer_sc->sc;
179  peer_sc->op_done_task_id = NULL;
180  op = &sc->ops[peer_sc->peer_index];
181  GNUNET_assert (NULL != *op);
183  *op = NULL;
184 }
185 
186 
194 static void
195 iteration_completion_cb (void *cls, int success)
196 {
197  struct PeerGetStatsContext *peer_sc = cls;
198  struct GetStatsContext *sc;
199 
200  GNUNET_break (GNUNET_OK == success);
201  sc = peer_sc->sc;
202  peer_sc->get_handle = NULL;
203  sc->num_completed++;
205  if (sc->num_completed == sc->num_peers)
206  {
207  LOG_DEBUG ("Scheduling to call iteration completion callback\n");
208  sc->call_completion_task_id =
210  }
211 }
212 
213 
224 static int
225 iterator_cb (void *cls, const char *subsystem,
226  const char *name, uint64_t value,
227  int is_persistent)
228 {
229  struct PeerGetStatsContext *peer_sc = cls;
230  struct GetStatsContext *sc;
231  struct GNUNET_TESTBED_Peer *peer;
232  int ret;
233 
234  sc = peer_sc->sc;
235  peer = sc->peers[peer_sc->peer_index];
236  LOG_DEBUG ("Peer %u: [%s,%s] -> %lu\n", peer_sc->peer_index,
237  subsystem, name, (unsigned long) value);
238  ret = sc->proc (sc->cb_cls, peer,
239  subsystem, name, value, is_persistent);
240  if (GNUNET_SYSERR == ret)
241  LOG_DEBUG ("Aborting iteration for peer %u\n", peer_sc->peer_index);
242  return ret;
243 }
244 
245 
255 static void
258  void *ca_result,
259  const char *emsg)
260 {
261  struct PeerGetStatsContext *peer_sc = cls;
262  struct GNUNET_STATISTICS_Handle *h = ca_result;
263 
264  LOG_DEBUG ("Retrieving statistics of peer %u\n",
265  peer_sc->peer_index);
266  peer_sc->get_handle =
267  GNUNET_STATISTICS_get (h, peer_sc->sc->subsystem,
268  peer_sc->sc->name,
270  iterator_cb, peer_sc);
271 }
272 
273 
284 static void *
286 {
287  struct PeerGetStatsContext *peer_sc = cls;
288 
289  LOG_DEBUG ("Connecting to statistics service of peer %u\n",
290  peer_sc->peer_index);
291  return GNUNET_STATISTICS_create ("<testbed-api>", cfg);
292 }
293 
294 
301 static void
302 statistics_da (void *cls, void *op_result)
303 {
304  struct PeerGetStatsContext *peer_sc = cls;
306 
307  if (NULL != peer_sc->get_handle)
308  {
310  peer_sc->get_handle = NULL;
311  }
313  if (NULL != peer_sc->op_done_task_id)
315  GNUNET_free (peer_sc);
316 }
317 
318 
324 static void
325 opstart_get_stats (void *cls)
326 {
327  struct GetStatsContext *sc = cls;
328  struct PeerGetStatsContext *peer_sc;
329  unsigned int peer;
330 
331  LOG_DEBUG ("Starting get_statistics operation\n");
332  sc->ops = GNUNET_malloc (sc->num_peers
333  * sizeof(struct GNUNET_TESTBED_Operation *));
334  for (peer = 0; peer < sc->num_peers; peer++)
335  {
336  if (NULL == sc->peers[peer])
337  {
338  GNUNET_break (0);
339  continue;
340  }
341  peer_sc = GNUNET_new (struct PeerGetStatsContext);
342  peer_sc->sc = sc;
343  peer_sc->peer_index = peer;
344  sc->ops[peer] =
345  GNUNET_TESTBED_service_connect (sc, sc->peers[peer], "statistics",
347  peer_sc,
348  &statistics_ca,
349  &statistics_da,
350  peer_sc);
351  }
352 }
353 
354 
360 static void
362 {
363  struct GetStatsContext *sc = cls;
364  unsigned int peer;
365 
366  LOG_DEBUG ("Cleaning up get_statistics operation\n");
367  if (NULL != sc->call_completion_task_id)
368  GNUNET_SCHEDULER_cancel (sc->call_completion_task_id);
369  if (NULL != sc->ops)
370  {
371  for (peer = 0; peer < sc->num_peers; peer++)
372  {
373  if (NULL != sc->ops[peer])
374  {
376  sc->ops[peer] = NULL;
377  }
378  }
379  GNUNET_free (sc->ops);
380  }
381  GNUNET_free (sc->subsystem);
382  GNUNET_free (sc->name);
383  GNUNET_free (sc);
384  if (GNUNET_YES ==
386  no_wait_queue = NULL;
387 }
388 
389 
405  struct GNUNET_TESTBED_Peer **peers,
406  const char *subsystem, const char *name,
409  void *cls)
410 {
411  struct GetStatsContext *sc;
412 
413  GNUNET_assert (NULL != proc);
414  GNUNET_assert (NULL != cont);
415  if (NULL == no_wait_queue)
417  (OPERATION_QUEUE_TYPE_FIXED, UINT_MAX);
418  sc = GNUNET_new (struct GetStatsContext);
419  sc->peers = peers;
420  sc->subsystem = (NULL == subsystem) ? NULL : GNUNET_strdup (subsystem);
421  sc->name = (NULL == name) ? NULL : GNUNET_strdup (name);
422  sc->proc = proc;
423  sc->cont = cont;
424  sc->cb_cls = cls;
425  sc->num_peers = num_peers;
426  sc->main_op =
431  return sc->main_op;
432 }
433 
434 
435 /* end of testbed_api_statistics.c */
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static struct SolverHandle * sh
static struct CadetPeer * peers
Operation to get peer ids.
static unsigned int num_peers
static char * value
Value of the record to add/remove.
static struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:87
static char * subsystem
Set to subsystem that we're going to get stats for (or NULL for all).
API for writing tests and creating large-scale emulation testbeds for GNUnet.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
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:1299
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
void GNUNET_STATISTICS_get_cancel(struct GNUNET_STATISTICS_GetHandle *gh)
Cancel a GNUNET_STATISTICS_get request.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
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_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:2021
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.
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.
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...
void(* GNUNET_TESTBED_OperationCompletionCallback)(void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
Callback to be called when an operation is completed.
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:246
const char * name
Entry in list of pending tasks.
Definition: scheduler.c:136
Linked list of things we still need to do.
Handle for the service.
Opaque handle to an abstract operation to be executed by the testing framework.
A peer controlled by the testing framework.
Context information for use in GNUNET_TESTBED_get_statistics()
unsigned int num_completed
How many peers' statistics have we iterated through.
struct GNUNET_TESTBED_Peer ** peers
The array of peers whose statistics services are to be accessed.
GNUNET_TESTBED_OperationCompletionCallback cont
The callback to call when we are done iterating through all peers' statistics services.
char * name
The particular statistics value of interest.
unsigned int num_peers
The number of peers present in the peers array.
struct GNUNET_SCHEDULER_Task * call_completion_task_id
The task for calling the continuation callback.
void * cb_cls
The closure for the above callbacks.
struct GNUNET_TESTBED_Operation * main_op
The main operation we generate while creating this context.
GNUNET_TESTBED_StatisticsIterator proc
The iterator to call with statistics information.
char * subsystem
The subsystem of peers for which statistics are requested.
struct GNUNET_TESTBED_Operation ** ops
The service connect operations we create to open connection to the statistics service of each given p...
Queue of operations where we can only support a certain number of concurrent operations of a particul...
Context information with respect to a particular peer.
struct GNUNET_SCHEDULER_Task * op_done_task_id
Task to mark the statistics service connect operation as done.
struct GNUNET_STATISTICS_GetHandle * get_handle
The handle from GNUNET_STATISTICS_get()
struct GetStatsContext * sc
The GetStatsContext which is associated with this context.
unsigned int peer_index
The index of this peer in the peers array of GetStatsContext.
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_operation_create_(void *cls, OperationStart start, OperationRelease release)
Create an 'operation' to be performed.
struct OperationQueue * GNUNET_TESTBED_operation_queue_create_(enum OperationQueueType type, unsigned int max_active)
Create an operation queue.
void GNUNET_TESTBED_operation_queue_insert_(struct OperationQueue *queue, struct GNUNET_TESTBED_Operation *op)
Add an operation to a queue.
void GNUNET_TESTBED_operation_begin_wait_(struct GNUNET_TESTBED_Operation *op)
Marks the given operation as waiting on the queues.
int GNUNET_TESTBED_operation_queue_destroy_empty_(struct OperationQueue *queue)
Destroys the operation queue if it is empty.
internal API to access the 'operations' subsystem
@ OPERATION_QUEUE_TYPE_FIXED
Operation queue which permits a fixed maximum number of operations to be active at any time.
static void iteration_completion_cb(void *cls, int success)
Continuation called by the "get_all" and "get" functions.
static void oprelease_get_stats(void *cls)
Function called when get_statistics operation is cancelled or marked as done.
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.
#define LOG_DEBUG(...)
Debug logging shorthand.
static void call_completion_task(void *cls)
Call statistics operation completion.
static void op_done_task(void *cls)
Task to mark statistics service connect operation as done.
static struct OperationQueue * no_wait_queue
A no-wait operation queue.
static void opstart_get_stats(void *cls)
Function called when get_statistics operation is ready.
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.
static int iterator_cb(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Callback function to process statistic values.
static void statistics_da(void *cls, void *op_result)
Adapter function called to destroy statistics connection.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.