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) g_log_flags = TAILQ_HEAD_INITIALIZER(g_log_flags); 11 12 static struct spdk_log_flag * 13 get_log_flag(const char *name) 14 { 15 struct spdk_log_flag *flag; 16 17 TAILQ_FOREACH(flag, &g_log_flags, tailq) { 18 if (strcasecmp(name, flag->name) == 0) { 19 return flag; 20 } 21 } 22 23 return NULL; 24 } 25 26 void 27 spdk_log_register_flag(const char *name, struct spdk_log_flag *flag) 28 { 29 struct spdk_log_flag *iter; 30 31 if (name == NULL || flag == NULL) { 32 SPDK_ERRLOG("missing spdk_log_flag parameters\n"); 33 assert(false); 34 return; 35 } 36 37 if (get_log_flag(name)) { 38 SPDK_ERRLOG("duplicate spdk_log_flag '%s'\n", name); 39 assert(false); 40 return; 41 } 42 43 TAILQ_FOREACH(iter, &g_log_flags, tailq) { 44 if (strcasecmp(iter->name, flag->name) > 0) { 45 TAILQ_INSERT_BEFORE(iter, flag, tailq); 46 return; 47 } 48 } 49 50 TAILQ_INSERT_TAIL(&g_log_flags, flag, tailq); 51 } 52 53 bool 54 spdk_log_get_flag(const char *name) 55 { 56 struct spdk_log_flag *flag = get_log_flag(name); 57 58 if (flag && flag->enabled) { 59 return true; 60 } 61 62 return false; 63 } 64 65 static int 66 log_set_flag(const char *name, bool value) 67 { 68 struct spdk_log_flag *flag; 69 int rc = -EINVAL; 70 71 if (strcasecmp(name, "all") == 0) { 72 TAILQ_FOREACH(flag, &g_log_flags, tailq) { 73 flag->enabled = value; 74 } 75 return 0; 76 } 77 78 TAILQ_FOREACH(flag, &g_log_flags, tailq) { 79 if (fnmatch(name, flag->name, FNM_CASEFOLD) == 0) { 80 flag->enabled = value; 81 rc = 0; 82 } 83 } 84 85 return rc; 86 } 87 88 int 89 spdk_log_set_flag(const char *name) 90 { 91 return log_set_flag(name, true); 92 } 93 94 int 95 spdk_log_clear_flag(const char *name) 96 { 97 return log_set_flag(name, false); 98 } 99 100 struct spdk_log_flag * 101 spdk_log_get_first_flag(void) 102 { 103 return TAILQ_FIRST(&g_log_flags); 104 } 105 106 struct spdk_log_flag * 107 spdk_log_get_next_flag(struct spdk_log_flag *flag) 108 { 109 return TAILQ_NEXT(flag, tailq); 110 } 111 112 void 113 spdk_log_usage(FILE *f, const char *log_arg) 114 { 115 struct spdk_log_flag *flag; 116 fprintf(f, " %s, --logflag <flag> enable log flag (all", log_arg); 117 118 TAILQ_FOREACH(flag, &g_log_flags, tailq) { 119 fprintf(f, ", %s", flag->name); 120 } 121 122 fprintf(f, ")\n"); 123 } 124