1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse * Copyright (C) 2017 Intel Corporation.
385c146efSEd Rodriguez * All rights reserved.
485c146efSEd Rodriguez */
585c146efSEd Rodriguez
685c146efSEd Rodriguez #include "spdk/stdinc.h"
785c146efSEd Rodriguez
84e8e97c8STomasz Zawadzki #include "spdk/log.h"
985c146efSEd Rodriguez
10*2d65fd75SKrzysztof Karas static TAILQ_HEAD(spdk_log_flag_head,
11*2d65fd75SKrzysztof Karas spdk_log_flag) g_log_flags = TAILQ_HEAD_INITIALIZER(g_log_flags);
1285c146efSEd Rodriguez
133dc8dfb4SJim Harris static struct spdk_log_flag *
get_log_flag(const char * name)14b4b7d5d3SJim Harris get_log_flag(const char *name)
1585c146efSEd Rodriguez {
163dc8dfb4SJim Harris struct spdk_log_flag *flag;
1785c146efSEd Rodriguez
1872f8c6a1SJim Harris TAILQ_FOREACH(flag, &g_log_flags, tailq) {
1985c146efSEd Rodriguez if (strcasecmp(name, flag->name) == 0) {
2085c146efSEd Rodriguez return flag;
2185c146efSEd Rodriguez }
2285c146efSEd Rodriguez }
2385c146efSEd Rodriguez
2485c146efSEd Rodriguez return NULL;
2585c146efSEd Rodriguez }
2685c146efSEd Rodriguez
2785c146efSEd Rodriguez void
spdk_log_register_flag(const char * name,struct spdk_log_flag * flag)2872f8c6a1SJim Harris spdk_log_register_flag(const char *name, struct spdk_log_flag *flag)
2985c146efSEd Rodriguez {
303dc8dfb4SJim Harris struct spdk_log_flag *iter;
3185c146efSEd Rodriguez
3285c146efSEd Rodriguez if (name == NULL || flag == NULL) {
333dc8dfb4SJim Harris SPDK_ERRLOG("missing spdk_log_flag parameters\n");
343181857bSEd rodriguez assert(false);
353181857bSEd rodriguez return;
3685c146efSEd Rodriguez }
3785c146efSEd Rodriguez
38b4b7d5d3SJim Harris if (get_log_flag(name)) {
393dc8dfb4SJim Harris SPDK_ERRLOG("duplicate spdk_log_flag '%s'\n", name);
403181857bSEd rodriguez assert(false);
413181857bSEd rodriguez return;
4285c146efSEd Rodriguez }
4385c146efSEd Rodriguez
4472f8c6a1SJim Harris TAILQ_FOREACH(iter, &g_log_flags, tailq) {
4585c146efSEd Rodriguez if (strcasecmp(iter->name, flag->name) > 0) {
4685c146efSEd Rodriguez TAILQ_INSERT_BEFORE(iter, flag, tailq);
4785c146efSEd Rodriguez return;
4885c146efSEd Rodriguez }
4985c146efSEd Rodriguez }
5085c146efSEd Rodriguez
5172f8c6a1SJim Harris TAILQ_INSERT_TAIL(&g_log_flags, flag, tailq);
5285c146efSEd Rodriguez }
5385c146efSEd Rodriguez
5485c146efSEd Rodriguez bool
spdk_log_get_flag(const char * name)55b4b7d5d3SJim Harris spdk_log_get_flag(const char *name)
5685c146efSEd Rodriguez {
57b4b7d5d3SJim Harris struct spdk_log_flag *flag = get_log_flag(name);
5885c146efSEd Rodriguez
5985c146efSEd Rodriguez if (flag && flag->enabled) {
6085c146efSEd Rodriguez return true;
6185c146efSEd Rodriguez }
6285c146efSEd Rodriguez
6385c146efSEd Rodriguez return false;
6485c146efSEd Rodriguez }
6585c146efSEd Rodriguez
6685c146efSEd Rodriguez static int
log_set_flag(const char * name,bool value)678dc50d2dSMaciej Wawryk log_set_flag(const char *name, bool value)
6885c146efSEd Rodriguez {
693dc8dfb4SJim Harris struct spdk_log_flag *flag;
7003593c44SKonrad Sztyber int rc = -EINVAL;
7185c146efSEd Rodriguez
7285c146efSEd Rodriguez if (strcasecmp(name, "all") == 0) {
7372f8c6a1SJim Harris TAILQ_FOREACH(flag, &g_log_flags, tailq) {
7485c146efSEd Rodriguez flag->enabled = value;
7585c146efSEd Rodriguez }
7685c146efSEd Rodriguez return 0;
7785c146efSEd Rodriguez }
7885c146efSEd Rodriguez
7903593c44SKonrad Sztyber TAILQ_FOREACH(flag, &g_log_flags, tailq) {
8003593c44SKonrad Sztyber if (fnmatch(name, flag->name, FNM_CASEFOLD) == 0) {
8103593c44SKonrad Sztyber flag->enabled = value;
8203593c44SKonrad Sztyber rc = 0;
8303593c44SKonrad Sztyber }
8485c146efSEd Rodriguez }
8585c146efSEd Rodriguez
8603593c44SKonrad Sztyber return rc;
8785c146efSEd Rodriguez }
8885c146efSEd Rodriguez
8985c146efSEd Rodriguez int
spdk_log_set_flag(const char * name)90b4b7d5d3SJim Harris spdk_log_set_flag(const char *name)
9185c146efSEd Rodriguez {
928dc50d2dSMaciej Wawryk return log_set_flag(name, true);
9385c146efSEd Rodriguez }
9485c146efSEd Rodriguez
9585c146efSEd Rodriguez int
spdk_log_clear_flag(const char * name)96b4b7d5d3SJim Harris spdk_log_clear_flag(const char *name)
9785c146efSEd Rodriguez {
988dc50d2dSMaciej Wawryk return log_set_flag(name, false);
9985c146efSEd Rodriguez }
10085c146efSEd Rodriguez
1013dc8dfb4SJim Harris struct spdk_log_flag *
spdk_log_get_first_flag(void)10272f8c6a1SJim Harris spdk_log_get_first_flag(void)
10385c146efSEd Rodriguez {
10472f8c6a1SJim Harris return TAILQ_FIRST(&g_log_flags);
10585c146efSEd Rodriguez }
10685c146efSEd Rodriguez
1073dc8dfb4SJim Harris struct spdk_log_flag *
spdk_log_get_next_flag(struct spdk_log_flag * flag)10872f8c6a1SJim Harris spdk_log_get_next_flag(struct spdk_log_flag *flag)
10985c146efSEd Rodriguez {
11085c146efSEd Rodriguez return TAILQ_NEXT(flag, tailq);
11185c146efSEd Rodriguez }
11285c146efSEd Rodriguez
11385c146efSEd Rodriguez void
spdk_log_usage(FILE * f,const char * log_arg)114b4b7d5d3SJim Harris spdk_log_usage(FILE *f, const char *log_arg)
11585c146efSEd Rodriguez {
116*2d65fd75SKrzysztof Karas #define LINE_PREFIX " "
117*2d65fd75SKrzysztof Karas #define ENTRY_SEPARATOR ", "
118*2d65fd75SKrzysztof Karas #define MAX_LINE_LENGTH 100
119*2d65fd75SKrzysztof Karas uint64_t prefix_len = strlen(LINE_PREFIX);
120*2d65fd75SKrzysztof Karas uint64_t separator_len = strlen(ENTRY_SEPARATOR);
121*2d65fd75SKrzysztof Karas const char *first_entry = "--logflag <flag> enable log flag (all, ";
122*2d65fd75SKrzysztof Karas uint64_t curr_line_len;
123*2d65fd75SKrzysztof Karas uint64_t curr_entry_len;
1243dc8dfb4SJim Harris struct spdk_log_flag *flag;
125*2d65fd75SKrzysztof Karas char first_line[MAX_LINE_LENGTH] = {};
126*2d65fd75SKrzysztof Karas
127*2d65fd75SKrzysztof Karas snprintf(first_line, sizeof(first_line), " %s, %s", log_arg, first_entry);
128*2d65fd75SKrzysztof Karas fprintf(f, "%s", first_line);
129*2d65fd75SKrzysztof Karas curr_line_len = strlen(first_line);
13085c146efSEd Rodriguez
13172f8c6a1SJim Harris TAILQ_FOREACH(flag, &g_log_flags, tailq) {
132*2d65fd75SKrzysztof Karas curr_entry_len = strlen(flag->name);
133*2d65fd75SKrzysztof Karas if ((curr_line_len + curr_entry_len + separator_len) > MAX_LINE_LENGTH) {
134*2d65fd75SKrzysztof Karas fprintf(f, "\n%s", LINE_PREFIX);
135*2d65fd75SKrzysztof Karas curr_line_len = prefix_len;
136*2d65fd75SKrzysztof Karas }
137*2d65fd75SKrzysztof Karas
138*2d65fd75SKrzysztof Karas fprintf(f, "%s", flag->name);
139*2d65fd75SKrzysztof Karas curr_line_len += curr_entry_len;
140*2d65fd75SKrzysztof Karas
141*2d65fd75SKrzysztof Karas if (TAILQ_LAST(&g_log_flags, spdk_log_flag_head) == flag) {
142*2d65fd75SKrzysztof Karas break;
143*2d65fd75SKrzysztof Karas }
144*2d65fd75SKrzysztof Karas
145*2d65fd75SKrzysztof Karas fprintf(f, "%s", ENTRY_SEPARATOR);
146*2d65fd75SKrzysztof Karas curr_line_len += separator_len;
14785c146efSEd Rodriguez }
14885c146efSEd Rodriguez
14985c146efSEd Rodriguez fprintf(f, ")\n");
15085c146efSEd Rodriguez }
151