Statistics
| Branch: | Revision:

root / drivers / tapdisk-log.c @ abdb293f

History | View | Annotate | Download (5.9 kB)

1
/*
2
 * Copyright (c) 2008, 2009, XenSource Inc.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *     * Redistributions of source code must retain the above copyright
8
 *       notice, this list of conditions and the following disclaimer.
9
 *     * Redistributions in binary form must reproduce the above copyright
10
 *       notice, this list of conditions and the following disclaimer in the
11
 *       documentation and/or other materials provided with the distribution.
12
 *     * Neither the name of XenSource Inc. nor the names of its contributors
13
 *       may be used to endorse or promote products derived from this software
14
 *       without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28

    
29
#ifdef HAVE_CONFIG_H
30
#include "config.h"
31
#endif
32

    
33
#include <stdlib.h>
34
#include <unistd.h>
35
#include <errno.h>
36
#include <stdarg.h>
37
#include <syslog.h>
38
#include <sys/time.h>
39
#include <sys/stat.h>
40
#include <sys/types.h>
41

    
42
#include "tapdisk-log.h"
43
#include "tapdisk-utils.h"
44
#include "tapdisk-logfile.h"
45
#include "tapdisk-syslog.h"
46
#include "tapdisk-server.h"
47

    
48
#define TLOG_LOGFILE_BUFSZ (16<<10)
49
#define TLOG_SYSLOG_BUFSZ   (8<<10)
50

    
51
#define MAX_ENTRY_LEN      512
52

    
53
struct tlog {
54
        char          *name;
55
        td_logfile_t   logfile;
56
        int            precious;
57
        int            level;
58

    
59
        char          *ident;
60
        td_syslog_t    syslog;
61
        unsigned long  errors;
62
};
63

    
64
static struct tlog tapdisk_log;
65

    
66
static void
67
tlog_logfile_vprint(const char *fmt, va_list ap)
68
{
69
        tapdisk_logfile_vprintf(&tapdisk_log.logfile, fmt, ap);
70
}
71

    
72
static void __printf(1, 2)
73
tlog_logfile_print(const char *fmt, ...)
74
{
75
        va_list ap;
76

    
77
        va_start(ap, fmt);
78
        tlog_logfile_vprint(fmt, ap);
79
        va_end(ap);
80
}
81

    
82
#define tlog_info(_fmt, _args ...)                                        \
83
        tlog_logfile_print("%s: "_fmt, tapdisk_log.ident, ##_args)
84

    
85
static void
86
tlog_logfile_save(void)
87
{
88
        td_logfile_t *logfile = &tapdisk_log.logfile;
89
        const char *name = tapdisk_log.name;
90
        int err;
91

    
92
        tlog_info("saving log, %lu errors", tapdisk_log.errors);
93

    
94
        tapdisk_logfile_flush(logfile);
95

    
96
        err = tapdisk_logfile_rename(logfile,
97
                                     TLOG_DIR, name, ".log");
98

    
99
        tlog_syslog(LOG_INFO,
100
                    "logfile saved to %s: %d\n", logfile->path, err);
101
}
102

    
103
static void
104
tlog_logfile_close(void)
105
{
106
        td_logfile_t *logfile = &tapdisk_log.logfile;
107
        int keep;
108

    
109
        keep = tapdisk_log.precious || tapdisk_log.errors;
110

    
111
        tlog_info("closing log, %lu errors", tapdisk_log.errors);
112

    
113
        if (keep)
114
                tlog_logfile_save();
115

    
116
        tapdisk_logfile_close(logfile);
117

    
118
        if (!keep)
119
                tapdisk_logfile_unlink(logfile);
120
}
121

    
122
static int
123
tlog_logfile_open(const char *name, int level)
124
{
125
        td_logfile_t *logfile = &tapdisk_log.logfile;
126
        int mode, err;
127

    
128
        err = mkdir(TLOG_DIR, 0755);
129
        if (err) {
130
                err = -errno;
131
                if (err != -EEXIST)
132
                        goto fail;
133
        }
134

    
135
        err = tapdisk_logfile_open(logfile,
136
                                   TLOG_DIR, name, ".tmp",
137
                                   TLOG_LOGFILE_BUFSZ);
138
        if (err)
139
                goto fail;
140

    
141
        mode = (level == TLOG_DBG) ? _IOLBF : _IOFBF;
142

    
143
        err = tapdisk_logfile_setvbuf(logfile, mode);
144
        if (err)
145
                goto fail;
146

    
147
        tlog_info("log start, level %d", level);
148

    
149
        return 0;
150

    
151
fail:
152
        tlog_logfile_close();
153
        return err;
154
}
155

    
156
static void
157
tlog_syslog_close(void)
158
{
159
        td_syslog_t *syslog = &tapdisk_log.syslog;
160

    
161
        tapdisk_syslog_stats(syslog, LOG_INFO);
162
        tapdisk_syslog_flush(syslog);
163
        tapdisk_syslog_close(syslog);
164
}
165

    
166
static int
167
tlog_syslog_open(const char *ident, int facility)
168
{
169
        td_syslog_t *syslog = &tapdisk_log.syslog;
170
        int err;
171

    
172
        err = tapdisk_syslog_open(syslog,
173
                                  tapdisk_log.ident, facility,
174
                                  TLOG_SYSLOG_BUFSZ);
175
        return err;
176
}
177

    
178
void
179
tlog_vsyslog(int prio, const char *fmt, va_list ap)
180
{
181
        td_syslog_t *syslog = &tapdisk_log.syslog;
182

    
183
        tapdisk_vsyslog(syslog, prio, fmt, ap);
184
}
185

    
186
void
187
tlog_syslog(int prio, const char *fmt, ...)
188
{
189
        va_list ap;
190

    
191
        va_start(ap, fmt);
192
        tlog_vsyslog(prio, fmt, ap);
193
        va_end(ap);
194
}
195

    
196
int
197
tlog_open(const char *name, int facility, int level)
198
{
199
        int err;
200

    
201
        DPRINTF("tapdisk-log: started, level %d\n", level);
202

    
203
        tapdisk_log.level = level;
204
        tapdisk_log.name  = strdup(name);
205
        tapdisk_log.ident = tapdisk_syslog_ident(name);
206

    
207
        if (!tapdisk_log.name || !tapdisk_log.ident) {
208
                err = -errno;
209
                goto fail;
210
        }
211

    
212
        err = tlog_logfile_open(tapdisk_log.name, level);
213
        if (err)
214
                goto fail;
215

    
216
        err = tlog_syslog_open(tapdisk_log.ident, facility);
217
        if (err)
218
                goto fail;
219

    
220
        return 0;
221

    
222
fail:
223
        tlog_close();
224
        return err;
225
}
226

    
227
void
228
tlog_close(void)
229
{
230
        DPRINTF("tapdisk-log: closing after %lu errors\n",
231
                tapdisk_log.errors);
232

    
233
        tlog_logfile_close();
234
        tlog_syslog_close();
235

    
236
        free(tapdisk_log.ident);
237
        tapdisk_log.ident = NULL;
238
}
239

    
240
void
241
tlog_precious(void)
242
{
243
        if (!tapdisk_log.precious)
244
                tlog_logfile_save();
245

    
246
        tapdisk_log.precious = 1;
247
}
248

    
249
void
250
__tlog_write(int level, const char *fmt, ...)
251
{
252
        va_list ap;
253

    
254
        if (level <= tapdisk_log.level) {
255
                va_start(ap, fmt);
256
                tlog_logfile_vprint(fmt, ap);
257
                va_end(ap);
258
        }
259
}
260

    
261
void
262
__tlog_error(const char *fmt, ...)
263
{
264
        va_list ap;
265

    
266
        va_start(ap, fmt);
267
        tlog_vsyslog(LOG_ERR, fmt, ap);
268
        va_end(ap);
269

    
270
        tapdisk_log.errors++;
271
}
272

    
273
void
274
tapdisk_start_logging(const char *ident, const char *_facility)
275
{
276
        int facility;
277

    
278
        facility = tapdisk_syslog_facility(_facility);
279
        tapdisk_server_openlog(ident, LOG_CONS|LOG_ODELAY, facility);
280
}
281

    
282
void
283
tapdisk_stop_logging(void)
284
{
285
        tapdisk_server_closelog();
286
}