Motr  M0
trace_debugfs.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-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 #if 0
23 
24 #include <linux/kernel.h> /* pr_info */
25 #include <linux/debugfs.h> /* debugfs_create_dir */
26 #include <linux/module.h> /* THIS_MODULE */
27 #include <linux/uaccess.h> /* strncpy_from_user */
28 #include <linux/string.h> /* strncmp */
29 #include <linux/ctype.h> /* isprint */
30 #include <linux/delay.h> /* msleep */
31 #include <linux/mm.h>
32 #include <linux/vmalloc.h>
33 #include <linux/poll.h> /* poll_table */
34 #include <linux/version.h>
35 
36 #include "lib/mutex.h" /* m0_mutex */
37 #include "lib/time.h" /* m0_time_now */
38 #include "lib/misc.h" /* M0_SET_ARR0 */
39 #include "lib/trace.h"
40 #include "lib/trace_internal.h"
41 #include "lib/linux_kernel/trace.h"
44 
45 
52 static struct dentry *trc_dir;
53 static const char trc_dir_name[] = "trace";
54 
55 
56 typedef int (*trc_write_actor_t)(const char *level_str);
57 
58 static ssize_t trc_write_helper(struct file *file, const char __user *ubuf,
59  size_t ubuf_size, loff_t *ppos,
60  trc_write_actor_t actor)
61 {
62  int rc;
63  ssize_t ret_size = ubuf_size;
64  static char buf[256];
65 
66  if (ubuf_size > sizeof buf - 1)
67  return -EINVAL;
68 
69  if (strncpy_from_user(buf, ubuf, ubuf_size) < 0)
70  return -EFAULT;
71  buf[ubuf_size] = '\0';
72 
73  /*
74  * usually debugfs files are written with `echo` command which appends a
75  * newline character at the end of string, so we need to remove it if it
76  * present
77  */
78  if (buf[ubuf_size - 1] == '\n') {
79  buf[ubuf_size - 1] = 0;
80  ubuf_size--;
81  }
82 
83  pr_info(KBUILD_MODNAME ": %s (%s) command '%s'\n",
84  file->f_path.dentry->d_name.name,
85  file->f_path.dentry->d_iname,
86  buf);
87 
88  rc = actor(buf);
89  if (rc < 0)
90  return rc;
91 
92  /* ignore the rest of the buffer */
93  *ppos += ret_size;
94 
95  return ret_size;
96 }
97 
98 /******************************* immediate_mask *******************************/
99 
100 static bool trc_immediate_mask_is_opened = false;
101 
102 static int trc_immediate_mask_open(struct inode *i, struct file *f)
103 {
104  if (trc_immediate_mask_is_opened)
105  return -EBUSY;
106 
107  trc_immediate_mask_is_opened = true;
108 
109  return 0;
110 }
111 
112 static int trc_immediate_mask_release(struct inode *i, struct file *f)
113 {
114  trc_immediate_mask_is_opened = false;
115  return 0;
116 }
117 
118 static size_t buf_add(char *buf, size_t buf_size, size_t buf_used,
119  const char *fmt, ...)
120 {
121  size_t n = 0;
122  va_list args;
123 
124  va_start(args, fmt);
125  n += vsnprintf(buf + buf_used,
126  buf_used >= buf_size ? 0 : buf_size - buf_used,
127  fmt, args);
128  va_end(args);
129 
130  return n;
131 }
132 
133 static ssize_t trc_immediate_mask_read(struct file *file, char __user *ubuf,
134  size_t ubuf_size, loff_t *ppos)
135 {
136  int i;
137  ssize_t ret_size = 0;
138  uint64_t subsys;
139  const char *subsys_name;
140 
141  static char buf[4096];
142  size_t buf_used = 0;
143 
144  /* indicate EOF if we are not at the beginning of file */
145  if (*ppos != 0)
146  return 0;
147 
148  buf[0] = '\0';
149 
150  for (i = 0; i < sizeof m0_trace_immediate_mask * CHAR_BIT; ++i) {
151  subsys = m0_trace_immediate_mask & (1UL << i);
152  if (subsys != 0) {
153  subsys_name = m0_trace_subsys_name(subsys);
154  if (subsys_name == NULL)
155  continue;
156  buf_used += buf_add(buf, sizeof buf, buf_used,
157  "%s ", subsys_name);
158  if (buf_used >= sizeof buf) {
159  buf_used = sizeof buf - 2;
160  break;
161  }
162  }
163  }
164 
165  buf[buf_used++] = '\n';
166  buf[buf_used++] = '\0';
167  ret_size = min(ubuf_size, buf_used);
168 
169  return simple_read_from_buffer(ubuf, ubuf_size, ppos, buf, ret_size);
170 }
171 
172 static ssize_t trc_immediate_mask_write(struct file *file,
173  const char __user *ubuf,
174  size_t ubuf_size, loff_t *ppos)
175 {
176  return trc_write_helper(file, ubuf, ubuf_size, ppos,
178 }
179 
180 static const struct file_operations trc_immediate_mask_fops = {
181  .owner = THIS_MODULE,
182  .open = trc_immediate_mask_open,
183  .release = trc_immediate_mask_release,
184  .read = trc_immediate_mask_read,
185  .write = trc_immediate_mask_write,
186 };
187 
188 /******************************* level ****************************************/
189 
190 static bool trc_level_is_opened = false;
191 
192 static int trc_level_open(struct inode *i, struct file *f)
193 {
194  if (trc_level_is_opened)
195  return -EBUSY;
196 
197  trc_level_is_opened = true;
198 
199  return 0;
200 }
201 
202 static int trc_level_release(struct inode *i, struct file *f)
203 {
204  trc_level_is_opened = false;
205  return 0;
206 }
207 
208 static ssize_t trc_level_read(struct file *file, char __user *ubuf,
209  size_t ubuf_size, loff_t *ppos)
210 {
211  int i;
212  ssize_t ret_size = 0;
213  uint32_t level;
214  const char *level_name;
215 
216  static char buf[256];
217  size_t buf_used = 0;
218 
219  /* indicate EOF if we are not at the beginning of file */
220  if (*ppos != 0)
221  return 0;
222 
223  buf[0] = '\0';
224 
225  for (i = 0; i < sizeof m0_trace_level * CHAR_BIT; ++i) {
226  level = m0_trace_level & (1 << i);
227  if (level != M0_NONE) {
228  level_name = m0_trace_level_name(level);
229  buf_used += buf_add(buf, sizeof buf, buf_used,
230  "%s ", level_name);
231  if (buf_used >= sizeof buf) {
232  buf_used = sizeof buf - 2;
233  break;
234  }
235  }
236  }
237 
238  buf[buf_used++] = '\n';
239  buf[buf_used++] = '\0';
240  ret_size = min(ubuf_size, buf_used);
241 
242  return simple_read_from_buffer(ubuf, ubuf_size, ppos, buf, ret_size);
243 }
244 
245 static ssize_t trc_level_write(struct file *file, const char __user *ubuf,
246  size_t ubuf_size, loff_t *ppos)
247 {
248  return trc_write_helper(file, ubuf, ubuf_size, ppos, m0_trace_set_level);
249 }
250 
251 static const struct file_operations trc_level_fops = {
252  .owner = THIS_MODULE,
253  .open = trc_level_open,
254  .release = trc_level_release,
255  .read = trc_level_read,
256  .write = trc_level_write,
257 };
258 
259 /******************************* print_context ********************************/
260 
261 static bool trc_print_context_is_opened = false;
262 
263 static int trc_print_context_open(struct inode *i, struct file *f)
264 {
265  if (trc_print_context_is_opened)
266  return -EBUSY;
267 
268  trc_print_context_is_opened = true;
269 
270  return 0;
271 }
272 
273 static int trc_print_context_release(struct inode *i, struct file *f)
274 {
275  trc_print_context_is_opened = false;
276  return 0;
277 }
278 
279 static ssize_t trc_print_context_read(struct file *file, char __user *ubuf,
280  size_t ubuf_size, loff_t *ppos)
281 {
282  static char buf[16];
283  size_t ret_size;
284 
286  strncpy(buf, "func\n", sizeof buf);
288  strncpy(buf, "short\n", sizeof buf);
290  strncpy(buf, "full\n", sizeof buf);
292  strncpy(buf, "none\n", sizeof buf);
293  else
294  strncpy(buf, "INVALID\n", sizeof buf);
295 
296  ret_size = min(ubuf_size, strlen(buf) + 1);
297 
298  return simple_read_from_buffer(ubuf, ubuf_size, ppos, buf, ret_size);
299 }
300 
301 static ssize_t trc_print_context_write(struct file *file, const char __user *ubuf,
302  size_t ubuf_size, loff_t *ppos)
303 {
304  return trc_write_helper(file, ubuf, ubuf_size, ppos,
306 }
307 
308 static const struct file_operations trc_print_context_fops = {
309  .owner = THIS_MODULE,
310  .open = trc_print_context_open,
311  .release = trc_print_context_release,
312  .read = trc_print_context_read,
313  .write = trc_print_context_write,
314 };
315 
316 /******************************* stat ****************************************/
317 
318 static bool trc_stat_is_opened = false;
319 
320 static int trc_stat_open(struct inode *i, struct file *f)
321 {
322  if (trc_stat_is_opened)
323  return -EBUSY;
324 
325  trc_stat_is_opened = true;
326 
327  return 0;
328 }
329 
330 static int trc_stat_release(struct inode *i, struct file *f)
331 {
332  trc_stat_is_opened = false;
333  return 0;
334 }
335 
336 static const char *bytes_to_human_str(uint64_t bytes)
337 {
338  static char buf[256];
339  uint64_t integer;
340  uint32_t reminder;
341  const char *units;
342 
343  buf[0] = '\0';
344 
345  if (bytes / 1024 / 1024 / 1024) { /* > 1 gigabyte */
346  integer = bytes / 1024 / 1024 / 1024;
347  reminder = bytes % (1024 * 1024 * 1024) / 10000000;
348  units = "Gi";
349  } else if (bytes / 1024 / 1024) { /* > 1 megabyte */
350  integer = bytes / 1024 / 1024;
351  reminder = bytes % (1024 * 1024) / 10000;
352  units = "Mi";
353  } else if (bytes / 1024) { /* > 1 kilobyte */
354  integer = bytes / 1024;
355  reminder = bytes % 1024 / 10;
356  units = "Ki";
357  } else {
358  /* just return an empty string for now, to avoid duplication */
359  return buf;
360  }
361 
362  snprintf(buf, sizeof buf, "%" PRIu64 ".%02u%s", integer, reminder, units);
363  buf[sizeof buf - 1] = '\0';
364 
365  return buf;
366 }
367 
368 static ssize_t trc_stat_read(struct file *file, char __user *ubuf,
369  size_t ubuf_size, loff_t *ppos)
370 {
371  static char buf[4096];
372  const size_t buf_size = sizeof buf - 1; /* reserve last byte for '\0' */
373  size_t buf_used = 0;
374  ssize_t ret_size = 0;
375  const struct m0_trace_stats *stats = m0_trace_get_stats();
376  uint64_t logbuf_pos;
377  uint32_t logbuf_size;
378  uint64_t total_rec_num;
379  uint32_t rec_per_sec;
380  uint32_t bytes_per_sec;
381  uint32_t avg_rec_per_sec;
382  uint32_t avg_bytes_per_sec;
383  uint32_t max_rec_per_sec;
384  uint32_t max_bytes_per_sec;
385  uint32_t avg_rec_size;
386  uint32_t max_rec_size;
387 
388  /* indicate EOF if we are not at the beginning of file */
389  if (*ppos != 0)
390  return 0;
391 
392  buf[0] = '\0';
393 
395  logbuf_pos = m0_trace_logbuf_pos_get();
396  logbuf_size = m0_trace_logbuf_size_get();
397  total_rec_num = m0_atomic64_get(&stats->trs_rec_total);
398  rec_per_sec = stats->trs_rec_per_sec;
399  bytes_per_sec = stats->trs_bytes_per_sec;
400  avg_rec_per_sec = stats->trs_avg_rec_per_sec;
401  avg_bytes_per_sec = stats->trs_avg_bytes_per_sec;
402  max_rec_per_sec = stats->trs_max_rec_per_sec;
403  max_bytes_per_sec = stats->trs_max_bytes_per_sec;
404  avg_rec_size = stats->trs_avg_rec_size;
405  max_rec_size = stats->trs_max_rec_size;
406 
407  buf_used += buf_add(buf, buf_size, buf_used,
408  "buffer address: 0x%p\n",
410 
411  buf_used += buf_add(buf, buf_size, buf_used,
412  "buffer size: %-12u %s\n",
413  logbuf_size, bytes_to_human_str(logbuf_size));
414 
415  buf_used += buf_add(buf, buf_size, buf_used,
416  "buffer abs pos: %-12llu %s\n",
417  logbuf_pos, bytes_to_human_str(logbuf_pos));
418 
419  buf_used += buf_add(buf, buf_size, buf_used,
420  "total rec num: %-12llu %s\n",
421  total_rec_num, bytes_to_human_str(total_rec_num));
422 
423  buf_used += buf_add(buf, buf_size, buf_used,
424  "records per sec: %-12u %s\n",
425  rec_per_sec, bytes_to_human_str(rec_per_sec));
426 
427  buf_used += buf_add(buf, buf_size, buf_used,
428  "bytes per sec: %-12u %s\n",
429  bytes_per_sec, bytes_to_human_str(bytes_per_sec));
430 
431  buf_used += buf_add(buf, buf_size, buf_used,
432  "avg records per sec: %-12u %s\n",
433  avg_rec_per_sec,
434  bytes_to_human_str(avg_rec_per_sec));
435 
436  buf_used += buf_add(buf, buf_size, buf_used,
437  "avg bytes per sec: %-12u %s\n",
438  avg_bytes_per_sec,
439  bytes_to_human_str(avg_bytes_per_sec));
440 
441  buf_used += buf_add(buf, buf_size, buf_used,
442  "max records per sec: %-12u %s\n",
443  max_rec_per_sec,
444  bytes_to_human_str(max_rec_per_sec));
445 
446  buf_used += buf_add(buf, buf_size, buf_used,
447  "max bytes per sec: %-12u %s\n",
448  max_bytes_per_sec,
449  bytes_to_human_str(max_bytes_per_sec));
450 
451  buf_used += buf_add(buf, buf_size, buf_used,
452  "avg record size: %-12u %s\n",
453  avg_rec_size, bytes_to_human_str(avg_rec_size));
454 
455  buf_used += buf_add(buf, buf_size, buf_used,
456  "max record size: %-12u %s\n",
457  max_rec_size, bytes_to_human_str(max_rec_size));
458 
459  if (buf_used >= sizeof buf)
460  buf_used = buf_size - 1;
461  buf[buf_used++] = '\0';
462  ret_size = min(ubuf_size, buf_used);
463 
464  return simple_read_from_buffer(ubuf, ubuf_size, ppos, buf, ret_size);
465 }
466 
467 static const struct file_operations trc_stat_fops = {
468  .owner = THIS_MODULE,
469  .open = trc_stat_open,
470  .release = trc_stat_release,
471  .read = trc_stat_read,
472 };
473 
474 /******************************* records **************************************/
475 
476 static bool trc_records_is_opened = false;
477 static const struct m0_trace_rec_header *trc_records_last_trh;
478 
479 static int trc_records_open(struct inode *i, struct file *f)
480 {
481  if (trc_records_is_opened)
482  return -EBUSY;
483 
484  trc_records_is_opened = true;
485  trc_records_last_trh = NULL;
486 
487  return 0;
488 }
489 
490 static int trc_records_release(struct inode *i, struct file *f)
491 {
492  trc_records_is_opened = false;
493  return 0;
494 }
495 
496 static const struct m0_trace_rec_header*
497 find_next_recornd(const struct m0_trace_rec_header *curtrh)
498 {
499  const char *begptr = (char*)m0_trace_logbuf_get();
500  const char *endptr = begptr + m0_trace_logbuf_size_get();
501  const char *curptr = begptr + m0_trace_logbuf_pos_get() %
503 
504  const char *p = (char*)curtrh + curtrh->trh_record_size;
505 
506  if (p > curptr) {
507  for (; p < endptr; p += M0_TRACE_REC_ALIGN)
508  if (*((uint64_t*)p) == M0_TRACE_MAGIC)
509  return (const struct m0_trace_rec_header*)p;
510  p = begptr;
511  }
512 
513  for (; p < curptr; p += M0_TRACE_REC_ALIGN)
514  if (*((uint64_t*)p) == M0_TRACE_MAGIC)
515  return (const struct m0_trace_rec_header*)p;
516 
517  /* p == curptr, it means there is no new trace records in log buffer */
518  return NULL;
519 }
520 
521 static ssize_t trc_records_read(struct file *file, char __user *ubuf,
522  size_t ubuf_size, loff_t *ppos)
523 {
524  long rc;
525  static char buf[16 * 1024]; /* 16 KB */
526  void *tr_body;
527  loff_t fake_pos = 0;
528 
529  const struct m0_trace_rec_header *trh;
530 
531  buf[0] = '\0';
532 
533  while (true) {
534  if (trc_records_last_trh == NULL)
535  trh = m0_trace_last_record_get();
536  else
537  trh = find_next_recornd(trc_records_last_trh);
538 
539  if (trh != NULL && trh != trc_records_last_trh) {
540  trc_records_last_trh = trh;
541  tr_body = (char*)trh + m0_align(sizeof *trh,
543  break;
544  }
545 
546  rc = msleep_interruptible(100);
547  if (rc != 0)
548  /* got a signal, return EOF */
549  return 0;
550  }
551 
552  rc = m0_trace_record_print_yaml(buf, sizeof buf, trh, tr_body, true);
553  if (rc != 0) {
554  pr_warn(KBUILD_MODNAME ": internal buffer is to small to hold"
555  " trace record\n");
556  /* return empty string: there is only '\0' in the buffer */
557  return simple_read_from_buffer(ubuf, ubuf_size, &fake_pos,
558  buf, 1);
559  }
560 
561  return simple_read_from_buffer(ubuf, ubuf_size, &fake_pos,
562  buf, strlen(buf));
563 }
564 
565 static const struct file_operations trc_records_fops = {
566  .owner = THIS_MODULE,
567  .open = trc_records_open,
568  .release = trc_records_release,
569  .read = trc_records_read,
570 };
571 
572 /******************************* buffer **************************************/
573 
574 static int trc_buffer_open(struct inode *i, struct file *f)
575 {
576  return 0;
577 }
578 
579 static int trc_buffer_release(struct inode *i, struct file *f)
580 {
581  return 0;
582 }
583 
584 static ssize_t trc_buffer_read(struct file *file, char __user *ubuf,
585  size_t ubuf_size, loff_t *ppos)
586 {
587  const void *logbuf_header = m0_trace_logbuf_header_get();
588  uint32_t logbuf_size = M0_TRACE_BUF_HEADER_SIZE +
590 
591  return simple_read_from_buffer(ubuf, ubuf_size, ppos, logbuf_header,
592  logbuf_size);
593 }
594 
595 static void trc_buffer_mmap_close(struct vm_area_struct *vma)
596 {
597 }
598 
599 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0)
600 static int trc_buffer_mmap_fault(struct vm_fault *vmf)
601 #else
602 static int trc_buffer_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
603 #endif
604 {
605  const void *logbuf_header = m0_trace_logbuf_header_get();
606  pgoff_t pgoff = vmf->pgoff;
607  struct page *page;
608 
609  page = vmalloc_to_page(logbuf_header + (pgoff << PAGE_SHIFT));
610  if (!page)
611  return VM_FAULT_SIGBUS;
612 
613  get_page(page);
614  vmf->page = page;
615 
616  return 0;
617 }
618 
619 static const struct vm_operations_struct trc_buffer_mmap_ops = {
620  .fault = trc_buffer_mmap_fault,
621  .close = trc_buffer_mmap_close,
622 };
623 
624 static int trc_buffer_mmap(struct file *filp, struct vm_area_struct *vma)
625 {
626  unsigned long length = vma->vm_end - vma->vm_start;
627  uint32_t logbuf_size = M0_TRACE_BUF_HEADER_SIZE +
629 
630  if (length + (vma->vm_pgoff << PAGE_SHIFT) > logbuf_size)
631  return -EINVAL;
632 
633  vma->vm_ops = &trc_buffer_mmap_ops;
634  vma->vm_flags |= VM_DONTEXPAND;
635 
636  return 0;
637 }
638 
639 static unsigned int trc_buffer_poll(struct file *filp, poll_table *pt)
640 {
641  long rc;
642  const char *curpos;
643  const uint32_t idle_timeo = 100; /* in msec */
644 
645  static uint32_t timeo;
646  static const char *oldpos;
647 
648  curpos = (char*)m0_trace_logbuf_get() +
650 
651  /* init static vars */
652  if (oldpos == NULL) {
653  oldpos = curpos;
654  timeo = idle_timeo;
655  }
656 
657  while (curpos == oldpos) {
658  rc = msleep_interruptible(timeo);
659  if (rc != 0)
660  /* got a signal, return "no data" */
661  return 0;
662 
663  curpos = (char*)m0_trace_logbuf_get() +
665 
666  if (++timeo > idle_timeo)
667  timeo = idle_timeo;
668  }
669  oldpos = curpos;
670  timeo /= 2;
671 
672  return (unsigned int)(POLLIN | POLLRDNORM);
673 }
674 
675 static const struct file_operations trc_buffer_fops = {
676  .owner = THIS_MODULE,
677  .open = trc_buffer_open,
678  .release = trc_buffer_release,
679  .read = trc_buffer_read,
680  .mmap = trc_buffer_mmap,
681  .poll = trc_buffer_poll,
682 };
683 
684 /******************************* init/fini ************************************/
685 
686 int trc_dfs_init(void)
687 {
688  struct dentry *trc_level_file;
689  static const char trc_level_name[] = "level";
690  struct dentry *trc_immediate_mask_file;
691  static const char trc_immediate_mask_name[] = "immediate_mask";
692  struct dentry *trc_print_context_file;
693  static const char trc_print_context_name[] = "print_context";
694  struct dentry *trc_stat_file;
695  static const char trc_stat_name[] = "stat";
696  struct dentry *trc_records_file;
697  static const char trc_records_name[] = "records";
698  struct dentry *trc_buffer_file;
699  static const char trc_buffer_name[] = "buffer";
700  int rc = 0;
701 
702  trc_dir = debugfs_create_dir(trc_dir_name, dfs_root_dir);
703  if (trc_dir == NULL) {
704  pr_err(KBUILD_MODNAME ": can't create debugfs dir '%s/%s'\n",
705  dfs_root_name, trc_dir_name);
706  rc = -EPERM;
707  goto out;
708  }
709 
710  trc_level_file = debugfs_create_file(trc_level_name, S_IRUSR | S_IWUSR,
711  trc_dir, NULL, &trc_level_fops);
712  if (trc_level_file == NULL) {
713  pr_err(KBUILD_MODNAME ": failed to create debugfs file"
714  " '%s/%s/%s'\n", dfs_root_name, trc_dir_name,
715  trc_level_name);
716  rc = -EPERM;
717  goto err;
718  }
719 
720  trc_immediate_mask_file = debugfs_create_file(trc_immediate_mask_name,
721  S_IRUSR | S_IWUSR, trc_dir, NULL,
722  &trc_immediate_mask_fops);
723  if (trc_immediate_mask_file == NULL) {
724  pr_err(KBUILD_MODNAME ": failed to create debugfs file"
725  " '%s/%s/%s'\n", dfs_root_name, trc_dir_name,
726  trc_immediate_mask_name);
727  rc = -EPERM;
728  goto err;
729  }
730 
731  trc_print_context_file = debugfs_create_file(trc_print_context_name,
732  S_IRUSR | S_IWUSR, trc_dir, NULL,
733  &trc_print_context_fops);
734  if (trc_print_context_file == NULL) {
735  pr_err(KBUILD_MODNAME ": failed to create debugfs file"
736  " '%s/%s/%s'\n", dfs_root_name, trc_dir_name,
737  trc_print_context_name);
738  rc = -EPERM;
739  goto err;
740  }
741 
742  trc_stat_file = debugfs_create_file(trc_stat_name, S_IRUSR, trc_dir,
743  NULL, &trc_stat_fops);
744  if (trc_stat_file == NULL) {
745  pr_err(KBUILD_MODNAME ": failed to create debugfs file"
746  " '%s/%s/%s'\n", dfs_root_name, trc_dir_name,
747  trc_stat_name);
748  rc = -EPERM;
749  goto err;
750  }
751 
752  trc_records_file = debugfs_create_file(trc_records_name, S_IRUSR,
753  trc_dir, NULL,
754  &trc_records_fops);
755  if (trc_records_file == NULL) {
756  pr_err(KBUILD_MODNAME ": failed to create debugfs file"
757  " '%s/%s/%s'\n", dfs_root_name, trc_dir_name,
758  trc_records_name);
759  rc = -EPERM;
760  goto err;
761  }
762 
763  trc_buffer_file = debugfs_create_file(trc_buffer_name, S_IRUSR,
764  trc_dir, NULL,
765  &trc_buffer_fops);
766  if (trc_buffer_file == NULL) {
767  pr_err(KBUILD_MODNAME ": failed to create debugfs file"
768  " '%s/%s/%s'\n", dfs_root_name, trc_dir_name,
769  trc_buffer_name);
770  rc = -EPERM;
771  goto err;
772  }
773 out:
774  return rc;
775 err:
776  debugfs_remove_recursive(trc_dir);
777  trc_dir = 0;
778  return rc;
779 }
780 
781 void trc_dfs_cleanup(void)
782 {
783  debugfs_remove_recursive(trc_dir);
784 }
785 #endif
786 
789 /*
790  * Local variables:
791  * c-indentation-style: "K&R"
792  * c-basic-offset: 8
793  * tab-width: 8
794  * fill-column: 80
795  * scroll-step: 1
796  * End:
797  */
M0_INTERNAL const void * m0_trace_logbuf_get(void)
Definition: trace.c:618
static struct m0_addb2_philter p
Definition: consumer.c:40
M0_INTERNAL uint32_t m0_trace_logbuf_size_get(void)
Definition: trace.c:624
#define NULL
Definition: misc.h:38
static FILE * f
Definition: adieu.c:79
struct m0_file file
Definition: di.c:36
enum m0_trace_level level
Definition: trace.c:111
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
struct dentry * dfs_root_dir
M0_INTERNAL const struct m0_trace_rec_header * m0_trace_last_record_get(void)
Definition: trace.c:929
uint64_t * tr_body
Definition: addb2.h:435
int trc_dfs_init(void)
static int void * buf
Definition: dir.c:1019
Definition: ub.c:49
Definition: sock.c:887
struct inode * inode
Definition: dir.c:624
int i
Definition: dir.c:1033
#define PRIu64
Definition: types.h:58
def args
Definition: addb2db.py:716
void trc_dfs_cleanup(void)
M0_INTERNAL const char * m0_trace_subsys_name(uint64_t subsys)
Definition: trace.c:339
if(value==NULL)
Definition: dir.c:350
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
static int struct dentry * dentry
Definition: dir.c:589
M0_INTERNAL const char * m0_trace_level_name(enum m0_trace_level level)
Definition: trace.c:460
static int buf_add(struct m0_net_buffer *nb)
Definition: sock.c:1787
char * fmt(const char *format,...) __attribute__((format(printf
M0_INTERNAL const struct m0_trace_buf_header * m0_trace_logbuf_header_get(void)
Definition: trace.c:612
uint32_t trh_record_size
Definition: trace.h:447
const char dfs_root_name[]
static int64_t m0_atomic64_get(const struct m0_atomic64 *a)
static long long min(long long a, long long b)
Definition: crate.c:191
uint64_t n
Definition: fops.h:107
Definition: beck.c:130
Definition: trace.h:459
M0_INTERNAL int m0_trace_set_immediate_mask(const char *mask_str)
Definition: ktrace.c:77
m0_trace_level
Definition: trace.h:454
m0_trace_print_context
Definition: trace.h:496
M0_INTERNAL const struct m0_trace_stats * m0_trace_get_stats(void)
Definition: ktrace.c:113
struct @326 level_str[]
static uint32_t buf_size
Definition: ad.c:75
unsigned long m0_trace_immediate_mask
Definition: trace.c:91
#define out(...)
Definition: gen.c:41
#define CHAR_BIT
Definition: misc.h:32
M0_INTERNAL uint64_t m0_trace_logbuf_pos_get(void)
Definition: trace.c:638
int32_t rc
Definition: trigger_fop.h:47
static uint64_t m0_align(uint64_t val, uint64_t alignment)
Definition: arith.h:170
M0_INTERNAL int m0_trace_set_level(const char *level_str)
Definition: trace.c:581