Motr  M0
utrace.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2011-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 #include <string.h> /* memset, strlen */
24 #include <errno.h>
25 #include <err.h> /* warn */
26 #include <sysexits.h> /* EX_* exit codes (EX_OSERR, EX_SOFTWARE) */
27 #include <stdio.h>
28 #include <stdlib.h> /* getenv, strtoul */
29 #include <unistd.h> /* getpagesize, getpid */
30 #include <fcntl.h> /* open, O_RDWR|O_CREAT|O_TRUNC */
31 #include <sys/mman.h> /* mmap */
32 #include <sys/stat.h> /* fstat */
33 #include <limits.h> /* CHAR_BIT */
34 #include <stddef.h> /* ptrdiff_t */
35 #include <time.h> /* strftime */
36 
37 #include "lib/types.h"
38 #include "lib/arith.h"
39 #include "lib/memory.h"
40 #include "lib/string.h" /* m0_strdup */
41 #include "lib/trace.h"
42 #include "lib/trace_internal.h"
43 #include "lib/cookie.h" /* m0_addr_is_sane_and_aligned */
44 
45 #include "motr/magic.h"
46 
56 
57 static int logfd;
58 static bool use_mmaped_buffer = true;
59 static char trace_file_path[PATH_MAX];
61 
62 static int logbuf_map()
63 {
64  struct m0_trace_area *trace_area;
65  size_t trace_area_size = M0_TRACE_BUF_HEADER_SIZE + trace_buf_size;
66  int rc;
67  m0_time_t stamp = m0_time_now();
68  time_t ts = m0_time_seconds(stamp);
69  struct tm tm;
70 
71  localtime_r(&ts, &tm);
72  M0_PRE((trace_area_size % m0_pagesize_get()) == 0);
73 
74  if (strlen(trace_file_path) == 0) {
75  if (getcwd(trace_file_path, sizeof trace_file_path) == NULL ) {
76  warn("failed to read CWD path, using relative path for"
77  " m0trace.PID file");
78  memset(trace_file_path, 0, sizeof trace_file_path);
79  } else {
80  strncat(trace_file_path, "/", sizeof trace_file_path -
81  strlen(trace_file_path) - 1);
82  }
83 
84  int available_bytes = sizeof trace_file_path -
85  strlen(trace_file_path);
86  rc = snprintf(trace_file_path + strlen(trace_file_path),
87  available_bytes,
88  "m0trace.%u.%04d-%02d-%02d-%02d:%02d:%02d",
89  m0_pid_cached, tm.tm_year + 1900,
90  tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
91  if (rc < 0) {
92  warn("failed to construct trace file path");
93  return rc;
94  }
95  if (rc >= available_bytes) {
96  warnx("failed to construct trace file path, not enough"
97  " space in the path buffer");
98  return -ENOBUFS;
99  }
100  }
101 
102  if ((logfd = open(trace_file_path, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0700)) == -1) {
103  warn("open(\"%s\")", trace_file_path);
104  } else if ((errno = posix_fallocate(logfd, 0, trace_area_size)) != 0) {
105  warn("fallocate(\"%s\", %zu)", trace_file_path, trace_area_size);
106  } else if ((trace_area = mmap(NULL, trace_area_size, PROT_WRITE,
107  MAP_SHARED, logfd, 0)) == MAP_FAILED)
108  {
109  warn("mmap(\"%s\")", trace_file_path);
110  } else {
111  m0_logbuf_header = &trace_area->ta_header;
112  m0_logbuf = trace_area->ta_buf;
113  memset(trace_area, 0, trace_area_size);
116  }
117 
118  return -errno;
119 }
120 
121 M0_INTERNAL const char *m0_trace_file_path_get(void)
122 {
123  return trace_file_path;
124 }
125 
126 M0_INTERNAL int m0_trace_set_immediate_mask(const char *mask)
127 {
128  if (mask != NULL) {
129  char *endp;
130 
131  m0_trace_immediate_mask = strtoul(mask, &endp, 0);
132 
133  /*
134  * if mask string fails to convert to a number cleanly, then
135  * assume that mask string contains a comma separated list of
136  * subsystem names, which we use to build a numeric mask
137  */
138  if (errno != 0 || *endp != 0) {
139  unsigned long m = 0;
140  int rc;
141  char *s = m0_strdup(mask);
142 
143  if (s == NULL)
144  return -ENOMEM;
145 
147  m0_free(s);
148 
149  if (rc != 0)
150  return rc;
151 
153  }
154  }
155 
156  return 0;
157 }
158 
159 M0_INTERNAL void m0_trace_stats_update(uint32_t rec_size)
160 {
161 }
162 
163 M0_INTERNAL void m0_trace_set_mmapped_buffer(bool val)
164 {
166 }
167 
168 M0_INTERNAL bool m0_trace_use_mmapped_buffer(void)
169 {
170  return use_mmaped_buffer;
171 }
172 
174 {
175  if (m0_pid_cached) {
176  m0_error_printf("motr: can't set trace buffer size after it's"
177  " been initialized\n");
178  return -EBUSY;
179  }
180 
181  if (size == 0 || !m0_is_po2(size) || size % m0_pagesize_get() != 0) {
182  m0_error_printf("motr: incorrect value for trace buffer size"
183  " parameter (%zu), it can't be zero, should be a power of"
184  " 2 and a multiple of PAGE_SIZE(%u)\n",
185  size, m0_pagesize_get());
186  return -EINVAL;
187  }
188 
190  return 0;
191 }
192 
193 static int set_trace_dir(const char *path)
194 {
195  int rc;
196  m0_time_t stamp = m0_time_now();
197  time_t ts = m0_time_seconds(stamp);
198  struct tm tm;
199 
200  if (path == NULL)
201  return 0;
202  localtime_r(&ts, &tm);
203  rc = snprintf(trace_file_path, sizeof trace_file_path, "%s/m0trace.%u.%04d-%02d-%02d-%02d:%02d:%02d",
204  path, m0_pid_cached, tm.tm_year + 1900,
205  tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
206  if (rc < 0) {
207  warn("ignoring environment variable M0_TRACE_DIR - failed"
208  " to construct trace file path");
209  memset(trace_file_path, 0, sizeof trace_file_path);
210  return rc;
211  }
212  if (rc >= sizeof trace_file_path) {
213  warnx("ignoring environment variable M0_TRACE_DIR - its content"
214  " is too long (%zu bytes), max allowed lengh is %zu bytes"
215  , strlen(path), (sizeof trace_file_path) - 16);
216  memset(trace_file_path, 0, sizeof trace_file_path);
217  return -EINVAL;
218  }
219 
220  return 0;
221 }
222 
223 M0_INTERNAL int m0_arch_trace_init()
224 {
225  int rc;
226  const char *var;
227 
228  m0_pid_cached = getpid();
229 
230  var = getenv("M0_TRACE_IMMEDIATE_MASK");
232  if (rc != 0)
233  return rc;
234 
235  var = getenv("M0_TRACE_LEVEL");
236  rc = m0_trace_set_level(var);
237  if (rc != 0)
238  return rc;
239 
240  var = getenv("M0_TRACE_PRINT_CONTEXT");
242  if (rc != 0)
243  return rc;
244 
245  var = getenv("M0_TRACE_DIR");
246  rc = set_trace_dir(var);
247  if (rc != 0 && rc != -EINVAL)
248  return rc;
249 
250  setlinebuf(stdout);
251  return m0_trace_use_mmapped_buffer() ? logbuf_map() : 0;
252 }
253 
254 M0_INTERNAL void m0_arch_trace_fini(void)
255 {
256  void *old_buffer = m0_logbuf_header;
257  uint32_t old_buffer_size = M0_TRACE_BUF_HEADER_SIZE +
259 
261 
263 
265  munmap(old_buffer, old_buffer_size);
266  close(logfd);
267 }
268 
269 M0_INTERNAL void m0_arch_trace_buf_header_init(struct m0_trace_buf_header *tbh)
270 {
271  int i;
272  int rc;
273  int cmdline_fd;
274  ssize_t read_bytes;
275 
277 
278 #define CMDLINE "/proc/self/cmdline"
279  cmdline_fd = open(CMDLINE, O_RDONLY);
280  if (cmdline_fd == -1)
281  return;
282 
283  read_bytes = read(cmdline_fd, tbh->tbh_cli_args,
284  sizeof(tbh->tbh_cli_args));
285  if (read_bytes == -1) {
286  warn("motr: failed to read " CMDLINE);
287  } else {
288  if (read_bytes == sizeof(tbh->tbh_cli_args)) {
289  warnx("motr: command line args don't fit into trace "
290  "buffer, truncating after %zu bytes", read_bytes);
291  tbh->tbh_cli_args[read_bytes - 1] = '\0';
292  } else {
293  tbh->tbh_cli_args[read_bytes] = '\0';
294  }
295  /* cli args are separated with '\0', replace it with spaces */
296  for (i = 0; i < read_bytes - 1; ++i)
297  if (tbh->tbh_cli_args[i] == '\0')
298  tbh->tbh_cli_args[i] = ' ';
299  }
300 
301  rc = close(cmdline_fd);
302  if (rc == -1)
303  warn("motr: failed to close " CMDLINE ": errno=%d", errno);
304 #undef CMDLINE
305 
306  if (strstr(tbh->tbh_cli_args, "m0mkfs") != NULL)
308 
310 }
311 
312 static unsigned align(FILE *file, uint64_t align, uint64_t pos)
313 {
315  while (!feof(file) && (pos & (align - 1))) {
316  fgetc(file);
317  pos++;
318  }
319  return pos;
320 }
321 
322 static const struct m0_trace_buf_header *read_trace_buf_header(FILE *trace_file)
323 {
324  const struct m0_trace_buf_header *tb_header;
325 
326  static char buf[M0_TRACE_BUF_HEADER_SIZE];
327  size_t n;
328 
329  n = fread(buf, 1, sizeof buf, trace_file);
330  if (n != sizeof buf) {
331  warnx("failed to read trace header (got %zu bytes instead of"
332  " %zu bytes)\n", n, sizeof buf);
333  return NULL;
334  }
335 
336  tb_header = (const struct m0_trace_buf_header *)buf;
337 
338  if (tb_header->tbh_magic != M0_TRACE_BUF_HEADER_MAGIC) {
339  warnx("invalid trace header MAGIC value\n");
340  return NULL;
341  }
342 
343  if (tb_header->tbh_header_size != M0_TRACE_BUF_HEADER_SIZE)
344  warnx("trace header has different size: expected=%u, actual=%u",
346 
347  return tb_header;
348 }
349 
350 static void print_trace_buf_header(FILE *ofile,
351  const struct m0_trace_buf_header *tbh)
352 {
353  int rc;
354  struct tm tm;
355  struct tm *ptm;
356  char time_str[512];
357  size_t time_str_len;
358  time_t time;
359  bool need_comma = false;
360 
361  fprintf(ofile, "header:\n");
362 
363  fprintf(ofile, " motr_version: %s\n", tbh->tbh_motr_version);
364  fprintf(ofile, " motr_git_describe: %s\n", tbh->tbh_motr_git_describe);
365  fprintf(ofile, " motr_kernel: %s\n", tbh->tbh_motr_kernel_ver);
366 
367  rc = putenv("TZ=UTC0");
368  if (rc != 0)
369  warn("failed to set timezone to UTC\n");
370 
371  time = m0_time_seconds(tbh->tbh_log_time);
372  ptm = localtime_r(&time, &tm);
373  if (ptm != NULL) {
374  time_str_len = strftime(time_str, sizeof time_str,
375  "%FT%T%z", &tm);
376  /*"%b %e %H:%M:%S %Z %Y", &tm);*/
377  if (time_str_len == 0)
378  fprintf(stderr, " failed to format trace file timestamp\n");
379  fprintf(ofile, " trace_time: %s\n", time_str);
380  } else {
381  fprintf(stderr, "incorrect timestamp value in trace header\n");
382  fprintf(ofile, " trace_time: ''\n");
383  }
384 
385  fprintf(ofile, " buffer_type: %s\n",
386  tbh->tbh_buf_type == M0_TRACE_BUF_KERNEL ? "KERNEL" :
387  tbh->tbh_buf_type == M0_TRACE_BUF_USER ? "USER" :
388  "UNKNOWN"
389  );
390  fprintf(ofile, " flags: [ ");
391  if (tbh->tbh_buf_flags & M0_TRACE_BUF_DIRTY) {
392  need_comma = true;
393  fprintf(ofile, "DIRTY");
394  }
395  if (tbh->tbh_buf_flags & M0_TRACE_BUF_MKFS) {
396  if (need_comma)
397  fprintf(ofile, ", ");
398  fprintf(ofile, "MKFS");
399  }
400  fprintf(ofile, " ]\n");
401 
402  fprintf(ofile, " header_addr: %p\n", tbh->tbh_header_addr);
403  fprintf(ofile, " header_size: %u\t\t# bytes\n", tbh->tbh_header_size);
404  fprintf(ofile, " buffer_addr: %p\n", tbh->tbh_buf_addr);
405  fprintf(ofile, " buffer_size: %" PRId64 "\t\t# bytes\n",
406  tbh->tbh_buf_size);
407 
408  if (tbh->tbh_buf_type == M0_TRACE_BUF_KERNEL) {
409  fprintf(ofile, " mod_struct_addr: %p\n",
410  tbh->tbh_module_struct);
411  fprintf(ofile, " mod_core_addr: %p\n",
412  tbh->tbh_module_core_addr);
413  fprintf(ofile, " mod_core_size: %u\t\t# bytes\n",
414  tbh->tbh_module_core_size);
415  }
416 
417  fprintf(ofile, " cli_args: '%s'\n", tbh->tbh_cli_args);
418 }
419 
420 static int mmap_m0tr_ko(const char *m0tr_ko_path, void **ko_addr)
421 {
422  int rc;
423  int kofd;
424  struct stat ko_stat;
425 
426  kofd = open(m0tr_ko_path, O_RDONLY);
427  if (kofd == -1) {
428  warn("failed to open '%s' file", m0tr_ko_path);
429  return EX_NOINPUT;
430  }
431 
432  rc = fstat(kofd, &ko_stat);
433  if (rc != 0) {
434  warn("failed to get stat info for '%s' file",
435  m0tr_ko_path);
436  return EX_OSERR;
437  }
438 
439  *ko_addr = mmap(NULL, ko_stat.st_size, PROT_READ, MAP_PRIVATE,
440  kofd, 0);
441  if (*ko_addr == MAP_FAILED) {
442  warn("failed to mmap '%s' file", m0tr_ko_path);
443  return EX_OSERR;
444  }
445 
446  return 0;
447 }
448 
449 static int calc_trace_descr_offset(const struct m0_trace_buf_header *tbh,
450  const char *m0tr_ko_path,
451  ptrdiff_t *td_offset)
452 {
453  if (tbh->tbh_buf_type == M0_TRACE_BUF_USER) {
454  *td_offset = (char*)m0_trace_magic_sym_addr_get() -
455  (char*)tbh->tbh_magic_sym_addr;
456  } else if (tbh->tbh_buf_type == M0_TRACE_BUF_KERNEL) {
457  int rc;
458  void *ko_addr;
459  off_t msym_file_offset;
460  uint64_t *msym;
461 
462  msym_file_offset = (char*)tbh->tbh_magic_sym_addr -
463  (char*)tbh->tbh_module_core_addr;
464 
465  rc = mmap_m0tr_ko(m0tr_ko_path, &ko_addr);
466  if (rc != 0)
467  return rc;
468 
469  msym = (uint64_t*)((char*)ko_addr + msym_file_offset);
470  if (*msym != M0_TRACE_MAGIC) {
471  warnx("invalid trace magic symbol value in '%s' file at"
472  " offset 0x%" PRIx64 ": 0x%"PRIx64
473  " (expected 0x%lx)",
474  m0tr_ko_path, msym_file_offset, *msym,
476  return EX_DATAERR;
477  }
478 
479  *td_offset = (char*)msym - (char*)tbh->tbh_magic_sym_addr;
480  } else {
481  return EX_DATAERR;
482  }
483 
484  return 0;
485 }
486 
488  const void *magic_symbols[],
489  size_t nr, ptrdiff_t td_offsets[])
490 {
491  int i;
492 
493  if (tbh->tbh_buf_type == M0_TRACE_BUF_USER) {
494  if (tbh->tbh_magic_sym_addresses_nr < nr) {
495  warnx("There are only %u additional magic symbols"
496  " stored in trace log, but %zu were provided to"
497  " m0_trace_parse()",
500  }
501  if (nr == 0)
502  return -ENODATA;
503  for (i = 0; i < nr; ++i)
504  td_offsets[i] = (char*)magic_symbols[i] -
505  (char*)tbh->tbh_magic_sym_addresses[i];
506  } else {
507  warnx("Cannot use additional magic symbols information with"
508  " kernel mode trace log");
509  return -EOPNOTSUPP;
510  }
511 
512  return 0;
513 }
514 
515 static void patch_trace_descr(struct m0_trace_descr *td, ptrdiff_t offset)
516 {
517  td->td_fmt = (char*)td->td_fmt + offset;
518  td->td_func = (char*)td->td_func + offset;
519  td->td_file = (char*)td->td_file + offset;
520  td->td_offset = (typeof (td->td_offset))((char*)td->td_offset + offset);
521  td->td_sizeof = (typeof (td->td_sizeof))((char*)td->td_sizeof + offset);
522  td->td_isstr = (typeof (td->td_isstr))((char*)td->td_isstr + offset);
523 }
524 
525 enum {
527  ((struct m0_trace_buf_header *)0)->tbh_magic_sym_addresses)
528 };
529 
538 M0_INTERNAL int m0_trace_parse(FILE *trace_file, FILE *output_file,
539  const char *m0tr_ko_path,
541  const void *magic_symbols[],
542  unsigned int magic_symbols_nr)
543 {
544  const struct m0_trace_buf_header *tbh;
545  struct m0_trace_rec_header trh;
546  struct m0_trace_descr *td;
547  struct m0_trace_descr patched_td;
548 
549  int rc;
550  int i;
551  size_t pos = 0;
552  size_t nr;
553  size_t n2r;
554  size_t size;
555  size_t invalid_td_count = 0;
556  bool td_is_sane;
557  char *buf;
558 
559  static char yaml_buf[256 * 1024]; /* 256 KB */
560  ptrdiff_t *td_offset;
561  ptrdiff_t td_offsets[MAGIC_SYM_OFFSETS_MAX + 1] = { 0 };
562  size_t td_offsets_nr =
563  (magic_symbols_nr < MAGIC_SYM_OFFSETS_MAX ?
564  magic_symbols_nr : MAGIC_SYM_OFFSETS_MAX) + 1;
565 
566  tbh = read_trace_buf_header(trace_file);
567  if (tbh == NULL)
568  return EX_DATAERR;
569 
570  print_trace_buf_header(output_file, tbh);
572  return 0;
573 
574  rc = calc_trace_descr_offset(tbh, m0tr_ko_path, &td_offsets[0]);
575  if (rc != 0)
576  return rc;
577 
578  if (magic_symbols != NULL) {
579  rc = calc_extra_trace_descr_offsets(tbh, magic_symbols,
580  td_offsets_nr - 1, &td_offsets[1]);
581  if (rc != 0)
582  /* something's not good with the additional magic
583  * symbols information, using only internal (libmotr)
584  * magic symbol */
585  td_offsets_nr = 1;
586  else if (magic_symbols_nr > MAGIC_SYM_OFFSETS_MAX)
587  warnx("Using only first %u magic symbol offsets"
588  " out of %u provided to m0_trace_parse()",
589  MAGIC_SYM_OFFSETS_MAX, magic_symbols_nr);
590  } else if (magic_symbols_nr > 0) {
591  warnx("Not using additional magic symbol addresses"
592  " - inconsistent parameters");
593  }
594 
596  fprintf(output_file, "trace_records:\n");
597 
598  while (!feof(trace_file)) {
599 
600  /* At the beginning of a record */
601  pos = align(trace_file, M0_TRACE_REC_ALIGN, pos);
602 
603  /* Find the complete record */
604  do {
605  nr = fread(&trh.trh_magic, 1,
606  sizeof trh.trh_magic, trace_file);
607 
608  if (nr != sizeof trh.trh_magic) {
609  if (!feof(trace_file)) {
610  warnx("Got %zu bytes of magic instead"
611  " of %zu", nr,
612  sizeof trh.trh_magic);
613  return EX_DATAERR;
614  }
615  if (invalid_td_count > 0)
616  warnx("Total number of unknown trace"
617  " records, that were skipped:"
618  " %zu", invalid_td_count);
619  return EX_OK;
620  }
621 
622  pos += nr;
623  } while (trh.trh_magic != M0_TRACE_MAGIC);
624 
625  /* Now we might have complete record */
626  n2r = sizeof trh - sizeof trh.trh_magic;
627  nr = fread(&trh.trh_sp, 1, n2r, trace_file);
628  if (nr != n2r) {
629  warnx("Got %zu bytes of record (need %zu)", nr, n2r);
630  return EX_DATAERR;
631  }
632  pos += nr;
633 
634  for (i = 0; i < td_offsets_nr; ++i) {
635  td_offset = &td_offsets[i];
636  td = (struct m0_trace_descr*)((char*)trh.trh_descr +
637  *td_offset);
638  td_is_sane =
639  m0_addr_is_sane_and_aligned((const uint64_t *)td);
640  if (td_is_sane && td->td_magic == M0_TRACE_DESCR_MAGIC)
641  break;
642 
643  }
644 
645  if (!td_is_sane) {
646  warnx("Skipping non-existing trace descriptor %p",
647  trh.trh_descr);
648  continue;
649  }
650 
651  if (td->td_magic != M0_TRACE_DESCR_MAGIC) {
652  if (invalid_td_count == 0)
653  warnx("Invalid trace descriptor - most probably"
654  "the trace file was produced by a"
655  "different version of Motr");
656  ++invalid_td_count;
657  continue;
658  }
659 
660  patched_td = *td;
661  if (tbh->tbh_buf_type == M0_TRACE_BUF_KERNEL)
662  patch_trace_descr(&patched_td, *td_offset);
663  trh.trh_descr = &patched_td;
666 
667  buf = m0_alloc(size);
668  if (buf == NULL) {
669  warn("Failed to allocate %zu bytes of memory, looks like"
670  " a corrupted trace descriptor, skipping...", size);
671  continue;
672  }
673 
674  nr = fread(buf, 1, size, trace_file);
675  if (nr != size) {
676  warnx("Got %zu bytes of data (need %zu)", nr, size);
677  return EX_DATAERR;
678  }
679  pos += nr;
680 
681  rc = m0_trace_record_print_yaml(yaml_buf, sizeof yaml_buf, &trh,
683  if (rc == 0)
684  fprintf(output_file, "%s", yaml_buf);
685  else if (rc == -ENOBUFS)
686  warnx("Internal buffer is too small to hold trace record");
687  else
688  warnx("Failed to process trace record data for %p"
689  " descriptor", trh.trh_descr);
690  m0_free(buf);
691  }
692  return EX_OK;
693 }
694 
695 M0_INTERNAL void m0_console_vprintf(const char *fmt, va_list args)
696 {
697  vprintf(fmt, args);
698 }
699 
700 void m0_console_flush(void)
701 {
702  fflush(stdout);
703 }
704 
705 void m0_error_printf(const char *fmt, ...)
706 {
707  va_list ap;
708 
709  va_start(ap, fmt);
710  vfprintf(stderr, fmt, ap);
711  va_end(ap);
712 }
713 
716 /*
717  * Local variables:
718  * c-indentation-style: "K&R"
719  * c-basic-offset: 8
720  * tab-width: 8
721  * fill-column: 80
722  * scroll-step: 1
723  * End:
724  */
M0_INTERNAL bool m0_trace_use_mmapped_buffer(void)
Definition: utrace.c:168
M0_INTERNAL void m0_trace_buf_header_init(struct m0_trace_buf_header *tbh, size_t buf_size)
Definition: trace.c:956
static void patch_trace_descr(struct m0_trace_descr *td, ptrdiff_t offset)
Definition: utrace.c:515
static size_t nr
Definition: dump.c:1505
#define M0_PRE(cond)
#define m0_strdup(s)
Definition: string.h:43
M0_INTERNAL uint32_t m0_trace_logbuf_size_get(void)
Definition: trace.c:624
int const char const void size_t int flags
Definition: dir.c:328
M0_INTERNAL int struct dentry struct kstat * stat
Definition: dir.c:1433
#define NULL
Definition: misc.h:38
static struct m0_addb2_mach * m
Definition: consumer.c:38
Definition: idx_mock.c:52
void m0_error_printf(const char *fmt,...)
Definition: ktrace.c:169
static unsigned align(FILE *file, uint64_t align, uint64_t pos)
Definition: utrace.c:312
struct m0_file file
Definition: di.c:36
uint64_t m0_time_t
Definition: time.h:37
M0_INTERNAL void m0_trace_logbuf_size_set(size_t size)
Definition: trace.c:630
uint64_t tbh_buf_size
Definition: trace.h:376
M0_INTERNAL const char * m0_trace_file_path_get(void)
Definition: ktrace.c:72
M0_INTERNAL int m0_trace_record_print_yaml(char *outbuf, size_t outbuf_size, const struct m0_trace_rec_header *trh, const void *tr_body, bool yaml_stream_mode)
Definition: trace.c:836
const bool * td_isstr
Definition: trace.h:516
static bool m0_is_po2(uint64_t val)
Definition: arith.h:153
const int * td_offset
Definition: trace.h:514
void * m0_logbuf
Definition: trace.c:86
const void * tbh_header_addr
Definition: trace.h:365
static int set_trace_dir(const char *path)
Definition: utrace.c:193
char tbh_motr_version[16]
Definition: trace.h:394
void m0_console_vprintf(const char *fmt, va_list args)
Definition: ktrace.c:160
uint16_t tbh_buf_flags
Definition: trace.h:380
static int void * buf
Definition: dir.c:1019
Definition: ub.c:49
uint16_t tbh_magic_sym_addresses_nr
Definition: trace.h:417
m0_trace_parse_flags
Definition: trace.h:41
struct m0_trace_buf_header ta_header
#define PRIx64
Definition: types.h:61
Definition: sock.c:887
uint64_t td_magic
Definition: trace.h:506
M0_INTERNAL int m0_pagesize_get(void)
Definition: memory.c:233
static void print_trace_buf_header(FILE *ofile, const struct m0_trace_buf_header *tbh)
Definition: utrace.c:350
char tbh_motr_kernel_ver[128]
Definition: trace.h:398
const char * td_func
Definition: trace.h:508
int i
Definition: dir.c:1033
M0_INTERNAL void m0_arch_trace_fini(void)
Definition: ktrace.c:225
unsigned int tbh_module_core_size
Definition: trace.h:409
const void * tbh_module_struct
Definition: trace.h:402
uint64_t trh_sp
Definition: trace.h:441
M0_INTERNAL int m0_trace_subsys_list_to_mask(char *subsys_names, unsigned long *ret_mask)
Definition: trace.c:414
uint32_t trh_string_data_size
Definition: trace.h:446
M0_INTERNAL void m0_trace_switch_to_static_logbuf(void)
Definition: trace.c:986
#define M0_ASSERT(cond)
static int mmap_m0tr_ko(const char *m0tr_ko_path, void **ko_addr)
Definition: utrace.c:420
M0_INTERNAL int m0_trace_set_print_context(const char *ctx_name)
Definition: trace.c:562
M0_INTERNAL void m0_trace_stats_update(uint32_t rec_size)
Definition: ktrace.c:119
char tbh_motr_git_describe[64]
Definition: trace.h:396
m0_time_t m0_time_now(void)
Definition: time.c:134
#define M0_TRACE_UBUF_SIZE
Definition: config.h:296
char * fmt(const char *format,...) __attribute__((format(printf
void * m0_alloc(size_t size)
Definition: memory.c:126
const void * tbh_magic_sym_addresses[128]
Definition: trace.h:419
static const struct m0_trace_buf_header * read_trace_buf_header(FILE *trace_file)
Definition: utrace.c:322
const char * td_fmt
Definition: trace.h:507
pid_t m0_pid_cached
Definition: utrace.c:55
static m0_bindex_t offset
Definition: dump.c:173
uint64_t tbh_magic
Definition: trace.h:363
char tbh_cli_args[1024]
Definition: trace.h:411
static size_t trace_buf_size
Definition: utrace.c:60
uint64_t m0_time_seconds(const m0_time_t time)
Definition: time.c:83
#define PRId64
Definition: types.h:57
const char * td_file
Definition: trace.h:509
static int calc_extra_trace_descr_offsets(const struct m0_trace_buf_header *tbh, const void *magic_symbols[], size_t nr, ptrdiff_t td_offsets[])
Definition: utrace.c:487
uint64_t n
Definition: fops.h:107
const void * tbh_buf_addr
Definition: trace.h:374
const void * tbh_module_core_addr
Definition: trace.h:407
void m0_console_flush(void)
Definition: ktrace.c:165
uint32_t tbh_header_size
Definition: trace.h:372
const void * tbh_magic_sym_addr
Definition: trace.h:392
int td_size
Definition: trace.h:512
static char trace_file_path[PATH_MAX]
Definition: utrace.c:59
M0_INTERNAL int m0_trace_set_immediate_mask(const char *mask_str)
Definition: ktrace.c:77
int m0_trace_set_buffer_size(size_t size)
Definition: utrace.c:173
m0_bcount_t size
Definition: di.c:39
static int logfd
Definition: utrace.c:57
const int * td_sizeof
Definition: trace.h:515
#define CMDLINE
M0_INTERNAL int m0_trace_parse(FILE *trace_file, FILE *output_file, const char *m0tr_ko_path, enum m0_trace_parse_flags flags, const void *magic_symbols[], unsigned int magic_symbols_nr)
Definition: utrace.c:538
const struct m0_trace_descr * trh_descr
Definition: trace.h:445
unsigned long m0_trace_immediate_mask
Definition: trace.c:91
M0_INTERNAL const void * m0_trace_magic_sym_addr_get(void)
Definition: trace.c:644
M0_INTERNAL int m0_arch_trace_init()
Definition: ktrace.c:178
M0_INTERNAL void m0_arch_trace_buf_header_init(struct m0_trace_buf_header *tbh)
Definition: ktrace.c:233
struct m0_trace_buf_header * m0_logbuf_header
Definition: trace.c:85
uint64_t trh_magic
Definition: trace.h:440
void m0_free(void *data)
Definition: memory.c:146
static struct m0_addb2_source * s
Definition: consumer.c:39
m0_time_t tbh_log_time
Definition: trace.h:400
static int calc_trace_descr_offset(const struct m0_trace_buf_header *tbh, const char *m0tr_ko_path, ptrdiff_t *td_offset)
Definition: utrace.c:449
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL void m0_trace_set_mmapped_buffer(bool val)
Definition: utrace.c:163
#define ARRAY_SIZE(a)
Definition: misc.h:45
static uint64_t m0_align(uint64_t val, uint64_t alignment)
Definition: arith.h:170
uint16_t tbh_buf_type
Definition: trace.h:378
static bool use_mmaped_buffer
Definition: utrace.c:58
static int logbuf_map()
Definition: utrace.c:62
M0_INTERNAL int m0_trace_set_level(const char *level_str)
Definition: trace.c:581