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 
55 
61 
66 
70  char *subsystem;
71 
75  char *name;
76 
81 
87 
91  void *cb_cls;
92 
97 
102  unsigned int num_peers;
103 
107  unsigned int num_completed;
108 };
109 
110 
119 
124 
129 
133  unsigned int peer_index;
134 };
135 
136 
141 
142 
151 static void
153 {
154  struct GetStatsContext *sc = cls;
155 
157  sc->call_completion_task_id = NULL;
158  LOG_DEBUG("Calling get_statistics() continuation callback\n");
159  sc->cont(sc->cb_cls, sc->main_op, NULL);
160 }
161 
162 
169 static void
170 op_done_task(void *cls)
171 {
172  struct PeerGetStatsContext *peer_sc = cls;
173  struct GetStatsContext *sc;
174  struct GNUNET_TESTBED_Operation **op;
175 
176  sc = peer_sc->sc;
177  peer_sc->op_done_task_id = NULL;
178  op = &sc->ops[peer_sc->peer_index];
179  GNUNET_assert(NULL != *op);
181  *op = NULL;
182 }
183 
184 
192 static void
193 iteration_completion_cb(void *cls, int success)
194 {
195  struct PeerGetStatsContext *peer_sc = cls;
196  struct GetStatsContext *sc;
197 
198  GNUNET_break(GNUNET_OK == success);
199  sc = peer_sc->sc;
200  peer_sc->get_handle = NULL;
201  sc->num_completed++;
203  if (sc->num_completed == sc->num_peers)
204  {
205  LOG_DEBUG("Scheduling to call iteration completion callback\n");
208  }
209 }
210 
211 
222 static int
223 iterator_cb(void *cls, const char *subsystem,
224  const char *name, uint64_t value,
225  int is_persistent)
226 {
227  struct PeerGetStatsContext *peer_sc = cls;
228  struct GetStatsContext *sc;
229  struct GNUNET_TESTBED_Peer *peer;
230  int ret;
231 
232  sc = peer_sc->sc;
233  peer = sc->peers[peer_sc->peer_index];
234  LOG_DEBUG("Peer %u: [%s,%s] -> %lu\n", peer_sc->peer_index,
235  subsystem, name, (unsigned long)value);
236  ret = sc->proc(sc->cb_cls, peer,
237  subsystem, name, value, is_persistent);
238  if (GNUNET_SYSERR == ret)
239  LOG_DEBUG("Aborting iteration for peer %u\n", peer_sc->peer_index);
240  return ret;
241 }
242 
243 
253 static void
256  void *ca_result,
257  const char *emsg)
258 {
259  struct PeerGetStatsContext *peer_sc = cls;
260  struct GNUNET_STATISTICS_Handle *h = ca_result;
261 
262  LOG_DEBUG("Retrieving statistics of peer %u\n",
263  peer_sc->peer_index);
264  peer_sc->get_handle =
265  GNUNET_STATISTICS_get(h, peer_sc->sc->subsystem,
266  peer_sc->sc->name,
268  iterator_cb, peer_sc);
269 }
270 
271 
282 static void *
284 {
285  struct PeerGetStatsContext *peer_sc = cls;
286 
287  LOG_DEBUG("Connecting to statistics service of peer %u\n",
288  peer_sc->peer_index);
289  return GNUNET_STATISTICS_create("<testbed-api>", cfg);
290 }
291 
292 
299 static void
300 statistics_da(void *cls, void *op_result)
301 {
302  struct PeerGetStatsContext *peer_sc = cls;
304 
305  if (NULL != peer_sc->get_handle)
306  {
308  peer_sc->get_handle = NULL;
309  }
311  if (NULL != peer_sc->op_done_task_id)
313  GNUNET_free(peer_sc);
314 }
315 
316 
322 static void
324 {
325  struct GetStatsContext *sc = cls;
326  struct PeerGetStatsContext *peer_sc;
327  unsigned int peer;
328 
329  LOG_DEBUG("Starting get_statistics operation\n");
330  sc->ops = GNUNET_malloc(sc->num_peers *
331  sizeof(struct GNUNET_TESTBED_Operation *));
332  for (peer = 0; peer < sc->num_peers; peer++)
333  {
334  if (NULL == sc->peers[peer])
335  {
336  GNUNET_break(0);
337  continue;
338  }
339  peer_sc = GNUNET_new(struct PeerGetStatsContext);
340  peer_sc->sc = sc;
341  peer_sc->peer_index = peer;
342  sc->ops[peer] =
343  GNUNET_TESTBED_service_connect(sc, sc->peers[peer], "statistics",
345  peer_sc,
346  &statistics_ca,
347  &statistics_da,
348  peer_sc);
349  }
350 }
351 
352 
358 static void
360 {
361  struct GetStatsContext *sc = cls;
362  unsigned int peer;
363 
364  LOG_DEBUG("Cleaning up get_statistics operation\n");
365  if (NULL != sc->call_completion_task_id)
367  if (NULL != sc->ops)
368  {
369  for (peer = 0; peer < sc->num_peers; peer++)
370  {
371  if (NULL != sc->ops[peer])
372  {
374  sc->ops[peer] = NULL;
375  }
376  }
377  GNUNET_free(sc->ops);
378  }
381  GNUNET_free(sc);
382  if (GNUNET_YES ==
384  no_wait_queue = NULL;
385 }
386 
387 
403  struct GNUNET_TESTBED_Peer **peers,
404  const char *subsystem, const char *name,
407  void *cls)
408 {
409  struct GetStatsContext *sc;
410 
411  GNUNET_assert(NULL != proc);
412  GNUNET_assert(NULL != cont);
413  if (NULL == no_wait_queue)
415  (OPERATION_QUEUE_TYPE_FIXED, UINT_MAX);
416  sc = GNUNET_new(struct GetStatsContext);
417  sc->peers = peers;
418  sc->subsystem = (NULL == subsystem) ? NULL : GNUNET_strdup(subsystem);
419  sc->name = (NULL == name) ? NULL : GNUNET_strdup(name);
420  sc->proc = proc;
421  sc->cont = cont;
422  sc->cb_cls = cls;
423  sc->num_peers = num_peers;
424  sc->main_op =
429  return sc->main_op;
430 }
431 
432 
433 /* 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:243
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:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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:1264
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:2037
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:76
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:83
Entry in list of pending tasks.
Definition: scheduler.c:131
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:77
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:956