Motr  M0
dump.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2015-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 
30 #include <dlfcn.h>
31 #include <err.h>
32 #include <sys/stat.h>
33 #include <stdio.h>
34 #include <sysexits.h>
35 #include <execinfo.h>
36 #include <signal.h>
37 #include <bfd.h>
38 #include <stdlib.h> /* qsort */
39 #include <unistd.h> /* sleep */
40 
41 #include "lib/memory.h"
42 #include "lib/assert.h"
43 #include "lib/errno.h"
44 #include "lib/tlist.h"
45 #include "lib/varr.h"
46 #include "lib/getopts.h"
47 #include "lib/uuid.h" /* m0_node_uuid_string_set */
48 
49 #include "rpc/item.h" /* m0_rpc_item_type_lookup */
50 #include "rpc/rpc_opcodes_xc.h" /* m0_xc_M0_RPC_OPCODES_enum */
51 #include "fop/fop.h"
52 #include "stob/domain.h"
53 #include "stob/stob.h"
54 #include "stob/addb2.h"
55 #include "stob/addb2_xc.h"
56 #include "motr/init.h"
57 #include "module/instance.h"
58 #include "rpc/rpc_opcodes.h" /* M0_OPCODES_NR */
59 #include "rpc/bulk_xc.h"
60 #include "rpc/addb2.h"
61 #include "rpc/addb2_xc.h"
62 #include "be/addb2.h"
63 #include "be/addb2_xc.h"
64 #include "motr/client.h"
65 #include "motr/client_internal_xc.h"
66 #include "motr/addb_xc.h"
67 #include "motr/client_xc.h"
68 #include "ioservice/io_addb2.h"
69 #include "ioservice/io_addb2_xc.h"
70 #include "dix/dix_addb_xc.h"
71 #include "dix/req_xc.h"
72 #include "cas/cas_addb2_xc.h"
73 
74 #include "addb2/identifier.h"
75 #include "addb2/consumer.h"
76 #include "addb2/storage.h"
77 #include "addb2/counter.h"
78 #include "addb2/histogram.h"
79 #include "dtm0/addb2.h"
80 
81 #include "cob/cob_xc.h"
82 #include "stob/addb2.h"
83 #include "stob/addb2_xc.h" /* m0_xc_m0_stio_req_states_enum */
84 #include "net/addb2.h"
85 #include "ioservice/io_addb2.h"
86 #include "cas/cas_addb2.h"
88 #include "sns/cm/cm.h" /* m0_sns_cm_repair_trigger_fop_init */
89 #include "motr/addb.h"
90 #include "dix/dix_addb.h"
91 #include "cas/cas_addb2.h"
92 #include "xcode/xcode.h"
94 #include "addb2/addb2_internal.h"
95 #include "lib/trace.h"
96 #include "lib/thread.h" /* m0_pid() */
97 
98 enum {
99  BUF_SIZE = 4096,
101 };
102 
103 struct fom {
105  uint64_t fo_addr;
106  uint64_t fo_tid;
107  const struct m0_fom_type *fo_type;
108  uint64_t fo_magix;
109 };
110 
112  struct fom c_fom;
113  const struct m0_addb2_record *c_rec;
114  const struct m0_addb2_value *c_val;
115 };
116 
117 struct plugin
118 {
119  const char *p_path;
120  void *p_handle;
121  uint64_t p_flag;
124 };
125 
126 static struct plugin plugins[PLUGINS_MAX];
127 static size_t plugins_nr;
128 
129 static struct m0_varr value_id;
130 
131 static void id_init (void);
132 static void id_fini (void);
133 static void id_set (struct m0_addb2__id_intrp *intrp);
134 static void id_set_nr(struct m0_addb2__id_intrp *intrp, int nr);
135 
136 static struct m0_addb2__id_intrp *id_get(uint64_t id);
137 
138 static void rec_dump(struct m0_addb2__context *ctx,
139  const struct m0_addb2_record *rec);
140 
141 static void val_dump(struct m0_addb2__context *ctx, const char *prefix,
142  const struct m0_addb2_value *val, int indent, bool cr);
143 
144 static void context_fill(struct m0_addb2__context *ctx,
145  const struct m0_addb2_value *val);
146 
147 static void file_dump(struct m0_stob_domain *dom, const char *fname,
148  const uint64_t start_time, const uint64_t stop_time);
149 
150 static int plugin_load(struct plugin *plugin);
151 static void plugin_unload(struct plugin *plugin);
152 static int plugins_load(void);
153 static void plugins_unload(void);
154 
155 static void libbfd_init(const char *libpath);
156 static void libbfd_fini(void);
157 static void libbfd_resolve(uint64_t delta, char *buf);
158 
159 static void flate(void);
160 static void deflate(void);
161 
162 static void misc_init(void);
163 static void misc_fini(void);
164 
165 #define DOM "./_addb2-dump_%d"
166 
167 
168 extern int optind;
169 static bool flatten = false;
170 static bool deflatten = false;
171 static bool json_output = false;
172 static const char *json_extra_data = NULL;
173 static m0_bindex_t offset = 0;
174 static int delay = 0;
175 
176 extern void m0_dix_cm_repair_cpx_init(void);
177 extern void m0_dix_cm_repair_cpx_fini(void);
178 extern void m0_dix_cm_rebalance_cpx_init(void);
179 extern void m0_dix_cm_rebalance_cpx_fini(void);
180 
181 
182 static int plugin_add(const char *path)
183 {
184  struct plugin *plugin;
185 
187  M0_PRE(path != NULL);
188 
190  plugin->p_path = path;
191  ++plugins_nr;
192  return M0_RC(0);
193 }
194 
195 int main(int argc, char **argv)
196 {
197  struct m0_stob_domain *dom;
198  struct m0 instance = {0};
199  int result;
200  int i;
201  int rc;
202  uint64_t start_time = 0;
203  uint64_t stop_time = (uint64_t)-1;
204  char buf[80];
205 
206  sprintf(buf, "linuxstob:"DOM, (int)m0_pid());
207 
209  result = m0_init(&instance);
210  if (result != 0)
211  err(EX_CONFIG, "Cannot initialise motr: %d", result);
212 
213  misc_init();
214 
215  result = M0_GETOPTS("m0addb2dump", argc, argv,
216  M0_FORMATARG('o', "Starting offset",
217  "%"SCNx64, &offset),
218  M0_FORMATARG('c', "Continuous dump interval (sec.)",
219  "%i", &delay),
220  M0_STRINGARG('l', "Motr library path",
221  LAMBDA(void, (const char *path) {
222  libbfd_init(path);
223  })),
224 
225  M0_STRINGARG('p', "Path to plugin",
226  LAMBDA(void, (const char *path) {
227  rc = plugin_add(path);
228 
229  if (rc != 0)
230  err(EX_OSERR, "Memory allocation failed");
231  })),
232  M0_FLAGARG('f', "Flatten output", &flatten),
233  M0_FLAGARG('d', "De-flatten input", &deflatten),
234  M0_FLAGARG('j', "JSON output (see jsonlines.org)", &json_output),
235  M0_STRINGARG('J', "Embed extra JSON data into every record",
236  LAMBDA(void, (const char *json_text) {
237  json_extra_data = strdup(json_text);
238  })),
239  M0_FORMATARG('s', "Capture start time in nanosecs since epoch",
240  "%"PRIu64, &start_time),
241  M0_FORMATARG('e', "Capture finish time in nanosecs since epoch",
242  "%"PRIu64, &stop_time)
243  );
244  if (result != 0)
245  err(EX_USAGE, "Wrong option: %d", result);
246  if (deflatten) {
247  if (flatten || optind < argc)
248  err(EX_USAGE, "De-flattening is exclusive.");
249  deflate();
250  return EX_OK;
251  }
252  if (flatten && optind == argc) {
253  flate();
254  return EX_OK;
255  }
256  if ((delay != 0 || offset != 0) && optind + 1 < argc)
257  err(EX_USAGE,
258  "Staring offset and continuous dump imply single file.");
259  result = m0_stob_domain_init(buf, "directio=true", &dom);
260  if (result == 0)
262  else if (result != -ENOENT)
263  err(EX_CONFIG, "Cannot destroy domain: %d", result);
264  result = m0_stob_domain_create_or_init(buf, "directio=true",
265  /* domain key, not important */
266  8, NULL, &dom);
267  if (result != 0)
268  err(EX_CANTCREAT, "Cannot create domain: %d", result);
269 
270  rc = plugins_load();
271 
272  if (rc != 0)
273  err(EX_CONFIG, "Plugins loading failed");
274 
275  id_init();
276  for (i = optind; i < argc; ++i)
277  file_dump(dom, argv[i], start_time, stop_time);
278 
279  plugins_unload();
280 
281  id_fini();
283  libbfd_fini();
284  misc_fini();
285  m0_fini();
286  return EX_OK;
287 }
288 
289 static int plugin_load(struct plugin *plugin)
290 {
291  M0_ENTRY();
292  M0_PRE(plugin != NULL);
293  M0_PRE(plugin->p_path != NULL);
294 
295  plugin->p_handle = dlopen(plugin->p_path, RTLD_LAZY);
296 
297  if (plugin->p_handle == NULL)
298  return M0_ERR_INFO(-ELIBACC, "%s", dlerror());
299 
301 
302  if (plugin->p_intrp_load == NULL) {
303  dlclose(plugin->p_handle);
304  plugin->p_handle = NULL;
305  return M0_ERR_INFO(-ELIBBAD, "%s", dlerror());
306  }
307 
308  return M0_RC(0);
309 }
310 
311 static void plugin_unload(struct plugin *plugin)
312 {
313  M0_ENTRY();
314  M0_PRE(plugin != NULL);
315  M0_PRE(plugin->p_handle != NULL);
316 
317  dlclose(plugin->p_handle);
318 }
319 
320 static int plugins_load(void)
321 {
322  struct plugin *p;
323  int i;
324  int rc;
325 
326  for (i = 0; i < plugins_nr; ++i) {
327  p = &plugins[i];
328  rc = plugin_load(p) ?: p->p_intrp_load(p->p_flag, &p->p_intrp);
329 
330  if (rc != 0)
331  return M0_ERR(rc);
332  }
333 
334  return M0_RC(0);
335 }
336 
337 static void plugins_unload(void)
338 {
339  struct plugin *plugin;
340  int i;
341 
342  for (i = 0; i < plugins_nr; ++i) {
343  plugin = &plugins[i];
345  }
346 
347  plugins_nr = 0;
348 }
349 
350 static bool intrps_equal(const struct m0_addb2__id_intrp *intrp0,
351  const struct m0_addb2__id_intrp *intrp1)
352 {
353  return memcmp(intrp0, intrp1, sizeof(struct m0_addb2__id_intrp)) == 0;
354 }
355 
356 static void file_dump(struct m0_stob_domain *dom, const char *fname,
357  const uint64_t start_time, const uint64_t stop_time)
358 {
359  struct m0_stob *stob;
360  struct m0_addb2_sit *sit;
361  struct stat buf;
362  struct m0_addb2_record *rec;
363  int result;
364  struct m0_stob_id stob_id;
365 
366  m0_stob_id_make(0, 1 /* stob key, any */, &dom->sd_id, &stob_id);
367  result = m0_stob_find(&stob_id, &stob);
368  if (result != 0)
369  err(EX_CANTCREAT, "Cannot find stob: %d", result);
371  result = m0_stob_locate(stob);
372  if (result != 0)
373  err(EX_CANTCREAT, "Cannot locate stob: %d", result);
374  }
375  result = m0_stob_create(stob, NULL, fname);
376  if (result != 0)
377  err(EX_NOINPUT, "Cannot create stob: %d", result);
379  result = stat(fname, &buf);
380  if (result != 0)
381  err(EX_NOINPUT, "Cannot stat: %d", result);
382  do {
383  result = m0_addb2_sit_init(&sit, stob, offset);
384  if (delay > 0 && result == -EPROTO) {
385  printf("Sleeping for %i seconds (%" PRIx64 ").\n",
386  delay, offset);
387  sleep(delay);
388  continue;
389  }
390  if (result != 0)
391  err(EX_DATAERR, "Cannot initialise iterator: %d",
392  result);
393  while ((result = m0_addb2_sit_next(sit, &rec)) > 0) {
394  if (start_time <= rec->ar_val.va_time &&
395  rec->ar_val.va_time <= stop_time) {
396  rec_dump(&(struct m0_addb2__context){}, rec);
397  if (rec->ar_val.va_id == M0_AVI_SIT)
398  offset = rec->ar_val.va_data[3];
399  }
400  }
401  if (result != 0)
402  err(EX_DATAERR, "Iterator error: %d", result);
404  } while (delay > 0);
406 }
407 
408 static void dec(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
409 {
410  sprintf(buf, "%"PRId64, v[0]);
411 }
412 
413 static void hex(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
414 {
415  if (json_output)
416  /* JSON spec supports only decimal format (int and float) */
417  sprintf(buf, "%"PRId64, v[0]);
418  else
419  sprintf(buf, "%"PRIx64, v[0]);
420 }
421 
422 static void hex0x(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
423 {
424  if (json_output)
425  /* JSON spec supports only decimal format (int and float) */
426  sprintf(buf, "%"PRId64, v[0]);
427  else
428  sprintf(buf, "0x%"PRIx64, v[0]);
429 }
430 
431 static void oct(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
432 {
433  if (json_output)
434  /* JSON spec supports only decimal format (int and float) */
435  sprintf(buf, "%"PRId64, v[0]);
436  else
437  sprintf(buf, "%"PRIo64, v[0]);
438 }
439 
440 static void ptr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
441 {
442  if (json_output)
443  /* JSON spec supports only decimal format (int and float) */
444  sprintf(buf, "{\"ptr\":%" PRIu64 "}", (uint64_t)*(void **)v);
445  else
446  sprintf(buf, "@%p", *(void **)v);
447 }
448 
449 static void bol(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
450 {
451  sprintf(buf, "%s", v[0] ? "true" : "false");
452 }
453 
454 static void fid(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
455 {
456  if (json_output)
457  /* JSON spec supports only decimal format (int and float) */
458  sprintf(buf, "{\"container\":%" PRId64 ","
459  "\"key\":%" PRId64 "}",
460  FID_P((struct m0_fid *)v));
461  else
462  sprintf(buf, FID_F, FID_P((struct m0_fid *)v));
463 }
464 
465 static void skip(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
466 {
467  if (json_output)
468  /*
469  * This is a placeholder guard that must effect parsing error of
470  * resulting JSON output. Normally, "skip" records should be
471  * removed from the output entirely. This is aimed to protect
472  * against the case where a "skip" record might be printed
473  * partially, e.g. only "key" w/o corresponding "value". This
474  * way we can catch it and fix.
475  */
476  sprintf(buf, "[FIXME]");
477  else
478  buf[0] = 0;
479 }
480 
481 static void _clock(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
482 {
483  m0_time_t stamp = v[0];
484  time_t ts = m0_time_seconds(stamp);
485  struct tm tm;
486 
487  if (json_output) {
488  gmtime_r(&ts, &tm);
489  /* ISO8601 formating */
490  sprintf(buf, "\"%04d-%02d-%02dT%02d:%02d:%02d.%09" PRIu64 "Z\"",
491  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
492  tm.tm_hour, tm.tm_min, tm.tm_sec,
493  m0_time_nanoseconds(stamp));
494  }else {
495  localtime_r(&ts, &tm);
496  sprintf(buf, "%04d-%02d-%02d-%02d:%02d:%02d.%09"PRIu64,
497  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
498  tm.tm_hour, tm.tm_min, tm.tm_sec,
499  m0_time_nanoseconds(stamp));
500  }
501 }
502 
503 static void duration(struct m0_addb2__context *ctx, const uint64_t *v,
504  char *buf)
505 {
506  m0_time_t elapsed = v[0];
507 
508  if (json_output)
509  sprintf(buf, "{\"sec\":%" PRId64 ",\"ns\":%" PRId64 "}",
510  m0_time_seconds(elapsed), m0_time_nanoseconds(elapsed));
511  else
512  sprintf(buf, "%" PRId64 ".%09"PRId64,
513  m0_time_seconds(elapsed), m0_time_nanoseconds(elapsed));
514 }
515 
516 static void fom_type(struct m0_addb2__context *ctx, const uint64_t *v,
517  char *buf)
518 {
519  const struct m0_fom_type *ftype = ctx->c_fom.fo_type;
520  const struct m0_sm_conf *conf = &ftype->ft_conf;
521  const char *fmt;
522 
523  if (ftype != NULL) {
524  M0_ASSERT(v[2] < conf->scf_nr_states);
525  fmt = json_output ?
526  "\"type\":\"%s\",\"transitions\":%"PRId64
527  ",\"phase\":\"%s\""
528  : "'%s' transitions: %" PRId64 " phase: %s";
529  sprintf(buf, fmt, conf->scf_name, v[1],
530  conf->scf_state[v[2]].sd_name);
531  } else {
532  fmt = json_output ?
533  "\"type\":\"UNKNOWN-%" PRId64 "\",\"transitions\":%"PRId64
534  ",\"phase\":\"%s\""
535  : "?'UNKNOWN-%" PRId64 "' transitions: %"PRId64
536  " phase: %"PRId64;
537  sprintf(buf, fmt, ctx->c_fom.fo_tid, v[1], v[2]);
538  }
539 }
540 
541 static void sm_state(const struct m0_sm_conf *conf,
542  struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
543 {
544  const char *fmt;
545 
546  /*
547  * v[3] - time stamp
548  * v[2] - transition id
549  * v[1] - state id
550  * v[0] - sm_id
551  */
552 
553  if (conf->scf_trans == NULL) {
554  M0_ASSERT(v[1] == 0);
555  fmt = json_output ?
556  "{\"sm_id\":%" PRId64 ",\"tgt_state\":\"%s\"}" :
557  "sm_id: %" PRIu64 " --> %s";
558  sprintf(buf, fmt, v[0], conf->scf_state[v[2]].sd_name);
559  } else {
560  /* There's no explicit transition into INIT state */
561  if (v[1] == (uint32_t)~0) {
562  fmt = json_output ?
563  "{\"sm_id\":%" PRId64 ",\"tgt_state\":\"%s\"}" :
564  "sm_id: %" PRIu64 " o--> %s";
565  sprintf(buf, fmt, v[0], conf->scf_state[v[2]].sd_name);
566  } else {
567  struct m0_sm_trans_descr *d = &conf->scf_trans[v[1]];
568 
569  M0_ASSERT(d->td_tgt == v[2]);
570  fmt = json_output ?
571  "{\"sm_id\":%"PRId64
572  ",\"src_state\":\"%s\""
573  ",\"cause\":\"%s\""
574  ",\"tgt_state\":\"%s\"}"
575  : "sm_id: %" PRIu64 " %s -[%s]-> %s";
576  sprintf(buf, fmt, v[0],
577  conf->scf_state[d->td_src].sd_name, d->td_cause,
578  conf->scf_state[d->td_tgt].sd_name);
579  }
580  }
581 }
582 
583 extern struct m0_sm_conf fom_states_conf;
584 static void fom_state(struct m0_addb2__context *ctx, const uint64_t *v,
585  char *buf)
586 {
588 }
589 
590 static void fom_phase(struct m0_addb2__context *ctx, const uint64_t *v,
591  char *buf)
592 {
593  const struct m0_sm_conf *conf;
594  const struct m0_sm_trans_descr *d;
595  const struct m0_sm_state_descr *s;
596  const char *fmt;
597  /*
598  * v[0] - sm_id
599  * v[1] - transition id
600  * v[2] - state id
601  */
602  if (ctx->c_fom.fo_type != NULL) {
603  conf = &ctx->c_fom.fo_type->ft_conf;
604  if (conf->scf_trans == NULL) {
605  M0_ASSERT(v[1] == 0);
606  s = &conf->scf_state[v[2]];
607  fmt = json_output ?
608  "{\"sm_id\":%" PRId64 ",\"tgt_state\":\"%s\"}" :
609  "sm_id: %" PRIu64 " --> %s";
610  sprintf(buf, fmt, v[0], s->sd_name);
611  } else if (v[1] < conf->scf_trans_nr) {
612  d = &conf->scf_trans[v[1]];
613  s = &conf->scf_state[d->td_tgt];
614  fmt = json_output ?
615  "{\"sm_id\":%"PRId64
616  ",\"src_state\":\"%s\""
617  ",\"cause\":\"%s\""
618  ",\"tgt_state\":\"%s\"}"
619  : "sm_id: %" PRIu64 " %s -[%s]-> %s";
620  sprintf(buf, fmt, v[0],
621  conf->scf_state[d->td_src].sd_name,
622  d->td_cause, s->sd_name);
623  } else {
624  fmt = json_output ?
625  "{\"sm_id\":%"PRId64
626  ",\"tgt_state\":\"phase transition %i\"}"
627  : "sm_id: %" PRIu64 " phase transition %i";
628  sprintf(buf, fmt, v[0], (int)v[1]);
629  }
630  } else {
631  fmt = json_output ?
632  "{\"sm_id\":%"PRId64
633  ",\"tgt_state\":\"phase ast transition %i\"}"
634  : "sm_id: %" PRIu64 " phase ast transition %i";
635  sprintf(buf, fmt, v[0], (int)v[1]);
636  }
637 }
638 
639 static void rpcop(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
640 {
642 
643  if (it != NULL) {
644  char area[64];
645  sprintf(buf, json_output ? "\"%s\"" : "%s",
646  m0_xcode_enum_print(&m0_xc_M0_RPC_OPCODES_enum,
647  it->rit_opcode, area));
648  } else if (v[0] == 0) {
649  sprintf(buf, json_output ? "\"none\"" : "none");
650  } else
651  sprintf(buf, json_output ? "\"rpc#%" PRId64 "\"" :
652  "?rpc: %"PRId64, v[0]);
653 }
654 
655 static void sym(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
656 {
657  const void *addr = m0_ptr_unwrap(v[0]);
658 
659  if (v[0] != 0) {
660  int rc;
661  Dl_info info;
662 
663  libbfd_resolve(v[0], buf);
664  buf += strlen(buf);
665  rc = dladdr(addr, &info); /* returns non-zero on *success* */
666  if (rc != 0 && info.dli_sname != NULL) {
667  sprintf(buf, json_output ?
668  "\"bfd_symbol\":"
669  "{\"name\":\"%s\",\"addr\":%lu},"
670  : " [%s+%lx]",
671  info.dli_sname, addr - info.dli_saddr);
672  buf += strlen(buf);
673  }
674  if (json_output)
675  sprintf(buf, "\"symbol\":{\"addr\":%" PRIu64 ","
676  "\"addr_ptr_wrap\":%" PRIu64 "}",
677  (uint64_t)addr, v[0]);
678  else
679  sprintf(buf, " @%p/%"PRIx64, addr, v[0]);
680  }
681 }
682 
683 static void counter(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
684 {
685  struct m0_addb2_counter_data *d = (void *)&v[0];
686  char sym_buf[BUF_SIZE];
687  const char *fmt;
688  double avg;
689  double dev;
690 
691  avg = d->cod_nr > 0 ? ((double)d->cod_sum) / d->cod_nr : 0;
692  dev = d->cod_nr > 1 ? ((double)d->cod_ssq) / d->cod_nr - avg * avg : 0;
693 
694  fmt = json_output ?
695  "\"counter\":{"
696  "\"nr\":%"PRId64
697  ",\"min\":%"PRId64
698  ",\"max\":%"PRId64
699  ",\"avg\":%g"
700  ",\"dev\":%g"
701  ",\"datum\":%" PRId64 "}"
702  : " nr: %" PRId64 " min: %" PRId64 " max: %"PRId64
703  " avg: %f dev: %f datum: %" PRIx64 " ";
704 
705  sprintf(buf + strlen(buf), fmt, d->cod_nr, d->cod_min, d->cod_max,
706  avg, dev, d->cod_datum);
707 
708  if (json_output) {
709  sym_buf[0] = '\0';
710  sym(ctx, &d->cod_datum, sym_buf);
711  if (strlen(sym_buf) > 0)
712  sprintf(buf + strlen(buf), ",%s", sym_buf);
713  } else {
714  sym(ctx, &d->cod_datum, buf + strlen(buf));
715  }
716 }
717 
718 static void hbar(char *buf, uint32_t val, uint32_t m)
719 {
720  int len;
721  static const char p[] = /* 60 characters. */
722  "************************************************************";
723  if (!json_output) {
724  len = val * strlen(p) / m;
725  sprintf(buf + strlen(buf), "%*.*s", len, len, p);
726  }
727 }
728 
729 static void hist(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
730 {
731  struct m0_addb2_hist_data *hd = (void *)&v[M0_ADDB2_COUNTER_VALS];
732  int i;
733  int64_t start;
734  uint64_t step;
735  uint32_t m = 1; /* avoid division by 0. */
736  char cr = flatten ? ' ' : '\n';
737 
738  counter(ctx, v, buf);
739  if (json_output)
740  /* TODO: enable histogram support in JSON format */
741  return;
742  start = hd->hd_min;
743  step = (hd->hd_max - hd->hd_min) / (M0_ADDB2_HIST_BUCKETS - 2);
744  sprintf(buf + strlen(buf), " %"PRId32, hd->hd_bucket[0]);
745  for (i = 1; i < ARRAY_SIZE(hd->hd_bucket); ++i) {
746  sprintf(buf + strlen(buf), " %" PRId64 ": %"PRId32,
747  start, hd->hd_bucket[i]);
748  start += step;
749  m = max32(m, hd->hd_bucket[i]);
750  }
751  sprintf(buf + strlen(buf), "%c| : %9"PRId32" | ",
752  cr, hd->hd_bucket[0]);
753  hbar(buf, hd->hd_bucket[0], m);
754  for (i = 1, start = hd->hd_min; i < ARRAY_SIZE(hd->hd_bucket); ++i) {
755  sprintf(buf + strlen(buf), "%c| %9" PRId64 " : %9"PRId32" | ",
756  cr, start, hd->hd_bucket[i]);
757  hbar(buf, hd->hd_bucket[i], m);
758  start += step;
759  }
760 }
761 
762 static void sm_trans(const struct m0_sm_conf *conf, const char *name,
763  struct m0_addb2__context *ctx, char *buf)
764 {
765  int nob;
766  const char *fmt;
767  int idx = ctx->c_val->va_id - conf->scf_addb2_counter;
768  const struct m0_sm_trans_descr *trans = &conf->scf_trans[idx];
769 
770  M0_PRE(conf->scf_addb2_key > 0);
771  M0_PRE(0 <= idx && idx < 200);
772 
773  fmt = json_output ?
774  "{\"name\":\"%s\""
775  ",\"sm_name\":\"%s\""
776  ",\"src_state\":\"%s\""
777  ",\"cause\":\"%s\""
778  ",\"tgt_state\":\"%s\"},"
779  : "%s/%s: %s -[%s]-> %s ";
780  nob = sprintf(buf, fmt, name, conf->scf_name,
781  conf->scf_state[trans->td_src].sd_name,
782  trans->td_cause, conf->scf_state[trans->td_tgt].sd_name);
783  hist(ctx, &ctx->c_val->va_data[0], buf + nob);
784 }
785 
786 static void fom_state_counter(struct m0_addb2__context *ctx, char *buf)
787 {
789 }
790 
791 static void fop_counter(struct m0_addb2__context *ctx, char *buf)
792 {
793  uint64_t mask = ctx->c_val->va_id - M0_AVI_FOP_TYPES_RANGE_START;
794  struct m0_fop_type *fopt = m0_fop_type_find(mask >> 12);
795  const struct m0_sm_conf *conf;
796 
797  if (fopt != NULL) {
798  switch ((mask >> 8) & 0xf) {
799  case M0_AFC_PHASE:
800  conf = &fopt->ft_fom_type.ft_conf;
801  break;
802  case M0_AFC_STATE:
803  conf = &fopt->ft_fom_type.ft_state_conf;
804  break;
805  case M0_AFC_RPC_OUT:
807  break;
808  case M0_AFC_RPC_IN:
810  break;
811  default:
812  M0_IMPOSSIBLE("Wrong mask.");
813  }
814  sm_trans(conf, fopt->ft_name, ctx, buf);
815  } else {
816  if (json_output)
817  sprintf(buf + strlen(buf),
818  "{\"error\":\"unknown-fop-mask\""
819  ",\"msg\":\"Unknown FOP mask 0x%" PRIx64 "\""
820  ",\"fop_mask\":%" PRId64 "},",
821  mask, mask);
822  else
823  sprintf(buf + strlen(buf),
824  " unknown-fop-mask: %"PRIx64, mask);
825  }
826 }
827 
828 static void rpc_in(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
829 {
830  extern const struct m0_sm_conf incoming_item_sm_conf;
832 }
833 
834 static void rpc_out(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
835 {
836  extern const struct m0_sm_conf outgoing_item_sm_conf;
838 }
839 
840 extern struct m0_sm_conf be_tx_sm_conf;
841 static void tx_state(struct m0_addb2__context *ctx, const uint64_t *v,
842  char *buf)
843 {
844  sm_state(&be_tx_sm_conf, ctx, v, buf);
845 }
846 
847 extern struct m0_sm_conf m0_dtx_sm_conf;
848 static void dtx0_state(struct m0_addb2__context *ctx, const uint64_t *v,
849  char *buf)
850 {
852 }
853 
854 static void tx_state_counter(struct m0_addb2__context *ctx, char *buf)
855 {
856  sm_trans(&be_tx_sm_conf, "tx", ctx, buf);
857 }
858 
859 static void dtx0_state_counter(struct m0_addb2__context *ctx, char *buf)
860 {
861  sm_trans(&m0_dtx_sm_conf, "dtx0", ctx, buf);
862 }
863 
864 
865 extern struct m0_sm_conf op_states_conf;
866 static void beop_state_counter(struct m0_addb2__context *ctx, char *buf)
867 {
868  sm_trans(&op_states_conf, "be-op", ctx, buf);
869 }
870 
871 extern struct m0_sm_conf m0_op_conf;
872 static void op_state(struct m0_addb2__context *ctx, const uint64_t *v,
873  char *buf)
874 {
875  sm_state(&m0_op_conf, ctx, v, buf);
876 }
877 
878 static void state_counter(struct m0_addb2__context *ctx, char *buf)
879 {
880  sm_trans(&m0_op_conf, "op", ctx, buf);
881 }
882 
883 extern struct m0_sm_conf dix_req_sm_conf;
884 static void dix_op_state(struct m0_addb2__context *ctx, const uint64_t *v,
885  char *buf)
886 {
888 }
889 
890 static void dix_state_counter(struct m0_addb2__context *ctx, char *buf)
891 {
892  sm_trans(&dix_req_sm_conf, "dix_req", ctx, buf);
893 }
894 
895 extern struct m0_sm_conf cas_req_sm_conf;
896 static void cas_op_state(struct m0_addb2__context *ctx, const uint64_t *v,
897  char *buf)
898 {
900 }
901 
902 static void cas_state_counter(struct m0_addb2__context *ctx, char *buf)
903 {
904  sm_trans(&cas_req_sm_conf, "cas_req", ctx, buf);
905 }
906 
907 extern struct m0_sm_conf io_sm_conf;
908 static void ioo_req_state(struct m0_addb2__context *ctx, const uint64_t *v,
909  char *buf)
910 {
911  sm_state(&io_sm_conf, ctx, v, buf);
912 }
913 
914 static void ioo_state_counter(struct m0_addb2__context *ctx, char *buf)
915 {
916  sm_trans(&io_sm_conf, "ioo_req", ctx, buf);
917 }
918 
919 static void cob_req_state(struct m0_addb2__context *ctx, const uint64_t *v,
920  char *buf)
921 {
922  uint64_t id = v[0];
923  const struct m0_xcode_enum_val *xev =
924  &m0_xc_m0_cob_req_states_enum.xe_val[id];
925  M0_ASSERT(xev->xev_idx == id);
926 
927  sprintf(buf, json_output ? "\"%s\"" : "%s", xev->xev_name);
928 }
929 
930 static void bulk_op_state(struct m0_addb2__context *ctx, const uint64_t *v,
931  char *buf)
932 {
933  uint64_t id = v[0];
934 
935  sprintf(buf, json_output ? "\"%s\"" : "%s",
936  m0_xcode_enum_print(&m0_xc_m0_rpc_bulk_op_states_enum,
937  id, buf));
938 }
939 
941  const uint64_t *v, char *buf)
942 {
943  uint64_t id = v[0];
944  sprintf(buf, json_output ? "\"%s\"" : "%s",
945  m0_xcode_enum_print(&m0_xc_m0_addb2_stio_req_labels_enum,
946  id, buf));
947 }
948 
949 static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
950 {
955  static const struct range_xen {
956  int start;
957  int end;
958  struct m0_xcode_enum *xen;
959  } names[] = {
961  &m0_xc_m0_avi_labels_enum },
963  &m0_xc_m0_avi_dix_labels_enum },
965  &m0_xc_m0_avi_cas_labels_enum },
967  &m0_xc_m0_avi_rpc_labels_enum },
969  &m0_xc_m0_avi_ios_io_labels_enum },
971  &m0_xc_m0_avi_stob_io_labels_enum },
973  &m0_xc_m0_avi_be_labels_enum },
974  }, client_opcode_xc[] = {
976  &m0_xc_m0_entity_opcode_enum },
977  { M0_OC_READ, M0_OC_NR,
978  &m0_xc_m0_obj_opcode_enum },
979  { M0_IC_GET, M0_IC_NR,
980  &m0_xc_m0_idx_opcode_enum },
981  };
982  static const struct attr_name_val {
983  int attr_name;
984  struct m0_xcode_enum *val_xen;
985  } client_values[] = {
987  &m0_xc_m0_entity_type_enum },
988  }, ios_values[] = {
989  { M0_AVI_IOS_IO_ATTR_FOMCOB_FOP_TYPE, &m0_xc_m0_cob_op_enum },
990  }, dix_values[] = {
991  { M0_AVI_DIX_REQ_ATTR_REQ_TYPE, &m0_xc_dix_req_type_enum },
992  }, rpc_values[] = {
993  { M0_AVI_RPC_ATTR_OPCODE, &m0_xc_M0_RPC_OPCODES_enum },
994  { M0_AVI_RPC_BULK_ATTR_OP, &m0_xc_m0_rpc_bulk_op_type_enum },
995  };
996  static struct {
997  struct m0_xcode_enum *attr_name_xen;
998  const struct attr_name_val *name_val;
999  int name_val_nr;
1000  } vnmap[] = {
1001  { &m0_xc_m0_avi_labels_enum, client_values,
1002  ARRAY_SIZE(client_values) },
1003  { &m0_xc_m0_avi_ios_io_labels_enum, ios_values,
1004  ARRAY_SIZE(ios_values) },
1005  { &m0_xc_m0_avi_dix_labels_enum, dix_values,
1006  ARRAY_SIZE(dix_values) },
1007  { &m0_xc_m0_avi_rpc_labels_enum, rpc_values,
1008  ARRAY_SIZE(rpc_values) },
1009  }, *vn = NULL;
1010  uint64_t attr_name = v[0];
1011  uint64_t attr_val = v[1];
1012  struct m0_xcode_enum *attr_name_xen = NULL;
1013  struct m0_xcode_enum *attr_val_xen = NULL;
1014  int i;
1015  char *buf_ptr;
1016 
1017  buf_ptr = buf;
1018 
1019  for (i = 0; i < ARRAY_SIZE(names); ++i) {
1020  if (attr_name >= names[i].start && attr_name < names[i].end) {
1021  attr_name_xen = names[i].xen;
1022  break;
1023  }
1024  }
1025  M0_ASSERT_INFO(i != ARRAY_SIZE(names), "Unsupported subsystem: %"PRIu64,
1026  attr_name);
1027 
1028  sprintf(buf_ptr, json_output ? "\"%s\":" : "%s: ",
1029  m0_xcode_enum_print(attr_name_xen,
1030  attr_name, NULL));
1031  buf_ptr += strlen(buf);
1032 
1033  /* Check whether we can log attr value as a string. */
1034  for (i = 0; i < ARRAY_SIZE(vnmap); i++)
1035  if (attr_name_xen == vnmap[i].attr_name_xen) {
1036  vn = &vnmap[i];
1037  break;
1038  }
1039  for (i = 0; vn && i < vn->name_val_nr; i++)
1040  if (attr_name == vn->name_val[i].attr_name) {
1041  attr_val_xen = vn->name_val[i].val_xen;
1042  break;
1043  }
1044 
1045  /*
1046  * A very specific case for Client opcode which is presented as
1047  * several enums.
1048  */
1049  if (attr_name == M0_AVI_OP_ATTR_CODE) {
1050  M0_ASSERT(attr_val_xen == NULL);
1051  for (i = 0; i < ARRAY_SIZE(client_opcode_xc); ++i) {
1052  if (attr_val >= client_opcode_xc[i].start &&
1053  attr_val < client_opcode_xc[i].end) {
1054  attr_val_xen = client_opcode_xc[i].xen;
1055  break;
1056  }
1057  }
1058  }
1059 
1060  if (attr_val_xen)
1061  sprintf(buf_ptr, json_output ? "\"%s\"" : "%s",
1062  m0_xcode_enum_print(attr_val_xen, attr_val, NULL));
1063  else
1064  sprintf(buf_ptr, "%"PRId64, attr_val);
1065 }
1066 
1067 #define COUNTER &counter, &skip, &skip, &skip, &skip, &skip, &skip
1068 #define FID &fid, &skip
1069 #define TIMED &duration, &sym
1070 #define HIST &hist, &skip, &skip, &skip, &skip, &skip, &skip, &skip, &skip, \
1071  &skip, &skip, &skip, &skip, &skip, &skip
1072 #define SKIP2 &skip, &skip
1073 
1075  { M0_AVI_NULL, "null" },
1076  { M0_AVI_NODE, "node", { FID } },
1077  { M0_AVI_LOCALITY, "locality", { &dec } },
1078  { M0_AVI_PID, "pid", { &dec } },
1079  { M0_AVI_THREAD, "thread", { &hex, &hex } },
1080  { M0_AVI_SERVICE, "service", { FID } },
1081  { M0_AVI_FOM, "fom", { &ptr, &fom_type,
1082  &skip, &skip },
1083  { "addr" } },
1084  { M0_AVI_CLOCK, "clock", { } },
1085  { M0_AVI_PHASE, "fom-phase", { &fom_phase, SKIP2 } },
1086  { M0_AVI_STATE, "fom-state", { &fom_state, SKIP2 } },
1087  { M0_AVI_STATE_COUNTER, "",
1089  .ii_spec = &fom_state_counter },
1090  { M0_AVI_ALLOC, "alloc", { &dec, &ptr },
1091  { "size", "addr" } },
1092  { M0_AVI_FOM_DESCR, "fom-descr", { FID, &hex0x, &rpcop,
1093  &rpcop, &bol, &dec,
1094  &dec, &dec },
1095  { "service", NULL, "sender",
1096  "req-opcode", "rep-opcode", "local", "rpc_sm_id",
1097  "fom_sm_id", "fom_state_sm_id" } },
1098  { M0_AVI_FOM_ACTIVE, "fom-active", { HIST } },
1099  { M0_AVI_RUNQ, "runq", { HIST } },
1100  { M0_AVI_WAIL, "wail", { HIST } },
1101  { M0_AVI_AST, "ast" },
1102  { M0_AVI_LOCALITY_FORQ_DURATION, "loc-forq-duration", { TIMED },
1103  { "duration" } },
1104  { M0_AVI_LOCALITY_FORQ, "loc-forq-hist", { HIST } },
1105  { M0_AVI_LOCALITY_CHAN_WAIT, "loc-wait-hist", { HIST } },
1106  { M0_AVI_LOCALITY_CHAN_CB, "loc-cb-hist", { HIST } },
1107  { M0_AVI_LOCALITY_CHAN_QUEUE,"loc-queue-hist", { HIST } },
1108  { M0_AVI_IOS_IO_DESCR, "ios-io-descr", { FID, FID,
1109  &hex, &hex, &dec, &dec,
1110  &dec, &dec, &dec },
1111  { "file", NULL, "cob", NULL,
1112  "seg-nr", "count", "offset", "descr-nr", "colour" }},
1113  { M0_AVI_FS_OPEN, "m0t1fs-open", { FID, &oct },
1114  { NULL, NULL, "flags" }},
1115  { M0_AVI_FS_LOOKUP, "m0t1fs-lookup", { FID } },
1116  { M0_AVI_FS_CREATE, "m0t1fs-create", { FID, &oct, &dec },
1117  { NULL, NULL, "mode", "rc" } },
1118  { M0_AVI_FS_READ, "m0t1fs-read", { FID } },
1119  { M0_AVI_FS_WRITE, "m0t1fs-write", { FID } },
1120  { M0_AVI_FS_IO_DESCR, "m0t1fs-io-descr", { &dec, &dec },
1121  { "offset", "rc" }},
1122  { M0_AVI_FS_IO_MAP, "m0t1fs-io-map", { &dec, FID, &dec,
1123  &dec, &dec,&dec,
1124  &dec,&dec },
1125  { "req_state", NULL, NULL, "unit_type", "device_state",
1126  "frame", "target", "group", "unit" }},
1127  { M0_AVI_STOB_IO_LAUNCH, "stob-io-launch", { FID, &dec,
1128  &dec, &dec, &dec, &dec },
1129  { "fid", NULL, "count", "bvec-nr", "ivec-nr", "offset" } },
1130  { M0_AVI_STOB_IO_END, "stob-io-end", { FID, &duration,
1131  &dec, &dec, &dec },
1132  { "fid", NULL, "duration", "rc", "count", "frag" } },
1133  { M0_AVI_STOB_IOQ, "stob-ioq-thread", { &dec } },
1134  { M0_AVI_STOB_IOQ_INFLIGHT, "stob-ioq-inflight", { HIST } },
1135  { M0_AVI_STOB_IOQ_QUEUED, "stob-ioq-queued", { HIST } },
1136  { M0_AVI_STOB_IOQ_GOT, "stob-ioq-got", { HIST } },
1137 
1138  { M0_AVI_RPC_LOCK, "rpc-machine-lock", { &ptr } },
1139  { M0_AVI_RPC_REPLIED, "rpc-replied", { &ptr, &rpcop } },
1140  { M0_AVI_RPC_OUT_PHASE, "rpc-out-phase", { &rpc_out, SKIP2 } },
1141  { M0_AVI_RPC_IN_PHASE, "rpc-in-phase", { &rpc_in, SKIP2 } },
1142  { M0_AVI_RPC_ITEM_ID_ASSIGN, "rpc-item-id-assign",
1143  { &dec, &dec, &dec, &dec }, { "id", "opcode", "xid", "session_id" } },
1144  { M0_AVI_RPC_ITEM_ID_FETCH, "rpc-item-id-fetch",
1145  { &dec, &dec, &dec, &dec }, { "id", "opcode", "xid", "session_id" } },
1146 
1147  { M0_AVI_DTX0_SM_STATE, "dtx0-state", { &dtx0_state, SKIP2 } },
1148  { M0_AVI_DTX0_SM_COUNTER, "",
1150  .ii_spec = &dtx0_state_counter },
1151 
1152  { M0_AVI_BE_TX_STATE, "tx-state", { &tx_state, SKIP2 } },
1153  { M0_AVI_BE_TX_COUNTER, "",
1155  .ii_spec = &tx_state_counter },
1156  { M0_AVI_BE_OP_COUNTER, "",
1158  .ii_spec = &beop_state_counter },
1159  { M0_AVI_BE_TX_TO_GROUP, "tx-to-gr", { &dec, &dec, &dec },
1160  { "tx_id", "gr_id", "inout" } },
1161  { M0_AVI_NET_BUF, "net-buf", { &ptr, &dec, &_clock,
1162  &duration, &dec, &dec },
1163  { "buf", "qtype", "time", "duration", "status", "len" } },
1166  .ii_spec = &fop_counter },
1167  { M0_AVI_SIT, "sit", { &hex, &hex, &hex, &hex, &hex,
1168  &dec, &dec, FID },
1169  { "seq", "offset", "prev", "next", "size", "idx", "nr", "fid" } },
1170  { M0_AVI_LONG_LOCK, "long-lock", { &ptr, &duration, &duration },
1171  { "fom", "wait", "hold"} },
1172  { M0_AVI_CAS_KV_SIZES, "cas-kv-sizes", { FID, &dec, &dec },
1173  { "ifid", NULL, "ksize", "vsize"} },
1174 
1175  /* client -> md|io-path */
1176  { M0_AVI_CLIENT_SM_OP, "op-state", { &op_state, SKIP2 } },
1179  .ii_spec = &state_counter },
1180 
1181  /* md path dumplings */
1182  { M0_AVI_DIX_SM_REQ, "dix-req-state", { &dix_op_state, SKIP2 } },
1185  .ii_spec = &dix_state_counter },
1186 
1187  { M0_AVI_CAS_SM_REQ, "cas-req-state", { &cas_op_state, SKIP2 } },
1190  .ii_spec = &cas_state_counter },
1191 
1192  { M0_AVI_CLIENT_TO_DIX, "client-to-dix", { &dec, &dec },
1193  { "client_id", "dix_id" } },
1194  { M0_AVI_DIX_TO_MDIX, "dix-to-mdix", { &dec, &dec },
1195  { "dix_id", "mdix_id" } },
1196  { M0_AVI_DIX_TO_CAS, "dix-to-cas", { &dec, &dec },
1197  { "dix_id", "cas_id" } },
1198  { M0_AVI_CAS_TO_RPC, "cas-to-rpc", { &dec, &dec },
1199  { "cas_id", "rpc_id" } },
1200  { M0_AVI_FOM_TO_TX, "fom-to-tx", { &dec, &dec },
1201  { "fom_id", "tx_id" } },
1202  { M0_AVI_FOM_TO_STIO, "fom-to-stio", { &dec, &dec },
1203  {"fom_id", "stio_id" } },
1204  { M0_AVI_CAS_FOM_TO_CROW_FOM, "cas-fom-to-crow-fom", { &dec, &dec },
1205  { "fom_id", "crow_fom_id" } },
1206 
1207  /* io path dumplings */
1208  { M0_AVI_CLIENT_COB_REQ, "cob-req-state", { &dec, &cob_req_state },
1209  { "cob_id", "cob_state" } },
1210  { M0_AVI_CLIENT_TO_COB_REQ, "client-to-cob", { &dec, &dec },
1211  { "client_id", "cob_id" } },
1212  { M0_AVI_CLIENT_COB_REQ_TO_RPC, "cob-to-rpc", { &dec, &dec },
1213  { "cob_id", "rpc_id" } },
1214  { M0_AVI_CLIENT_TO_IOO, "client-to-ioo", { &dec, &dec },
1215  { "client_id", "ioo_id" } },
1216  { M0_AVI_IOO_TO_RPC, "ioo-to-rpc", { &dec, &dec },
1217  { "ioo_id", "rpc_id" } },
1218 
1219  { M0_AVI_IOO_REQ, "ioo-req-state", { &ioo_req_state, SKIP2 } },
1220  { M0_AVI_IOO_REQ_COUNTER, "",
1222  .ii_spec = &ioo_state_counter },
1223  { M0_AVI_STOB_IO_REQ, "stio-req-state", { &dec, &stob_io_req_state},
1224  { "stio_id", "stio_state" } },
1225 
1226  { M0_AVI_KEM_CPU, "kem-cpu", { &dec },
1227  { "cpu" } },
1228  { M0_AVI_KEM_PAGE_FAULT, "pagefault", { &dec, &dec, &hex,
1229  &dec, &hex, &hex },
1230  { "tgid", "pid", "addr", "wr", "fault", "delta_t" } },
1231  { M0_AVI_KEM_CONTEXT_SWITCH, "ctx_switch", { &dec, &dec,
1232  &dec, &dec, &hex },
1233  { "prev_tgid", "prev_pid", "next_tgid", "next_pid", "delta_t" } },
1234  { M0_AVI_CLIENT_BULK_TO_RPC, "bulk-to-rpc", { &dec, &dec },
1235  { "bulk_id", "rpc_id" } },
1236  { M0_AVI_FOM_TO_BULK, "fom-to-bulk", { &dec, &dec },
1237  { "fom_sm_id", "bulk_id" } },
1238  { M0_AVI_RPC_BULK_OP, "rpc-bulk-op", { &dec, &bulk_op_state },
1239  { "bulk_id", "state" } },
1240  { M0_AVI_ATTR, "attr", { &dec, &attr, &skip },
1241  { "entity_id", NULL, NULL } },
1242  { M0_AVI_NODATA, "nodata" },
1243 };
1244 
1245 static void id_init(void)
1246 {
1247  int result;
1248  int i;
1249  const struct m0_addb2__id_intrp z_intrp = {};
1250 
1251  result = m0_varr_init(&value_id, M0_AVI_LAST, sizeof(char *), 4096);
1252  if (result != 0)
1253  err(EX_CONFIG, "Cannot initialise array: %d", result);
1255 
1256  for (i = 0; i < plugins_nr; ++i) {
1257  struct plugin *p = &plugins[i];
1258  uint32_t e_id_nr = 0;
1259 
1260  /* Calculate array size without last termination item */
1261  for(; !intrps_equal(&p->p_intrp[e_id_nr], &z_intrp); e_id_nr++);
1262 
1263  id_set_nr(p->p_intrp, e_id_nr);
1264  }
1265 }
1266 
1267 static void id_fini(void)
1268 {
1270 }
1271 
1272 static void id_set(struct m0_addb2__id_intrp *intrp)
1273 {
1274  struct m0_addb2__id_intrp **addr;
1275 
1276  if (intrp->ii_id < m0_varr_size(&value_id)) {
1277  addr = m0_varr_ele_get(&value_id, intrp->ii_id);
1278  M0_ASSERT(addr != NULL);
1279  M0_ASSERT(*addr == NULL);
1280  *addr = intrp;
1281  }
1282 }
1283 
1284 static void id_set_nr(struct m0_addb2__id_intrp *batch, int nr)
1285 {
1286  while (nr-- > 0) {
1287  struct m0_addb2__id_intrp *intrp = &batch[nr];
1288  int i;
1289 
1290  id_set(intrp);
1291  for (i = 0; i < intrp->ii_repeat; ++i) {
1292  ++(intrp->ii_id);
1293  id_set(intrp);
1294  }
1295  }
1296 }
1297 
1298 static struct m0_addb2__id_intrp *id_get(uint64_t id)
1299 {
1300  struct m0_addb2__id_intrp **addr;
1301  struct m0_addb2__id_intrp *intr = NULL;
1302 
1303  if (id < m0_varr_size(&value_id)) {
1304  addr = m0_varr_ele_get(&value_id, id);
1305  if (addr != NULL)
1306  intr = *addr;
1307  }
1308  return intr;
1309 }
1310 
1311 #define U64 "%16"PRIx64
1312 
1313 static void rec_dump(struct m0_addb2__context *ctx,
1314  const struct m0_addb2_record *rec)
1315 {
1316  int i;
1317 
1318  ctx->c_rec = rec;
1319  context_fill(ctx, &rec->ar_val);
1320  for (i = 0; i < rec->ar_label_nr; ++i)
1321  context_fill(ctx, &rec->ar_label[i]);
1322  if (json_output)
1323  printf("{");
1324  val_dump(ctx, "* ", &rec->ar_val, 0, !flatten);
1325  if (json_output && rec->ar_label_nr > 0)
1326  printf(",");
1327  for (i = 0; i < rec->ar_label_nr; ++i) {
1328  val_dump(ctx, "| ", &rec->ar_label[i], 8, !flatten);
1329  if (json_output && i < rec->ar_label_nr - 1)
1330  printf(",");
1331  }
1332  if (json_output) {
1333  if (json_extra_data != NULL)
1334  printf(",%s}\n", json_extra_data);
1335  else
1336  puts("}");
1337  } else if (flatten) {
1338  puts("");
1339  }
1340 }
1341 
1342 static int pad(int indent)
1343 {
1344  return indent > 0 ? printf("%*.*s", indent, indent,
1345  " ") : 0;
1346 }
1347 
1348 static unsigned int count_nonempty_vals(const struct m0_addb2_value *val)
1349 {
1350  struct m0_addb2__id_intrp *intrp = id_get(val->va_id);
1351  int i, c;
1352 
1353  for (i = 0, c = 0; intrp != NULL && i < val->va_nr; ++i)
1354  if (intrp->ii_print[i] != NULL && intrp->ii_print[i] != &skip)
1355  c++;
1356  return c;
1357 }
1358 
1360  const struct m0_addb2_value *val, bool output_timestamp)
1361 {
1362  struct m0_addb2__id_intrp *intrp = id_get(val->va_id);
1363  int i;
1364  char buf[BUF_SIZE];
1365  bool need_braces = false;
1366  bool need_comma;
1367 
1368 #define BEND (buf + strlen(buf))
1369 
1370  ctx->c_val = val;
1371  if (output_timestamp && val->va_time != 0) {
1372  _clock(ctx, &val->va_time, buf);
1373  printf("\"timestamp\":%s,", buf);
1374  }
1375  if (intrp != NULL && intrp->ii_spec != NULL) {
1376  intrp->ii_spec(ctx, buf);
1377  // FIXME: rename "spec" to something meaningful
1378  printf("\"spec\":%s", buf);
1379  return;
1380  }
1381  if (intrp != NULL) {
1382  need_braces = count_nonempty_vals(val) > 1;
1383  printf("\"%s\":%s", intrp->ii_name, need_braces ? "{" : "");
1384  /* boolean attributes (flags) */
1385  if (val->va_nr == 0)
1386  printf("true");
1387  else if (intrp->ii_print != NULL &&
1388  intrp->ii_print[0] == &hist)
1389  printf("true,");
1390  }
1391  else {
1392  printf("\"m0addb2dump[%s:%u]:%" PRIu64 "\"",
1393  __FILE__, __LINE__, val->va_id);
1394  }
1395  for (i = 0; i < val->va_nr; ++i) {
1396  buf[0] = 0;
1397  if (intrp == NULL)
1398  sprintf(buf, "\"m0addb2dump[%s:%u]:%" PRIu64 "\"",
1399  __FILE__, __LINE__, val->va_data[i]);
1400  else {
1401  if (intrp->ii_field[i] != NULL)
1402  sprintf(buf, "\"%s\":", intrp->ii_field[i]);
1403 
1404  need_comma = (i < val->va_nr - 2 &&
1405  intrp->ii_print[i] == &fid) ||
1406  (i < val->va_nr - 1 &&
1407  (intrp->ii_field[i + 1] != NULL ||
1408  intrp->ii_print[i + 1] == &attr));
1409 
1410  if (intrp->ii_print[i] == NULL)
1411  sprintf(BEND, "%" PRId64 "%s", val->va_data[i],
1412  need_comma ? "," : "");
1413  else {
1414  if (intrp->ii_print[i] == &skip)
1415  continue;
1416  intrp->ii_print[i](ctx, &val->va_data[i], BEND);
1417  if (intrp->ii_print[i] == &ptr ||
1418  intrp->ii_print[i] == &duration)
1419  need_comma = i < val->va_nr - 1;
1420  printf("%s%s", buf, need_comma ? "," : "");
1421  }
1422  }
1423  }
1424  if (need_braces)
1425  printf("}");
1426 #undef BEND
1427 }
1428 
1429 static void val_dump_plaintext(struct m0_addb2__context *ctx, const char *prefix,
1430  const struct m0_addb2_value *val, int indent, bool cr)
1431 {
1432  struct m0_addb2__id_intrp *intrp = id_get(val->va_id);
1433  int i;
1434  char buf[BUF_SIZE];
1435  enum { WIDTH = 12 };
1436 
1437 #define BEND (buf + strlen(buf))
1438 
1439  ctx->c_val = val;
1440  printf("%s", prefix);
1441  pad(indent);
1442  if (indent == 0 && val->va_time != 0) {
1443  _clock(ctx, &val->va_time, buf);
1444  printf("%s ", buf);
1445  }
1446  if (intrp != NULL && intrp->ii_spec != NULL) {
1447  intrp->ii_spec(ctx, buf);
1448  printf("%s%s", buf, cr ? "\n" : " ");
1449  return;
1450  }
1451  if (intrp != NULL)
1452  printf("%-16s ", intrp->ii_name);
1453  else
1454  printf(U64" ", val->va_id);
1455  for (i = 0, indent = 0; i < val->va_nr; ++i) {
1456  buf[0] = 0;
1457  if (intrp == NULL)
1458  sprintf(buf, "?"U64"?", val->va_data[i]);
1459  else {
1460  if (intrp->ii_field[i] != NULL)
1461  sprintf(buf, "%s: ", intrp->ii_field[i]);
1462  if (intrp->ii_print[i] == NULL)
1463  sprintf(BEND, "?"U64"?", val->va_data[i]);
1464  else {
1465  if (intrp->ii_print[i] == &skip)
1466  continue;
1467  intrp->ii_print[i](ctx, &val->va_data[i], BEND);
1468  }
1469  }
1470  if (i > 0)
1471  indent += printf(", ");
1472  indent += pad(WIDTH * i - indent);
1473  indent += printf("%s", buf);
1474  }
1475  printf("%s", cr ? "\n" : " ");
1476 #undef BEND
1477 }
1478 
1479 static void val_dump(struct m0_addb2__context *ctx, const char *prefix,
1480  const struct m0_addb2_value *val, int indent, bool cr)
1481 {
1482  if (json_output)
1483  val_dump_json(ctx, val, indent == 0 /* print timestamp? */);
1484  else
1486 }
1487 
1488 extern struct m0_fom_type *m0_fom__types[M0_OPCODES_NR];
1489 static void context_fill(struct m0_addb2__context *ctx,
1490  const struct m0_addb2_value *val)
1491 {
1492  switch (val->va_id) {
1493  case M0_AVI_FOM:
1494  ctx->c_fom.fo_addr = val->va_data[0];
1495  ctx->c_fom.fo_tid = val->va_data[1];
1496  M0_ASSERT(val->va_data[1] < ARRAY_SIZE(m0_fom__types));
1497  ctx->c_fom.fo_type = m0_fom__types[val->va_data[1]];
1498  break;
1499  }
1500 }
1501 
1502 static bfd *abfd;
1503 static asymbol **syms;
1504 static uint64_t base;
1505 static size_t nr;
1506 
1507 static int asymbol_cmp(const void *a0, const void *a1)
1508 {
1509  const asymbol *const* s0 = a0;
1510  const asymbol *const* s1 = a1;
1511 
1512  return ((int)bfd_asymbol_value(*s0)) - ((int)bfd_asymbol_value(*s1));
1513 }
1514 
1518 static void libbfd_init(const char *libpath)
1519 {
1520  unsigned symtab_size;
1521  size_t i;
1522 
1523  bfd_init();
1524  abfd = bfd_openr(libpath, 0);
1525  if (abfd == NULL)
1526  err(EX_OSERR, "bfd_openr(): %d.", errno);
1527  bfd_check_format(abfd, bfd_object); /* cargo-cult call. */
1528  symtab_size = bfd_get_symtab_upper_bound(abfd);
1529  syms = (asymbol **) m0_alloc(symtab_size);
1530  if (syms == NULL)
1531  err(EX_UNAVAILABLE, "Cannot allocate symtab.");
1532  nr = bfd_canonicalize_symtab(abfd, syms);
1533  for (i = 0; i < nr; ++i) {
1534  if (strcmp(syms[i]->name, "m0_ptr_wrap") == 0) {
1535  base = bfd_asymbol_value(syms[i]);
1536  break;
1537  }
1538  }
1539  if (base == 0)
1540  err(EX_CONFIG, "No base symbol found.");
1541  qsort(syms, nr, sizeof syms[0], &asymbol_cmp);
1542 }
1543 
1544 static void libbfd_fini(void)
1545 {
1546  m0_free(syms);
1547 }
1548 
1549 static void libbfd_resolve(uint64_t delta, char *buf)
1550 {
1551  static uint64_t cached = 0;
1552  static const char *name = NULL;
1553 
1554  if (abfd == NULL)
1555  ;
1556  else if (delta == cached)
1557  sprintf(buf, " %s", name);
1558  else {
1559  size_t mid;
1560  size_t left = 0;
1561  size_t right = nr;
1562 
1563  cached = delta;
1564  delta += base;
1565  while (left + 1 < right) {
1566  asymbol *sym;
1567 
1568  mid = (left + right) / 2;
1569  sym = syms[mid];
1570 
1571  if (bfd_asymbol_value(sym) > delta)
1572  right = mid;
1573  else if (bfd_asymbol_value(sym) < delta)
1574  left = mid;
1575  else {
1576  left = mid;
1577  break;
1578  }
1579  }
1580  name = syms[left]->name;
1581  sprintf(buf, " %s", name);
1582  }
1583 }
1584 
1585 static void deflate(void)
1586 {
1587  int ch;
1588 
1589  while ((ch = getchar()) != EOF) {
1590  if (ch == '|')
1591  putchar('\n');
1592  putchar(ch);
1593  }
1594 }
1595 
1596 static void flate(void)
1597 {
1598  int ch;
1599  int prev;
1600 
1601  for (prev = 0; (ch = getchar()) != EOF; prev = ch) {
1602  if (prev == '\n' && ch == '|')
1603  prev = ' ';
1604  if (prev != 0)
1605  putchar(prev);
1606  }
1607  if (prev != 0)
1608  putchar(prev);
1609 }
1610 
1611 static void misc_init(void)
1612 {
1619 }
1620 
1621 static void misc_fini(void)
1622 {
1629 }
1630 
1633 /*
1634  * Local variables:
1635  * c-indentation-style: "K&R"
1636  * c-basic-offset: 8
1637  * tab-width: 8
1638  * fill-column: 80
1639  * scroll-step: 1
1640  * End:
1641  */
1642 /*
1643  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
1644  */
struct m0_sm_conf dix_req_sm_conf
Definition: req.c:135
static void sm_state(const struct m0_sm_conf *conf, struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:541
struct m0_sm_conf be_tx_sm_conf
Definition: tx.c:176
void m0_dix_cm_repair_cpx_init(void)
#define M0_GETOPTS(progname, argc, argv,...)
Definition: getopts.h:169
uint64_t id
Definition: cob.h:2380
Definition: dump.c:99
static void ptr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:440
static void bulk_op_state(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:930
static struct m0_addb2_philter p
Definition: consumer.c:40
static size_t nr
Definition: dump.c:1505
static void id_init(void)
Definition: dump.c:1245
int optind
static struct m0_addb2__id_intrp * id_get(uint64_t id)
Definition: dump.c:1298
static void val_dump_plaintext(struct m0_addb2__context *ctx, const char *prefix, const struct m0_addb2_value *val, int indent, bool cr)
Definition: dump.c:1429
static const char * json_extra_data
Definition: dump.c:172
#define M0_PRE(cond)
static bool json_output
Definition: dump.c:171
void m0_dix_cm_repair_cpx_fini(void)
struct m0_sm_conf op_states_conf
Definition: op.c:66
void(* ii_print[M0_ADDB2__FIELD_MAX])(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
const struct m0_sm_conf incoming_item_sm_conf
Definition: item.c:60
static void id_set_nr(struct m0_addb2__id_intrp *intrp, int nr)
Definition: dump.c:1284
#define M0_FLAGARG(ch, desc, ptr)
Definition: getopts.h:232
M0_INTERNAL int struct dentry struct kstat * stat
Definition: dir.c:1433
static void misc_fini(void)
Definition: dump.c:1621
#define NULL
Definition: misc.h:38
static struct m0_addb2_mach * m
Definition: consumer.c:38
M0_INTERNAL int m0_stob_locate(struct m0_stob *stob)
Definition: stob.c:128
struct m0_sm_conf fom_states_conf
Definition: fom.c:1652
M0_INTERNAL void m0_sns_cm_repair_sw_onwire_fop_fini(void)
Definition: sw_onwire_fop.c:81
static void beop_state_counter(struct m0_addb2__context *ctx, char *buf)
Definition: dump.c:866
Definition: idx_mock.c:52
void m0_fini(void)
Definition: init.c:318
static void sym(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:655
static void fom_state_counter(struct m0_addb2__context *ctx, char *buf)
Definition: dump.c:786
Definition: sm.h:350
static void id_set(struct m0_addb2__id_intrp *intrp)
Definition: dump.c:1272
static void id_fini(void)
Definition: dump.c:1267
const char * p_path
Definition: dump.c:119
uint32_t td_tgt
Definition: sm.h:489
uint64_t m0_time_t
Definition: time.h:37
#define SCNx64
Definition: types.h:62
static int pad(int indent)
Definition: dump.c:1342
void * p_handle
Definition: dump.c:120
static void ioo_req_state(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:908
M0_INTERNAL int m0_stob_domain_destroy(struct m0_stob_domain *dom)
Definition: domain.c:227
M0_INTERNAL void m0_sns_cm_rebalance_trigger_fop_init(void)
Definition: trigger_fop.c:54
#define U64
Definition: dump.c:1311
M0_INTERNAL void m0_sns_cm_rebalance_sw_onwire_fop_fini(void)
Definition: sw_onwire_fop.c:81
uint64_t m0_time_nanoseconds(const m0_time_t time)
Definition: time.c:89
static struct m0_uint128 prefix
Definition: extmap.c:45
static void rpc_in(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:828
static int delay
Definition: dump.c:174
uint64_t p_flag
Definition: dump.c:121
struct m0_sm_conf io_sm_conf
Definition: io_req.c:141
static struct m0_be_emap_cursor it
Definition: extmap.c:46
uint64_t va_id
Definition: consumer.h:103
Definition: conf.py:1
uint64_t m0_bindex_t
Definition: types.h:80
M0_INTERNAL struct m0_rpc_item_type * m0_rpc_item_type_lookup(uint32_t opcode)
Definition: item.c:189
struct m0_sm_conf rit_incoming_conf
Definition: item.h:483
static void dtx0_state_counter(struct m0_addb2__context *ctx, char *buf)
Definition: dump.c:859
static struct m0_varr value_id
Definition: dump.c:129
static int left
Definition: locality.c:280
unsigned ar_label_nr
Definition: consumer.h:116
M0_INTERNAL void m0_sns_cm_rebalance_sw_onwire_fop_init(void)
Definition: sw_onwire_fop.c:63
static int void * buf
Definition: dir.c:1019
int m0_init(struct m0 *instance)
Definition: init.c:310
static int32_t max32(int32_t a, int32_t b)
Definition: arith.h:41
static void hist(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:729
void m0_dix_cm_rebalance_cpx_fini(void)
#define PRIx64
Definition: types.h:61
struct fom c_fom
Definition: dump.c:112
Definition: sock.c:887
struct m0_fom_type ft_fom_type
Definition: fop.h:232
const struct m0_fom_type * fo_type
Definition: dump.c:107
static void dix_state_counter(struct m0_addb2__context *ctx, char *buf)
Definition: dump.c:890
return M0_RC(rc)
M0_INTERNAL void m0_sns_cm_repair_trigger_fop_init(void)
Definition: trigger_fop.c:55
const char * ii_name
static bool intrps_equal(const struct m0_addb2__id_intrp *intrp0, const struct m0_addb2__id_intrp *intrp1)
Definition: dump.c:350
Definition: dump.c:117
#define M0_ENTRY(...)
Definition: trace.h:170
void(* ii_spec)(struct m0_addb2__context *ctx, char *buf)
m0_addb2__intrp_load_t p_intrp_load
Definition: dump.c:122
static void hex0x(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:422
static char * addr
Definition: node_k.c:37
#define M0_STRINGARG(ch, desc, func)
Definition: getopts.h:207
int i
Definition: dir.c:1033
static void rpc_out(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:834
#define PRIu64
Definition: types.h:58
const struct m0_addb2_record * c_rec
Definition: dump.c:113
static bfd * abfd
Definition: dump.c:1502
#define M0_ERR_INFO(rc, fmt,...)
Definition: trace.h:215
static void tx_state_counter(struct m0_addb2__context *ctx, char *buf)
Definition: dump.c:854
return M0_ERR(-EOPNOTSUPP)
#define LAMBDA(T,...)
Definition: thread.h:153
static void fom_phase(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:590
static void cas_op_state(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:896
static void plugin_unload(struct plugin *plugin)
Definition: dump.c:311
const char * name
Definition: trace.c:110
uint64_t va_time
Definition: consumer.h:104
static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:949
const char * ft_name
Definition: fop.h:225
static struct m0_addb2_sit * sit
Definition: storage.c:40
#define M0_FORMATARG(ch, desc, fmt, ptr)
Definition: getopts.h:218
Definition: stob.h:163
M0_INTERNAL uint64_t m0_varr_size(const struct m0_varr *arr)
Definition: varr.c:567
static struct m0_stob * stob
Definition: storage.c:39
static void tx_state(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:841
#define M0_ASSERT(cond)
static void counter(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:683
struct crate_conf * conf
static void duration(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:503
struct m0_sm_conf rit_outgoing_conf
Definition: item.h:484
#define HIST
Definition: dump.c:1070
uint64_t cod_ssq
Definition: counter.h:45
static struct m0_addb2_callback c
Definition: consumer.c:41
void m0_node_uuid_string_set(const char *uuid)
Definition: uuuid.c:64
static void libbfd_fini(void)
Definition: dump.c:1544
static unsigned int count_nonempty_vals(const struct m0_addb2_value *val)
Definition: dump.c:1348
uint32_t hd_bucket[M0_ADDB2_HIST_BUCKETS]
Definition: histogram.h:121
struct m0_sm_conf cas_req_sm_conf
Definition: client.c:133
const struct m0_addb2_value * c_val
Definition: dump.c:114
M0_INTERNAL int m0_varr_init(struct m0_varr *arr, uint64_t nr, size_t size, size_t bufsize)
Definition: varr.c:114
static struct m0_stob_domain * dom
Definition: storage.c:38
M0_INTERNAL void m0_stob_id_make(uint64_t container, uint64_t key, const struct m0_fid *dom_id, struct m0_stob_id *stob_id)
Definition: stob.c:343
#define FID
Definition: dump.c:1068
M0_INTERNAL const void * m0_ptr_unwrap(uint64_t val)
Definition: misc.c:282
static int plugin_add(const char *path)
Definition: dump.c:182
struct m0_addb2__id_intrp * p_intrp
Definition: dump.c:123
Definition: instance.h:80
static void rec_dump(struct m0_addb2__context *ctx, const struct m0_addb2_record *rec)
Definition: dump.c:1313
int m0_addb2_sit_init(struct m0_addb2_sit **out, struct m0_stob *stob, m0_bindex_t start)
Definition: sit.c:108
static void val_dump_json(struct m0_addb2__context *ctx, const struct m0_addb2_value *val, bool output_timestamp)
Definition: dump.c:1359
char * fmt(const char *format,...) __attribute__((format(printf
void * m0_alloc(size_t size)
Definition: memory.c:126
struct m0_addb2_value ar_label[M0_ADDB2_LABEL_MAX]
Definition: consumer.h:118
Definition: xcode.h:73
#define SKIP2
Definition: dump.c:1072
uint32_t td_src
Definition: sm.h:488
#define PRIo64
Definition: types.h:60
Definition: dump.c:103
static m0_bindex_t offset
Definition: dump.c:173
static void context_fill(struct m0_addb2__context *ctx, const struct m0_addb2_value *val)
Definition: dump.c:1489
struct m0_sm_conf m0_dtx_sm_conf
Definition: dtx.c:82
int(* m0_addb2__intrp_load_t)(uint64_t flags, struct m0_addb2__id_intrp **intrp)
static void rpcop(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:639
static void fop_counter(struct m0_addb2__context *ctx, char *buf)
Definition: dump.c:791
struct m0_addb2__id_intrp ids[]
Definition: dump.c:1074
static struct fdmi_ctx ctx
Definition: main.c:80
#define FID_P(f)
Definition: fid.h:77
uint64_t m0_time_seconds(const m0_time_t time)
Definition: time.c:83
const char * m0_xcode_enum_print(const struct m0_xcode_enum *en, uint64_t val, char *buf)
Definition: enum.c:51
int main(int argc, char **argv)
Test server for m0console.
Definition: dump.c:195
M0_INTERNAL struct m0_fop_type * m0_fop_type_find(uint32_t opcode)
Definition: fop.c:388
#define PRId64
Definition: types.h:57
const char * xev_name
Definition: enum.h:97
static int asymbol_cmp(const void *a0, const void *a1)
Definition: dump.c:1507
static void _clock(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:481
M0_INTERNAL void m0_sns_cm_repair_sw_onwire_fop_init(void)
Definition: sw_onwire_fop.c:63
static void indent(int depth)
Definition: gen.c:43
#define DOM
Definition: dump.c:165
M0_INTERNAL int m0_stob_create(struct m0_stob *stob, struct m0_dtx *dtx, const char *str_cfg)
Definition: stob.c:154
struct m0_fid sd_id
Definition: domain.h:96
static void val_dump(struct m0_addb2__context *ctx, const char *prefix, const struct m0_addb2_value *val, int indent, bool cr)
Definition: dump.c:1479
M0_INTERNAL int m0_stob_destroy(struct m0_stob *stob, struct m0_dtx *dtx)
Definition: stob.c:200
M0_INTERNAL void m0_sns_cm_rebalance_trigger_fop_fini(void)
Definition: trigger_fop.c:42
M0_INTERNAL enum m0_stob_state m0_stob_state_get(struct m0_stob *stob)
Definition: stob.c:265
static int plugin_load(struct plugin *plugin)
Definition: dump.c:289
static void misc_init(void)
Definition: dump.c:1611
static asymbol ** syms
Definition: dump.c:1503
M0_INTERNAL void m0_varr_fini(struct m0_varr *arr)
Definition: varr.c:486
static void stob_io_req_state(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:940
M0_INTERNAL int m0_stob_domain_init(const char *location, const char *str_cfg_init, struct m0_stob_domain **out)
Definition: domain.c:195
static void libbfd_init(const char *libpath)
Definition: dump.c:1518
#define M0_ADDB2__PLUGIN_FUNC_NAME
Definition: fid.h:38
M0_INTERNAL int m0_stob_domain_create_or_init(const char *location, const char *str_cfg_init, uint64_t dom_key, const char *str_cfg_create, struct m0_stob_domain **out)
Definition: domain.c:262
int m0_addb2_sit_next(struct m0_addb2_sit *it, struct m0_addb2_record **out)
Definition: sit.c:148
static struct m0_sm_trans_descr trans[]
Definition: stats_fom.c:47
struct m0_addb2_value ar_val
Definition: consumer.h:114
static struct plugin plugins[PLUGINS_MAX]
Definition: dump.c:126
const uint64_t * va_data
Definition: consumer.h:106
static void dtx0_state(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:848
void m0_dix_cm_rebalance_cpx_init(void)
static void flate(void)
Definition: dump.c:1596
uint64_t fo_addr
Definition: dump.c:105
#define TIMED
Definition: dump.c:1069
const struct m0_sm_conf outgoing_item_sm_conf
Definition: item.c:59
#define PRId32
Definition: types.h:65
static void op_state(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:872
struct m0_fom_type * m0_fom__types[M0_OPCODES_NR]
Definition: fom.c:1594
static size_t plugins_nr
Definition: dump.c:127
static void libbfd_resolve(uint64_t delta, char *buf)
Definition: dump.c:1549
static void file_dump(struct m0_stob_domain *dom, const char *fname, const uint64_t start_time, const uint64_t stop_time)
Definition: dump.c:356
struct m0_sm_conf ft_conf
Definition: fom.h:615
uint64_t cod_datum
Definition: counter.h:46
static int start(struct m0_fom *fom)
Definition: trigger_fom.c:321
Definition: helper.h:53
struct m0_rpc_item_type ft_rpc_item_type
Definition: fop.h:235
static struct m0 instance
Definition: main.c:78
static void plugins_unload(void)
Definition: dump.c:337
static void oct(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:431
static void bol(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:449
M0_INTERNAL int m0_stob_find(const struct m0_stob_id *id, struct m0_stob **out)
Definition: stob.c:92
static void skip(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:465
#define M0_ASSERT_INFO(cond, fmt,...)
static void fom_state(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:584
static void fom_type(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:516
static bool deflatten
Definition: dump.c:170
const char * ii_field[M0_ADDB2__FIELD_MAX]
uint64_t fo_tid
Definition: dump.c:106
static void fid(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:454
static uint64_t base
Definition: dump.c:1504
struct m0_tlink fo_linkage
Definition: dump.c:104
static void sm_trans(const struct m0_sm_conf *conf, const char *name, struct m0_addb2__context *ctx, char *buf)
Definition: dump.c:762
Definition: nucleus.c:42
M0_INTERNAL uint64_t m0_pid(void)
Definition: kthread.c:290
static void cob_req_state(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:919
static void ioo_state_counter(struct m0_addb2__context *ctx, char *buf)
Definition: dump.c:914
Definition: varr.h:121
const char * td_cause
Definition: sm.h:487
static void dix_op_state(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:884
static void cas_state_counter(struct m0_addb2__context *ctx, char *buf)
Definition: dump.c:902
void m0_free(void *data)
Definition: memory.c:146
static struct m0_addb2_source * s
Definition: consumer.c:39
M0_INTERNAL void m0_sns_cm_repair_trigger_fop_fini(void)
Definition: trigger_fop.c:43
int32_t rc
Definition: trigger_fop.h:47
static void state_counter(struct m0_addb2__context *ctx, char *buf)
Definition: dump.c:878
#define ARRAY_SIZE(a)
Definition: misc.h:45
static int plugins_load(void)
Definition: dump.c:320
#define BEND
static void hbar(char *buf, uint32_t val, uint32_t m)
Definition: dump.c:718
struct m0_sm_conf m0_op_conf
Definition: client.c:145
static void dec(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:408
struct m0_sm_conf ft_state_conf
Definition: fom.h:616
uint64_t fo_magix
Definition: dump.c:108
static void deflate(void)
Definition: dump.c:1585
#define FID_F
Definition: fid.h:75
M0_INTERNAL void * m0_varr_ele_get(struct m0_varr *arr, uint64_t index)
Definition: varr.c:505
Definition: hist.py:1
static void hex(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:413
#define M0_IMPOSSIBLE(fmt,...)
void m0_addb2_sit_fini(struct m0_addb2_sit *it)
Definition: sit.c:139
static bool flatten
Definition: dump.c:169