root / drivers / tapdisk-logfile.c @ master
History | View | Annotate | Download (5.4 kB)
1 | abdb293f | Chrysostomos Nanakos | /*
|
---|---|---|---|
2 | abdb293f | Chrysostomos Nanakos | * Copyright (c) 2009, XenSource Inc.
|
3 | abdb293f | Chrysostomos Nanakos | * All rights reserved.
|
4 | abdb293f | Chrysostomos Nanakos | *
|
5 | abdb293f | Chrysostomos Nanakos | * Redistribution and use in source and binary forms, with or without
|
6 | abdb293f | Chrysostomos Nanakos | * modification, are permitted provided that the following conditions are met:
|
7 | abdb293f | Chrysostomos Nanakos | * * Redistributions of source code must retain the above copyright
|
8 | abdb293f | Chrysostomos Nanakos | * notice, this list of conditions and the following disclaimer.
|
9 | abdb293f | Chrysostomos Nanakos | * * Redistributions in binary form must reproduce the above copyright
|
10 | abdb293f | Chrysostomos Nanakos | * notice, this list of conditions and the following disclaimer in the
|
11 | abdb293f | Chrysostomos Nanakos | * documentation and/or other materials provided with the distribution.
|
12 | abdb293f | Chrysostomos Nanakos | * * Neither the name of XenSource Inc. nor the names of its contributors
|
13 | abdb293f | Chrysostomos Nanakos | * may be used to endorse or promote products derived from this software
|
14 | abdb293f | Chrysostomos Nanakos | * without specific prior written permission.
|
15 | abdb293f | Chrysostomos Nanakos | *
|
16 | abdb293f | Chrysostomos Nanakos | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
17 | abdb293f | Chrysostomos Nanakos | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
18 | abdb293f | Chrysostomos Nanakos | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
19 | abdb293f | Chrysostomos Nanakos | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
20 | abdb293f | Chrysostomos Nanakos | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
21 | abdb293f | Chrysostomos Nanakos | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
22 | abdb293f | Chrysostomos Nanakos | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
23 | abdb293f | Chrysostomos Nanakos | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
24 | abdb293f | Chrysostomos Nanakos | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
25 | abdb293f | Chrysostomos Nanakos | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 | abdb293f | Chrysostomos Nanakos | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 | abdb293f | Chrysostomos Nanakos | */
|
28 | abdb293f | Chrysostomos Nanakos | |
29 | abdb293f | Chrysostomos Nanakos | #ifdef HAVE_CONFIG_H
|
30 | abdb293f | Chrysostomos Nanakos | #include "config.h" |
31 | abdb293f | Chrysostomos Nanakos | #endif
|
32 | abdb293f | Chrysostomos Nanakos | |
33 | abdb293f | Chrysostomos Nanakos | #include <stdlib.h> |
34 | abdb293f | Chrysostomos Nanakos | #include <string.h> |
35 | abdb293f | Chrysostomos Nanakos | #include <unistd.h> |
36 | abdb293f | Chrysostomos Nanakos | #include <errno.h> |
37 | abdb293f | Chrysostomos Nanakos | #include <time.h> |
38 | abdb293f | Chrysostomos Nanakos | #include <stdarg.h> |
39 | abdb293f | Chrysostomos Nanakos | #include <sys/time.h> |
40 | abdb293f | Chrysostomos Nanakos | #include <sys/mman.h> |
41 | abdb293f | Chrysostomos Nanakos | |
42 | abdb293f | Chrysostomos Nanakos | #include "tapdisk-logfile.h" |
43 | abdb293f | Chrysostomos Nanakos | #include "tapdisk-utils.h" |
44 | abdb293f | Chrysostomos Nanakos | |
45 | abdb293f | Chrysostomos Nanakos | #define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
46 | abdb293f | Chrysostomos Nanakos | |
47 | abdb293f | Chrysostomos Nanakos | static inline size_t |
48 | abdb293f | Chrysostomos Nanakos | page_align(size_t size) |
49 | abdb293f | Chrysostomos Nanakos | { |
50 | abdb293f | Chrysostomos Nanakos | size_t page_size = sysconf(_SC_PAGE_SIZE); |
51 | abdb293f | Chrysostomos Nanakos | return (size + page_size - 1) & ~(page_size - 1); |
52 | abdb293f | Chrysostomos Nanakos | } |
53 | abdb293f | Chrysostomos Nanakos | |
54 | abdb293f | Chrysostomos Nanakos | static void |
55 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_free_buffer(td_logfile_t *log) |
56 | abdb293f | Chrysostomos Nanakos | { |
57 | abdb293f | Chrysostomos Nanakos | if (log->vbuf) {
|
58 | abdb293f | Chrysostomos Nanakos | munmap(log->vbuf, page_align(log->vbufsz)); |
59 | abdb293f | Chrysostomos Nanakos | log->vbuf = NULL;
|
60 | abdb293f | Chrysostomos Nanakos | } |
61 | abdb293f | Chrysostomos Nanakos | } |
62 | abdb293f | Chrysostomos Nanakos | |
63 | abdb293f | Chrysostomos Nanakos | static int |
64 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_init_buffer(td_logfile_t *log, size_t size) |
65 | abdb293f | Chrysostomos Nanakos | { |
66 | abdb293f | Chrysostomos Nanakos | int prot, flags, err;
|
67 | abdb293f | Chrysostomos Nanakos | |
68 | abdb293f | Chrysostomos Nanakos | if (!size)
|
69 | abdb293f | Chrysostomos Nanakos | return -EINVAL;
|
70 | abdb293f | Chrysostomos Nanakos | |
71 | abdb293f | Chrysostomos Nanakos | prot = PROT_READ|PROT_WRITE; |
72 | abdb293f | Chrysostomos Nanakos | flags = MAP_ANONYMOUS|MAP_PRIVATE; |
73 | abdb293f | Chrysostomos Nanakos | |
74 | abdb293f | Chrysostomos Nanakos | log->vbuf = mmap(NULL, page_align(size), prot, flags, -1, 0); |
75 | abdb293f | Chrysostomos Nanakos | if (log->vbuf == MAP_FAILED) {
|
76 | abdb293f | Chrysostomos Nanakos | log->vbuf = NULL;
|
77 | abdb293f | Chrysostomos Nanakos | goto fail;
|
78 | abdb293f | Chrysostomos Nanakos | } |
79 | abdb293f | Chrysostomos Nanakos | |
80 | abdb293f | Chrysostomos Nanakos | err = mlock(log->vbuf, page_align(size)); |
81 | abdb293f | Chrysostomos Nanakos | if (err)
|
82 | abdb293f | Chrysostomos Nanakos | goto fail;
|
83 | abdb293f | Chrysostomos Nanakos | |
84 | abdb293f | Chrysostomos Nanakos | log->vbufsz = size; |
85 | abdb293f | Chrysostomos Nanakos | |
86 | abdb293f | Chrysostomos Nanakos | return 0; |
87 | abdb293f | Chrysostomos Nanakos | |
88 | abdb293f | Chrysostomos Nanakos | fail:
|
89 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_free_buffer(log); |
90 | abdb293f | Chrysostomos Nanakos | err = -errno; |
91 | abdb293f | Chrysostomos Nanakos | return err;
|
92 | abdb293f | Chrysostomos Nanakos | } |
93 | abdb293f | Chrysostomos Nanakos | |
94 | abdb293f | Chrysostomos Nanakos | int
|
95 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_unlink(td_logfile_t *log) |
96 | abdb293f | Chrysostomos Nanakos | { |
97 | abdb293f | Chrysostomos Nanakos | int err;
|
98 | abdb293f | Chrysostomos Nanakos | |
99 | abdb293f | Chrysostomos Nanakos | err = unlink(log->path); |
100 | abdb293f | Chrysostomos Nanakos | if (err)
|
101 | abdb293f | Chrysostomos Nanakos | err = -errno; |
102 | abdb293f | Chrysostomos Nanakos | |
103 | abdb293f | Chrysostomos Nanakos | return err;
|
104 | abdb293f | Chrysostomos Nanakos | } |
105 | abdb293f | Chrysostomos Nanakos | |
106 | abdb293f | Chrysostomos Nanakos | static int |
107 | abdb293f | Chrysostomos Nanakos | __tapdisk_logfile_rename(td_logfile_t *log, const char *newpath) |
108 | abdb293f | Chrysostomos Nanakos | { |
109 | abdb293f | Chrysostomos Nanakos | const size_t max = sizeof(log->path); |
110 | abdb293f | Chrysostomos Nanakos | int err;
|
111 | abdb293f | Chrysostomos Nanakos | |
112 | abdb293f | Chrysostomos Nanakos | if (!strcmp(log->path, newpath))
|
113 | abdb293f | Chrysostomos Nanakos | return 0; |
114 | abdb293f | Chrysostomos Nanakos | |
115 | abdb293f | Chrysostomos Nanakos | if (strlen(newpath) > max)
|
116 | abdb293f | Chrysostomos Nanakos | return -ENAMETOOLONG;
|
117 | abdb293f | Chrysostomos Nanakos | |
118 | abdb293f | Chrysostomos Nanakos | err = rename(log->path, newpath); |
119 | abdb293f | Chrysostomos Nanakos | if (err) {
|
120 | abdb293f | Chrysostomos Nanakos | err = -errno; |
121 | abdb293f | Chrysostomos Nanakos | return err;
|
122 | abdb293f | Chrysostomos Nanakos | } |
123 | abdb293f | Chrysostomos Nanakos | |
124 | abdb293f | Chrysostomos Nanakos | strncpy(log->path, newpath, max); |
125 | abdb293f | Chrysostomos Nanakos | |
126 | abdb293f | Chrysostomos Nanakos | return 0; |
127 | abdb293f | Chrysostomos Nanakos | } |
128 | abdb293f | Chrysostomos Nanakos | |
129 | abdb293f | Chrysostomos Nanakos | static int |
130 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_name(char *path, size_t size,
|
131 | abdb293f | Chrysostomos Nanakos | const char *dir, const char *ident, const char *suffix) |
132 | abdb293f | Chrysostomos Nanakos | { |
133 | abdb293f | Chrysostomos Nanakos | const size_t max = MIN(size, TD_LOGFILE_PATH_MAX);
|
134 | abdb293f | Chrysostomos Nanakos | return snprintf(path, max, "%s/%s.%d%s", dir, ident, getpid(), suffix); |
135 | abdb293f | Chrysostomos Nanakos | } |
136 | abdb293f | Chrysostomos Nanakos | |
137 | abdb293f | Chrysostomos Nanakos | int
|
138 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_rename(td_logfile_t *log, |
139 | abdb293f | Chrysostomos Nanakos | const char *dir, const char *ident, const char *suffix) |
140 | abdb293f | Chrysostomos Nanakos | { |
141 | abdb293f | Chrysostomos Nanakos | char newpath[TD_LOGFILE_PATH_MAX+1]; |
142 | abdb293f | Chrysostomos Nanakos | |
143 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_name(newpath, sizeof(newpath), dir, ident, suffix);
|
144 | abdb293f | Chrysostomos Nanakos | |
145 | abdb293f | Chrysostomos Nanakos | return __tapdisk_logfile_rename(log, newpath);
|
146 | abdb293f | Chrysostomos Nanakos | } |
147 | abdb293f | Chrysostomos Nanakos | |
148 | abdb293f | Chrysostomos Nanakos | void
|
149 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_close(td_logfile_t *log) |
150 | abdb293f | Chrysostomos Nanakos | { |
151 | abdb293f | Chrysostomos Nanakos | if (log->file) {
|
152 | abdb293f | Chrysostomos Nanakos | fclose(log->file); |
153 | abdb293f | Chrysostomos Nanakos | log->file = NULL;
|
154 | abdb293f | Chrysostomos Nanakos | } |
155 | abdb293f | Chrysostomos Nanakos | |
156 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_free_buffer(log); |
157 | abdb293f | Chrysostomos Nanakos | } |
158 | abdb293f | Chrysostomos Nanakos | |
159 | abdb293f | Chrysostomos Nanakos | int
|
160 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_open(td_logfile_t *log, |
161 | abdb293f | Chrysostomos Nanakos | const char *dir, const char *ident, const char *ext, |
162 | abdb293f | Chrysostomos Nanakos | size_t bufsz) |
163 | abdb293f | Chrysostomos Nanakos | { |
164 | abdb293f | Chrysostomos Nanakos | int err;
|
165 | abdb293f | Chrysostomos Nanakos | |
166 | abdb293f | Chrysostomos Nanakos | memset(log, 0, sizeof(log)); |
167 | abdb293f | Chrysostomos Nanakos | |
168 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_name(log->path, sizeof(log->path), dir, ident, ext);
|
169 | abdb293f | Chrysostomos Nanakos | |
170 | abdb293f | Chrysostomos Nanakos | log->file = fopen(log->path, "w");
|
171 | abdb293f | Chrysostomos Nanakos | if (!log->file) {
|
172 | abdb293f | Chrysostomos Nanakos | err = -errno; |
173 | abdb293f | Chrysostomos Nanakos | goto fail;
|
174 | abdb293f | Chrysostomos Nanakos | } |
175 | abdb293f | Chrysostomos Nanakos | |
176 | abdb293f | Chrysostomos Nanakos | err = tapdisk_logfile_init_buffer(log, bufsz); |
177 | abdb293f | Chrysostomos Nanakos | if (err)
|
178 | abdb293f | Chrysostomos Nanakos | goto fail;
|
179 | abdb293f | Chrysostomos Nanakos | |
180 | abdb293f | Chrysostomos Nanakos | return 0; |
181 | abdb293f | Chrysostomos Nanakos | |
182 | abdb293f | Chrysostomos Nanakos | fail:
|
183 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_unlink(log); |
184 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_close(log); |
185 | abdb293f | Chrysostomos Nanakos | return err;
|
186 | abdb293f | Chrysostomos Nanakos | } |
187 | abdb293f | Chrysostomos Nanakos | |
188 | abdb293f | Chrysostomos Nanakos | int
|
189 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_setvbuf(td_logfile_t *log, int mode)
|
190 | abdb293f | Chrysostomos Nanakos | { |
191 | abdb293f | Chrysostomos Nanakos | int err = 0; |
192 | abdb293f | Chrysostomos Nanakos | |
193 | abdb293f | Chrysostomos Nanakos | if (log->file) {
|
194 | abdb293f | Chrysostomos Nanakos | err = setvbuf(log->file, log->vbuf, mode, log->vbufsz); |
195 | abdb293f | Chrysostomos Nanakos | if (err)
|
196 | abdb293f | Chrysostomos Nanakos | err = -errno; |
197 | abdb293f | Chrysostomos Nanakos | } |
198 | abdb293f | Chrysostomos Nanakos | |
199 | abdb293f | Chrysostomos Nanakos | return err;
|
200 | abdb293f | Chrysostomos Nanakos | } |
201 | abdb293f | Chrysostomos Nanakos | |
202 | abdb293f | Chrysostomos Nanakos | ssize_t |
203 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_vprintf(td_logfile_t *log, const char *fmt, va_list ap) |
204 | abdb293f | Chrysostomos Nanakos | { |
205 | abdb293f | Chrysostomos Nanakos | char buf[1024]; |
206 | abdb293f | Chrysostomos Nanakos | size_t size, n; |
207 | abdb293f | Chrysostomos Nanakos | ssize_t len; |
208 | abdb293f | Chrysostomos Nanakos | struct timeval tv;
|
209 | abdb293f | Chrysostomos Nanakos | |
210 | abdb293f | Chrysostomos Nanakos | if (!log->file)
|
211 | abdb293f | Chrysostomos Nanakos | return -EBADF;
|
212 | abdb293f | Chrysostomos Nanakos | |
213 | abdb293f | Chrysostomos Nanakos | gettimeofday(&tv, NULL);
|
214 | abdb293f | Chrysostomos Nanakos | |
215 | abdb293f | Chrysostomos Nanakos | size = sizeof(buf);
|
216 | abdb293f | Chrysostomos Nanakos | len = 0;
|
217 | abdb293f | Chrysostomos Nanakos | |
218 | abdb293f | Chrysostomos Nanakos | len += tapdisk_syslog_strftime(buf, size, &tv); |
219 | abdb293f | Chrysostomos Nanakos | len += snprintf(buf + len, size - len, ": ");
|
220 | abdb293f | Chrysostomos Nanakos | len += tapdisk_syslog_strftv(buf + len, size - len, &tv); |
221 | abdb293f | Chrysostomos Nanakos | len += snprintf(buf + len, size - len, " ");
|
222 | abdb293f | Chrysostomos Nanakos | len += vsnprintf(buf + len, size - len, fmt, ap); |
223 | abdb293f | Chrysostomos Nanakos | |
224 | abdb293f | Chrysostomos Nanakos | if (buf[len-1] != '\n') |
225 | abdb293f | Chrysostomos Nanakos | len += snprintf(buf + len, size - len, "\n");
|
226 | abdb293f | Chrysostomos Nanakos | |
227 | abdb293f | Chrysostomos Nanakos | n = fwrite(buf, len, 1, log->file);
|
228 | abdb293f | Chrysostomos Nanakos | if (n != len)
|
229 | abdb293f | Chrysostomos Nanakos | len = -ferror(log->file); |
230 | abdb293f | Chrysostomos Nanakos | |
231 | abdb293f | Chrysostomos Nanakos | return len;
|
232 | abdb293f | Chrysostomos Nanakos | } |
233 | abdb293f | Chrysostomos Nanakos | |
234 | abdb293f | Chrysostomos Nanakos | ssize_t |
235 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_printf(td_logfile_t *log, const char *fmt, ...) |
236 | abdb293f | Chrysostomos Nanakos | { |
237 | abdb293f | Chrysostomos Nanakos | va_list ap; |
238 | abdb293f | Chrysostomos Nanakos | int rv;
|
239 | abdb293f | Chrysostomos Nanakos | |
240 | abdb293f | Chrysostomos Nanakos | va_start(ap, fmt); |
241 | abdb293f | Chrysostomos Nanakos | rv = tapdisk_logfile_vprintf(log, fmt, ap); |
242 | abdb293f | Chrysostomos Nanakos | va_end(ap); |
243 | abdb293f | Chrysostomos Nanakos | |
244 | abdb293f | Chrysostomos Nanakos | return rv;
|
245 | abdb293f | Chrysostomos Nanakos | } |
246 | abdb293f | Chrysostomos Nanakos | |
247 | abdb293f | Chrysostomos Nanakos | int
|
248 | abdb293f | Chrysostomos Nanakos | tapdisk_logfile_flush(td_logfile_t *log) |
249 | abdb293f | Chrysostomos Nanakos | { |
250 | abdb293f | Chrysostomos Nanakos | int rv = EOF; |
251 | abdb293f | Chrysostomos Nanakos | |
252 | abdb293f | Chrysostomos Nanakos | if (log->file)
|
253 | abdb293f | Chrysostomos Nanakos | rv = fflush(log->file); |
254 | abdb293f | Chrysostomos Nanakos | |
255 | abdb293f | Chrysostomos Nanakos | return rv;
|
256 | abdb293f | Chrysostomos Nanakos | } |