Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2016, Citrix Systems, Inc.
3 : : *
4 : : * All rights reserved.
5 : : *
6 : : * Redistribution and use in source and binary forms, with or without
7 : : * modification, are permitted provided that the following conditions are met:
8 : : *
9 : : * 1. Redistributions of source code must retain the above copyright
10 : : * notice, this list of conditions and the following disclaimer.
11 : : * 2. Redistributions in binary form must reproduce the above copyright
12 : : * notice, this list of conditions and the following disclaimer in the
13 : : * documentation and/or other materials provided with the distribution.
14 : : * 3. Neither the name of the copyright holder nor the names of its
15 : : * contributors may be used to endorse or promote products derived from
16 : : * this software without specific prior written permission.
17 : : *
18 : : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 : : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 : : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 : : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22 : : * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 : : * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 : : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 : : * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 : : * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 : : * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 : : * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 : : */
30 : :
31 : : #ifdef HAVE_CONFIG_H
32 : : #include "config.h"
33 : : #endif
34 : :
35 : : #include <stdlib.h>
36 : : #include <unistd.h>
37 : : #include <errno.h>
38 : : #include <stdarg.h>
39 : : #include <syslog.h>
40 : : #include <sys/time.h>
41 : : #include <sys/stat.h>
42 : : #include <sys/types.h>
43 : : #include <stdbool.h>
44 : :
45 : : #include "tapdisk-log.h"
46 : : #include "tapdisk-utils.h"
47 : : #include "tapdisk-logfile.h"
48 : : #include "tapdisk-syslog.h"
49 : : #include "tapdisk-server.h"
50 : :
51 : : #define TLOG_LOGFILE_BUFSZ (16<<10)
52 : : #define TLOG_SYSLOG_BUFSZ (8<<10)
53 : :
54 : : #define MAX_ENTRY_LEN 512
55 : :
56 : : struct tlog {
57 : : char *name;
58 : : td_logfile_t logfile;
59 : : int precious;
60 : : int level;
61 : :
62 : : char *ident;
63 : : td_syslog_t syslog;
64 : : unsigned long errors;
65 : : int facility;
66 : : };
67 : :
68 : : static struct tlog tapdisk_log;
69 : :
70 : : static void
71 : : tlog_logfile_vprint(const char *fmt, va_list ap)
72 : : {
73 : 0 : tapdisk_logfile_vprintf(&tapdisk_log.logfile, fmt, ap);
74 : : }
75 : :
76 : : static void __printf(1, 2)
77 : 0 : tlog_logfile_print(const char *fmt, ...)
78 : : {
79 : : va_list ap;
80 : :
81 : 0 : va_start(ap, fmt);
82 : : tlog_logfile_vprint(fmt, ap);
83 : 0 : va_end(ap);
84 : 0 : }
85 : :
86 : : #define tlog_info(_fmt, _args ...) \
87 : : tlog_logfile_print("%s: "_fmt, tapdisk_log.ident, ##_args)
88 : :
89 : : /**
90 : : * Closes the log file.
91 : : *
92 : : * @param keep if set to true the log file is never removed. NB if an error has
93 : : * occurred or a USR1 has been received the log is always kept, independently
94 : : * of whether @keep is set to false.
95 : : */
96 : : static void
97 : 0 : tlog_logfile_close(bool keep)
98 : : {
99 : 0 : td_logfile_t *logfile = &tapdisk_log.logfile;
100 : :
101 [ # # ][ # # ]: 0 : if (tapdisk_log.precious || tapdisk_log.errors)
102 : 0 : keep = true;
103 : :
104 : 0 : tlog_info("closing log, %lu errors", tapdisk_log.errors);
105 : :
106 : 0 : tapdisk_logfile_close(logfile);
107 : :
108 [ # # ]: 0 : if (!keep)
109 : 0 : tapdisk_logfile_unlink(logfile);
110 : 0 : }
111 : :
112 : : static int
113 : 0 : tlog_logfile_open(const char *name, int level)
114 : : {
115 : 0 : td_logfile_t *logfile = &tapdisk_log.logfile;
116 : : int mode, err;
117 : :
118 : 0 : err = mkdir(TLOG_DIR, 0755);
119 [ # # ]: 0 : if (err) {
120 : 0 : err = -errno;
121 [ # # ]: 0 : if (err != -EEXIST)
122 : : goto fail;
123 : : }
124 : :
125 : 0 : err = tapdisk_logfile_open(logfile, TLOG_DIR, name, TLOG_LOGFILE_BUFSZ);
126 [ # # ]: 0 : if (err)
127 : : goto fail;
128 : :
129 : 0 : mode = (level == TLOG_DBG) ? _IOLBF : _IOFBF;
130 : :
131 : 0 : err = tapdisk_logfile_setvbuf(logfile, mode);
132 [ # # ]: 0 : if (err)
133 : : goto fail;
134 : :
135 : 0 : tlog_info("log start, level %d", level);
136 : :
137 : 0 : return 0;
138 : :
139 : : fail:
140 : 0 : tlog_logfile_close(false);
141 : 0 : return err;
142 : : }
143 : :
144 : : static void
145 : 0 : tlog_syslog_close(void)
146 : : {
147 : 0 : td_syslog_t *syslog = &tapdisk_log.syslog;
148 : :
149 : 0 : tapdisk_syslog_stats(syslog, LOG_INFO);
150 : 0 : tapdisk_syslog_flush(syslog);
151 : 0 : tapdisk_syslog_close(syslog);
152 : 0 : }
153 : :
154 : : static int
155 : 0 : tlog_syslog_open(const char *ident, int facility)
156 : : {
157 : 0 : td_syslog_t *syslog = &tapdisk_log.syslog;
158 : : int err;
159 : :
160 : 0 : err = tapdisk_syslog_open(syslog,
161 : 0 : tapdisk_log.ident, facility,
162 : : TLOG_SYSLOG_BUFSZ);
163 : 0 : return err;
164 : : }
165 : :
166 : : void
167 : 0 : tlog_vsyslog(int prio, const char *fmt, va_list ap)
168 : : {
169 : 0 : td_syslog_t *syslog = &tapdisk_log.syslog;
170 : :
171 : 0 : tapdisk_vsyslog(syslog, prio, fmt, ap);
172 : 0 : }
173 : :
174 : : void
175 : 0 : tlog_syslog(int prio, const char *fmt, ...)
176 : : {
177 : : va_list ap;
178 : : static const int tlog_to_syslog[3] = {LOG_WARNING, LOG_INFO, LOG_DEBUG};
179 : :
180 [ # # ]: 0 : prio = prio >= 0 && prio < 3 ? tlog_to_syslog[prio] : LOG_INFO;
181 : :
182 : 0 : va_start(ap, fmt);
183 : 0 : tlog_vsyslog(prio, fmt, ap);
184 : 0 : va_end(ap);
185 : 0 : }
186 : :
187 : : int
188 : 0 : tlog_open(const char *name, int facility, int level)
189 : : {
190 : : int err;
191 : :
192 : : DPRINTF("tapdisk-log: started, level %d\n", level);
193 : :
194 : 0 : tapdisk_log.level = level;
195 : 0 : tapdisk_log.name = strdup(name);
196 : 0 : tapdisk_log.ident = tapdisk_syslog_ident(name);
197 : 0 : tapdisk_log.facility = facility;
198 : :
199 [ # # ][ # # ]: 0 : if (!tapdisk_log.name || !tapdisk_log.ident) {
200 : 0 : err = -errno;
201 : 0 : goto fail;
202 : : }
203 : :
204 : 0 : err = tlog_logfile_open(tapdisk_log.name, level);
205 [ # # ]: 0 : if (err)
206 : : goto fail;
207 : :
208 : 0 : err = tlog_syslog_open(tapdisk_log.ident, facility);
209 [ # # ]: 0 : if (err)
210 : : goto fail;
211 : :
212 : : return 0;
213 : :
214 : : fail:
215 : 0 : EPRINTF("tapdisk-log: failed %d\n", errno);
216 : 0 : tlog_close();
217 : 0 : return err;
218 : : }
219 : :
220 : : int
221 : 0 : tlog_reopen(void)
222 : : {
223 : : int err;
224 : :
225 : 0 : tlog_logfile_close(true);
226 : 0 : err = tlog_logfile_open(tapdisk_log.name, tapdisk_log.level);
227 [ # # ]: 0 : if (err)
228 : : return err;
229 : :
230 : 0 : tlog_syslog_close();
231 : 0 : return tlog_syslog_open(tapdisk_log.ident, tapdisk_log.facility);
232 : : }
233 : :
234 : : void
235 : 0 : tlog_close(void)
236 : : {
237 : 0 : DPRINTF("tapdisk-log: closing after %lu errors\n",
238 : : tapdisk_log.errors);
239 : :
240 : 0 : tlog_logfile_close(false);
241 : 0 : tlog_syslog_close();
242 : :
243 : 0 : free(tapdisk_log.ident);
244 : 0 : tapdisk_log.ident = NULL;
245 : 0 : }
246 : :
247 : : void
248 : 0 : tlog_precious(int force_flush)
249 : : {
250 [ # # ][ # # ]: 0 : if (!tapdisk_log.precious || force_flush)
251 : 0 : tapdisk_logfile_flush(&tapdisk_log.logfile);
252 : :
253 : 0 : tapdisk_log.precious = 1;
254 : 0 : }
255 : :
256 : : void
257 : 2 : __tlog_write(int level, const char *fmt, ...)
258 : : {
259 : : va_list ap;
260 : :
261 [ - + ]: 2 : if (level <= tapdisk_log.level) {
262 : 0 : va_start(ap, fmt);
263 : : tlog_logfile_vprint(fmt, ap);
264 : 0 : va_end(ap);
265 : : }
266 : 2 : }
267 : :
268 : : void
269 : 0 : __tlog_error(const char *fmt, ...)
270 : : {
271 : : va_list ap;
272 : :
273 : 0 : va_start(ap, fmt);
274 : 0 : tlog_vsyslog(LOG_ERR, fmt, ap);
275 : 0 : va_end(ap);
276 : :
277 : 0 : tapdisk_log.errors++;
278 : 0 : }
279 : :
280 : : void
281 : 0 : tapdisk_start_logging(const char *ident, const char *_facility)
282 : : {
283 : : int facility;
284 : :
285 : 0 : facility = tapdisk_syslog_facility(_facility);
286 : 0 : tapdisk_server_openlog(ident, LOG_CONS|LOG_ODELAY, facility);
287 : 0 : }
288 : :
289 : : void
290 : 0 : tapdisk_stop_logging(void)
291 : : {
292 : 0 : tapdisk_server_closelog();
293 : 0 : }
|