bslfile.c (4352B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * Broadcom System Log FIle Sink 8 */ 9 10 #include <sal/core/libc.h> 11 #include <sal/core/spl.h> 12 #include <sal/core/alloc.h> 13 #include <sal/core/dpc.h> 14 #include <sal/appl/io.h> 15 #include <appl/diag/bslsink.h> 16 #include <appl/diag/bslfile.h> 17 18 #ifndef NO_FILEIO 19 20 #include <stdio.h> 21 22 static FILE *file_fp = NULL; 23 static char *file_nm = NULL; 24 25 static bslsink_sink_t logfile_sink; 26 static sal_mutex_t file_lock = NULL; 27 28 #define FILE_LOCK \ 29 if (file_lock != NULL) \ 30 { sal_mutex_take(file_lock, sal_mutex_FOREVER); } 31 32 #define FILE_UNLOCK \ 33 if (file_lock != NULL) \ 34 { sal_mutex_give(file_lock); } 35 36 STATIC void 37 bslfile_dpc(void *a1, void *a2, void *a3, void *a4, void *a5) 38 { 39 char *fmt = (char *)a1; 40 FILE_LOCK; 41 if (file_fp) { 42 sal_fprintf(file_fp, fmt, a2, a3, a4, a5); 43 sal_fflush(file_fp); 44 } 45 FILE_UNLOCK; 46 } 47 48 STATIC int 49 bslfile_vfprintf(void *file, const char *format, va_list args) 50 { 51 int retv = 0; 52 53 FILE_LOCK; 54 if (file_fp) { 55 if (sal_int_context()) { 56 void *a1, *a2, *a3, *a4; 57 a1 = va_arg(args, void *); 58 a2 = va_arg(args, void *); 59 a3 = va_arg(args, void *); 60 a4 = va_arg(args, void *); 61 /* Passing format in lieu of fake owner to avoid wasting an arg */ 62 retv = sal_dpc(bslfile_dpc, (void *)format, a1, a2, a3, a4); 63 } else { 64 retv = sal_vfprintf(file_fp, format, args); 65 sal_fflush(file_fp); 66 } 67 } 68 FILE_UNLOCK; 69 return retv; 70 } 71 72 STATIC int 73 bslfile_check(bsl_meta_t *meta) 74 { 75 return (file_fp != NULL); 76 } 77 78 STATIC int 79 bslfile_cleanup(struct bslsink_sink_s *sink) 80 { 81 if (file_nm) { 82 bslfile_close(); 83 } 84 sal_mutex_destroy(file_lock); 85 file_lock = NULL; 86 return 0; 87 } 88 89 FILE * 90 bslfile_fp(void) 91 { 92 return file_fp; 93 } 94 95 #endif /* NO_FILEIO */ 96 97 int 98 bslfile_init(void) 99 { 100 #ifndef NO_FILEIO 101 bslsink_sink_t *sink; 102 103 /* Create mutex */ 104 file_lock = sal_mutex_create("BSLFILE MUTEX"); 105 if (file_lock == NULL) { 106 sal_printf("bslfile: Mutex create error\n"); 107 return -1; 108 } 109 110 /* Create logfile sink */ 111 sink = &logfile_sink; 112 bslsink_sink_t_init(sink); 113 sal_strncpy(sink->name, "logfile", sizeof(sink->name)); 114 sink->vfprintf = bslfile_vfprintf; 115 sink->check = bslfile_check; 116 sink->cleanup = bslfile_cleanup; 117 sink->enable_range.min = bslSeverityOff+1; 118 sink->enable_range.max = bslSeverityCount-1; 119 120 /* Configure log prefix */ 121 sal_strncpy(sink->prefix_format, "%u:%F: ", 122 sizeof(sink->prefix_format)); 123 sink->prefix_range.min = bslSeverityOff+1; 124 sink->prefix_range.max = bslSeverityWarn; 125 126 bslsink_sink_add(sink); 127 #endif 128 129 return 0; 130 } 131 132 char * 133 bslfile_name(void) 134 { 135 #ifdef NO_FILEIO 136 return "<no filesystem>"; 137 #else 138 return(file_nm); 139 #endif 140 } 141 142 int 143 bslfile_close(void) 144 { 145 #ifndef NO_FILEIO 146 FILE_LOCK; 147 if (file_nm) { 148 sal_free(file_nm); 149 file_nm = NULL; 150 } 151 if (file_fp) { 152 sal_fclose(file_fp); 153 file_fp = 0; 154 } 155 FILE_UNLOCK; 156 #endif 157 return 0; 158 } 159 160 int 161 bslfile_open(char *filename, int append) 162 { 163 #ifndef NO_FILEIO 164 FILE_LOCK; 165 if (file_nm) { 166 bslfile_close(); 167 } 168 if ((file_fp = sal_fopen(filename, append ? "a" : "w")) == 0) { 169 sal_printf("bslfile: File open error\n"); 170 FILE_UNLOCK; 171 return -1; 172 } 173 file_nm = sal_strdup(filename); 174 if (file_nm == NULL) { 175 bslfile_close(); 176 sal_printf("bslfile: strdup failed\n"); 177 FILE_UNLOCK; 178 return -1; 179 } 180 FILE_UNLOCK; 181 #endif /* NO_FILEIO */ 182 return 0; 183 } 184 185 int 186 bslfile_is_enabled(void) 187 { 188 #ifndef NO_FILEIO 189 if (file_fp != NULL) { 190 return 1; 191 } 192 #endif 193 return 0; 194 } 195 196 int 197 bslfile_enable(int enable) 198 { 199 int cur_enable = bslfile_is_enabled(); 200 #ifndef NO_FILEIO 201 FILE_LOCK; 202 if (file_fp == NULL && enable) { 203 if (file_nm == NULL) { 204 sal_printf("bslfile: No log file\n"); 205 FILE_UNLOCK; 206 return -1; 207 } 208 if ((file_fp = sal_fopen(file_nm, "a")) == 0) { 209 sal_printf("bslfile: File open error\n"); 210 FILE_UNLOCK; 211 return -1; 212 } 213 } 214 215 if (file_fp != NULL && !enable) { 216 bslfile_close(); 217 } 218 FILE_UNLOCK; 219 #endif 220 return cur_enable; 221 }