71 localtime_r(&ts, &tm);
76 warn(
"failed to read CWD path, using relative path for" 88 "m0trace.%u.%04d-%02d-%02d-%02d:%02d:%02d",
90 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
92 warn(
"failed to construct trace file path");
95 if (
rc >= available_bytes) {
96 warnx(
"failed to construct trace file path, not enough" 97 " space in the path buffer");
104 }
else if ((errno = posix_fallocate(
logfd, 0, trace_area_size)) != 0) {
106 }
else if ((trace_area = mmap(
NULL, trace_area_size, PROT_WRITE,
107 MAP_SHARED,
logfd, 0)) == MAP_FAILED)
113 memset(trace_area, 0, trace_area_size);
138 if (errno != 0 || *endp != 0) {
177 " been initialized\n");
183 " parameter (%zu), it can't be zero, should be a power of" 184 " 2 and a multiple of PAGE_SIZE(%u)\n",
202 localtime_r(&ts, &tm);
205 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
207 warn(
"ignoring environment variable M0_TRACE_DIR - failed" 208 " to construct 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" 230 var = getenv(
"M0_TRACE_IMMEDIATE_MASK");
235 var = getenv(
"M0_TRACE_LEVEL");
240 var = getenv(
"M0_TRACE_PRINT_CONTEXT");
245 var = getenv(
"M0_TRACE_DIR");
247 if (
rc != 0 &&
rc != -EINVAL)
265 munmap(old_buffer, old_buffer_size);
278 #define CMDLINE "/proc/self/cmdline" 279 cmdline_fd = open(
CMDLINE, O_RDONLY);
280 if (cmdline_fd == -1)
285 if (read_bytes == -1) {
286 warn(
"motr: failed to read " CMDLINE);
289 warnx(
"motr: command line args don't fit into trace " 290 "buffer, truncating after %zu bytes", read_bytes);
296 for (
i = 0;
i < read_bytes - 1; ++
i)
301 rc = close(cmdline_fd);
303 warn(
"motr: failed to close " CMDLINE ": errno=%d", errno);
315 while (!feof(
file) && (pos & (
align - 1))) {
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);
339 warnx(
"invalid trace header MAGIC value\n");
344 warnx(
"trace header has different size: expected=%u, actual=%u",
359 bool need_comma =
false;
361 fprintf(ofile,
"header:\n");
367 rc = putenv(
"TZ=UTC0");
369 warn(
"failed to set timezone to UTC\n");
372 ptm = localtime_r(&time, &tm);
374 time_str_len = strftime(time_str,
sizeof time_str,
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);
381 fprintf(stderr,
"incorrect timestamp value in trace header\n");
382 fprintf(ofile,
" trace_time: ''\n");
385 fprintf(ofile,
" buffer_type: %s\n",
390 fprintf(ofile,
" flags: [ ");
393 fprintf(ofile,
"DIRTY");
397 fprintf(ofile,
", ");
398 fprintf(ofile,
"MKFS");
400 fprintf(ofile,
" ]\n");
404 fprintf(ofile,
" buffer_addr: %p\n", tbh->
tbh_buf_addr);
405 fprintf(ofile,
" buffer_size: %" PRId64 "\t\t# bytes\n",
409 fprintf(ofile,
" mod_struct_addr: %p\n",
411 fprintf(ofile,
" mod_core_addr: %p\n",
413 fprintf(ofile,
" mod_core_size: %u\t\t# bytes\n",
426 kofd = open(m0tr_ko_path, O_RDONLY);
428 warn(
"failed to open '%s' file", m0tr_ko_path);
432 rc = fstat(kofd, &ko_stat);
434 warn(
"failed to get stat info for '%s' file",
439 *ko_addr = mmap(
NULL, ko_stat.st_size, PROT_READ, MAP_PRIVATE,
441 if (*ko_addr == MAP_FAILED) {
442 warn(
"failed to mmap '%s' file", m0tr_ko_path);
450 const char *m0tr_ko_path,
451 ptrdiff_t *td_offset)
459 off_t msym_file_offset;
469 msym = (uint64_t*)((
char*)ko_addr + msym_file_offset);
471 warnx(
"invalid trace magic symbol value in '%s' file at" 474 m0tr_ko_path, msym_file_offset, *msym,
488 const void *magic_symbols[],
489 size_t nr, ptrdiff_t td_offsets[])
495 warnx(
"There are only %u additional magic symbols" 496 " stored in trace log, but %zu were provided to" 503 for (
i = 0;
i <
nr; ++
i)
504 td_offsets[
i] = (
char*)magic_symbols[
i] -
507 warnx(
"Cannot use additional magic symbols information with" 508 " kernel mode trace log");
539 const char *m0tr_ko_path,
541 const void *magic_symbols[],
542 unsigned int magic_symbols_nr)
555 size_t invalid_td_count = 0;
559 static char yaml_buf[256 * 1024];
562 size_t td_offsets_nr =
578 if (magic_symbols !=
NULL) {
580 td_offsets_nr - 1, &td_offsets[1]);
587 warnx(
"Using only first %u magic symbol offsets" 588 " out of %u provided to m0_trace_parse()",
590 }
else if (magic_symbols_nr > 0) {
591 warnx(
"Not using additional magic symbol addresses" 592 " - inconsistent parameters");
596 fprintf(output_file,
"trace_records:\n");
598 while (!feof(trace_file)) {
609 if (!feof(trace_file)) {
610 warnx(
"Got %zu bytes of magic instead" 615 if (invalid_td_count > 0)
616 warnx(
"Total number of unknown trace" 617 " records, that were skipped:" 618 " %zu", invalid_td_count);
627 nr = fread(&trh.
trh_sp, 1, n2r, trace_file);
629 warnx(
"Got %zu bytes of record (need %zu)",
nr, n2r);
634 for (
i = 0;
i < td_offsets_nr; ++
i) {
646 warnx(
"Skipping non-existing trace descriptor %p",
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");
669 warn(
"Failed to allocate %zu bytes of memory, looks like" 670 " a corrupted trace descriptor, skipping...",
size);
676 warnx(
"Got %zu bytes of data (need %zu)",
nr,
size);
684 fprintf(output_file,
"%s", yaml_buf);
685 else if (
rc == -ENOBUFS)
686 warnx(
"Internal buffer is too small to hold trace record");
688 warnx(
"Failed to process trace record data for %p" 710 vfprintf(stderr,
fmt, ap);
M0_INTERNAL bool m0_trace_use_mmapped_buffer(void)
M0_INTERNAL void m0_trace_buf_header_init(struct m0_trace_buf_header *tbh, size_t buf_size)
static void patch_trace_descr(struct m0_trace_descr *td, ptrdiff_t offset)
M0_INTERNAL uint32_t m0_trace_logbuf_size_get(void)
int const char const void size_t int flags
M0_INTERNAL int struct dentry struct kstat * stat
static struct m0_addb2_mach * m
void m0_error_printf(const char *fmt,...)
static unsigned align(FILE *file, uint64_t align, uint64_t pos)
M0_INTERNAL void m0_trace_logbuf_size_set(size_t size)
M0_INTERNAL const char * m0_trace_file_path_get(void)
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)
static bool m0_is_po2(uint64_t val)
static int set_trace_dir(const char *path)
void m0_console_vprintf(const char *fmt, va_list args)
struct m0_trace_buf_header ta_header
M0_INTERNAL int m0_pagesize_get(void)
static void print_trace_buf_header(FILE *ofile, const struct m0_trace_buf_header *tbh)
M0_INTERNAL void m0_arch_trace_fini(void)
M0_INTERNAL int m0_trace_subsys_list_to_mask(char *subsys_names, unsigned long *ret_mask)
M0_INTERNAL bool m0_addr_is_sane_and_aligned(const uint64_t *addr)
M0_INTERNAL void m0_trace_switch_to_static_logbuf(void)
static int mmap_m0tr_ko(const char *m0tr_ko_path, void **ko_addr)
M0_INTERNAL int m0_trace_set_print_context(const char *ctx_name)
M0_INTERNAL void m0_trace_stats_update(uint32_t rec_size)
m0_time_t m0_time_now(void)
#define M0_TRACE_UBUF_SIZE
char * fmt(const char *format,...) __attribute__((format(printf
void * m0_alloc(size_t size)
static const struct m0_trace_buf_header * read_trace_buf_header(FILE *trace_file)
static m0_bindex_t offset
static size_t trace_buf_size
uint64_t m0_time_seconds(const m0_time_t time)
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[])
void m0_console_flush(void)
static char trace_file_path[PATH_MAX]
M0_INTERNAL int m0_trace_set_immediate_mask(const char *mask_str)
int m0_trace_set_buffer_size(size_t size)
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)
unsigned long m0_trace_immediate_mask
M0_INTERNAL const void * m0_trace_magic_sym_addr_get(void)
M0_INTERNAL int m0_arch_trace_init()
M0_INTERNAL void m0_arch_trace_buf_header_init(struct m0_trace_buf_header *tbh)
struct m0_trace_buf_header * m0_logbuf_header
static struct m0_addb2_source * s
static int calc_trace_descr_offset(const struct m0_trace_buf_header *tbh, const char *m0tr_ko_path, ptrdiff_t *td_offset)
M0_INTERNAL void m0_trace_set_mmapped_buffer(bool val)
static uint64_t m0_align(uint64_t val, uint64_t alignment)
static bool use_mmaped_buffer
M0_INTERNAL int m0_trace_set_level(const char *level_str)