Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause
2 : * Copyright (C) 2017 Intel Corporation.
3 : * All rights reserved.
4 : */
5 :
6 : #include "spdk/stdinc.h"
7 :
8 : #include "spdk/log.h"
9 :
10 : static TAILQ_HEAD(spdk_log_flag_head,
11 : spdk_log_flag) g_log_flags = TAILQ_HEAD_INITIALIZER(g_log_flags);
12 :
13 : static struct spdk_log_flag *
14 237 : get_log_flag(const char *name)
15 : {
16 : struct spdk_log_flag *flag;
17 :
18 452 : TAILQ_FOREACH(flag, &g_log_flags, tailq) {
19 271 : if (strcasecmp(name, flag->name) == 0) {
20 56 : return flag;
21 : }
22 : }
23 :
24 181 : return NULL;
25 : }
26 :
27 : void
28 181 : spdk_log_register_flag(const char *name, struct spdk_log_flag *flag)
29 : {
30 : struct spdk_log_flag *iter;
31 :
32 181 : if (name == NULL || flag == NULL) {
33 0 : SPDK_ERRLOG("missing spdk_log_flag parameters\n");
34 0 : assert(false);
35 : return;
36 : }
37 :
38 181 : if (get_log_flag(name)) {
39 0 : SPDK_ERRLOG("duplicate spdk_log_flag '%s'\n", name);
40 0 : assert(false);
41 : return;
42 : }
43 :
44 335 : TAILQ_FOREACH(iter, &g_log_flags, tailq) {
45 185 : if (strcasecmp(iter->name, flag->name) > 0) {
46 31 : TAILQ_INSERT_BEFORE(iter, flag, tailq);
47 31 : return;
48 : }
49 : }
50 :
51 150 : TAILQ_INSERT_TAIL(&g_log_flags, flag, tailq);
52 : }
53 :
54 : bool
55 56 : spdk_log_get_flag(const char *name)
56 : {
57 56 : struct spdk_log_flag *flag = get_log_flag(name);
58 :
59 56 : if (flag && flag->enabled) {
60 1 : return true;
61 : }
62 :
63 55 : return false;
64 : }
65 :
66 : static int
67 3 : log_set_flag(const char *name, bool value)
68 : {
69 : struct spdk_log_flag *flag;
70 3 : int rc = -EINVAL;
71 :
72 3 : if (strcasecmp(name, "all") == 0) {
73 0 : TAILQ_FOREACH(flag, &g_log_flags, tailq) {
74 0 : flag->enabled = value;
75 : }
76 0 : return 0;
77 : }
78 :
79 6 : TAILQ_FOREACH(flag, &g_log_flags, tailq) {
80 3 : if (fnmatch(name, flag->name, FNM_CASEFOLD) == 0) {
81 3 : flag->enabled = value;
82 3 : rc = 0;
83 : }
84 : }
85 :
86 3 : return rc;
87 : }
88 :
89 : int
90 2 : spdk_log_set_flag(const char *name)
91 : {
92 2 : return log_set_flag(name, true);
93 : }
94 :
95 : int
96 1 : spdk_log_clear_flag(const char *name)
97 : {
98 1 : return log_set_flag(name, false);
99 : }
100 :
101 : struct spdk_log_flag *
102 0 : spdk_log_get_first_flag(void)
103 : {
104 0 : return TAILQ_FIRST(&g_log_flags);
105 : }
106 :
107 : struct spdk_log_flag *
108 0 : spdk_log_get_next_flag(struct spdk_log_flag *flag)
109 : {
110 0 : return TAILQ_NEXT(flag, tailq);
111 : }
112 :
113 : void
114 3 : spdk_log_usage(FILE *f, const char *log_arg)
115 : {
116 : #define LINE_PREFIX " "
117 : #define ENTRY_SEPARATOR ", "
118 : #define MAX_LINE_LENGTH 100
119 3 : uint64_t prefix_len = strlen(LINE_PREFIX);
120 3 : uint64_t separator_len = strlen(ENTRY_SEPARATOR);
121 3 : const char *first_entry = "--logflag <flag> enable log flag (all, ";
122 : uint64_t curr_line_len;
123 : uint64_t curr_entry_len;
124 : struct spdk_log_flag *flag;
125 3 : char first_line[MAX_LINE_LENGTH] = {};
126 :
127 3 : snprintf(first_line, sizeof(first_line), " %s, %s", log_arg, first_entry);
128 3 : fprintf(f, "%s", first_line);
129 3 : curr_line_len = strlen(first_line);
130 :
131 15 : TAILQ_FOREACH(flag, &g_log_flags, tailq) {
132 15 : curr_entry_len = strlen(flag->name);
133 15 : if ((curr_line_len + curr_entry_len + separator_len) > MAX_LINE_LENGTH) {
134 0 : fprintf(f, "\n%s", LINE_PREFIX);
135 0 : curr_line_len = prefix_len;
136 : }
137 :
138 15 : fprintf(f, "%s", flag->name);
139 15 : curr_line_len += curr_entry_len;
140 :
141 15 : if (TAILQ_LAST(&g_log_flags, spdk_log_flag_head) == flag) {
142 3 : break;
143 : }
144 :
145 12 : fprintf(f, "%s", ENTRY_SEPARATOR);
146 12 : curr_line_len += separator_len;
147 : }
148 :
149 3 : fprintf(f, ")\n");
150 3 : }
|