ia64/xen-unstable

view tools/blktap2/drivers/tapdisk-log.c @ 19817:b7f73a7f3078

blktap2: portability fixes for NetBSD

- Use standard off_t and lseek() instead of non-portable off64_t and
lseek64()
- Use uuid API as documented in DCE 1.1 RPC specification
- Add NetBSD implementation for blk_getimagesize() and
blk_getsectorsize()
- Use blk_getimagesize() and blk_getsectorsize()
- Fix uuid header check

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 23 17:24:14 2009 +0100 (2009-06-23)
parents 1c627434605e
children
line source
1 /*
2 * Copyright (c) 2008, 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 */
29 #include <stdio.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdarg.h>
35 #include <syslog.h>
36 #include <inttypes.h>
37 #include <sys/time.h>
39 #include "tapdisk-log.h"
41 #define MAX_ENTRY_LEN 512
42 #define MAX_ERROR_MESSAGES 16
44 struct error {
45 int cnt;
46 int err;
47 char *func;
48 char msg[MAX_ENTRY_LEN];
49 };
51 struct ehandle {
52 int cnt;
53 int dropped;
54 struct error errors[MAX_ERROR_MESSAGES];
55 };
57 struct tlog {
58 char *p;
59 int size;
60 uint64_t cnt;
61 char *buf;
62 int level;
63 char *file;
64 int append;
65 };
67 static struct ehandle tapdisk_err;
68 static struct tlog tapdisk_log;
70 void
71 open_tlog(char *file, size_t bytes, int level, int append)
72 {
73 tapdisk_log.size = ((bytes + 511) & (~511));
75 if (asprintf(&tapdisk_log.file, "%s.%d", file, getpid()) == -1)
76 return;
78 if (posix_memalign((void **)&tapdisk_log.buf, 512, tapdisk_log.size)) {
79 free(tapdisk_log.file);
80 tapdisk_log.buf = NULL;
81 return;
82 }
84 memset(tapdisk_log.buf, 0, tapdisk_log.size);
86 tapdisk_log.p = tapdisk_log.buf;
87 tapdisk_log.level = level;
88 tapdisk_log.append = append;
89 }
91 void
92 close_tlog(void)
93 {
94 if (!tapdisk_log.buf)
95 return;
97 if (tapdisk_log.append)
98 tlog_flush();
100 free(tapdisk_log.buf);
101 free(tapdisk_log.file);
103 memset(&tapdisk_log, 0, sizeof(struct tlog));
104 }
106 void
107 __tlog_write(int level, const char *func, const char *fmt, ...)
108 {
109 char *buf;
110 va_list ap;
111 struct timeval t;
112 int ret, len, avail;
114 if (!tapdisk_log.buf)
115 return;
117 if (level > tapdisk_log.level)
118 return;
120 avail = tapdisk_log.size - (tapdisk_log.p - tapdisk_log.buf);
121 if (avail < MAX_ENTRY_LEN) {
122 if (tapdisk_log.append)
123 tlog_flush();
124 tapdisk_log.p = tapdisk_log.buf;
125 }
127 buf = tapdisk_log.p;
128 gettimeofday(&t, NULL);
129 len = snprintf(buf, MAX_ENTRY_LEN - 1, "%08"PRIu64":%010ld.%06lld:"
130 "%s ", tapdisk_log.cnt,
131 t.tv_sec, (unsigned long long)t.tv_usec, func);
133 va_start(ap, fmt);
134 ret = vsnprintf(buf + len, MAX_ENTRY_LEN - (len + 1), fmt, ap);
135 va_end(ap);
137 len = (ret < MAX_ENTRY_LEN - (len + 1) ?
138 len + ret : MAX_ENTRY_LEN - 1);
139 buf[len] = '\0';
141 tapdisk_log.cnt++;
142 tapdisk_log.p += len;
143 }
145 void
146 __tlog_error(int err, const char *func, const char *fmt, ...)
147 {
148 va_list ap;
149 int i, len, ret;
150 struct error *e;
151 struct timeval t;
153 err = (err > 0 ? err : -err);
155 for (i = 0; i < tapdisk_err.cnt; i++) {
156 e = &tapdisk_err.errors[i];
157 if (e->err == err && e->func == func) {
158 e->cnt++;
159 return;
160 }
161 }
163 if (tapdisk_err.cnt >= MAX_ERROR_MESSAGES) {
164 tapdisk_err.dropped++;
165 return;
166 }
168 gettimeofday(&t, NULL);
169 e = &tapdisk_err.errors[tapdisk_err.cnt];
171 len = snprintf(e->msg, MAX_ENTRY_LEN - 1, "%010ld.%06lld:%s ",
172 t.tv_sec, (unsigned long long)t.tv_usec, func);
174 va_start(ap, fmt);
175 ret = vsnprintf(e->msg + len, MAX_ENTRY_LEN - (len + 1), fmt, ap);
176 va_end(ap);
178 len = (ret < MAX_ENTRY_LEN - (len + 1) ?
179 len + ret : MAX_ENTRY_LEN - 1);
180 e->msg[len] = '\0';
182 e->cnt++;
183 e->err = err;
184 e->func = (char *)func;
185 tapdisk_err.cnt++;
186 }
188 void
189 tlog_print_errors(void)
190 {
191 int i;
192 struct error *e;
194 for (i = 0; i < tapdisk_err.cnt; i++) {
195 e = &tapdisk_err.errors[i];
196 syslog(LOG_INFO, "TAPDISK ERROR: errno %d at %s (cnt = %d): "
197 "%s\n", e->err, e->func, e->cnt, e->msg);
198 }
200 if (tapdisk_err.dropped)
201 syslog(LOG_INFO, "TAPDISK ERROR: %d other error messages "
202 "dropped\n", tapdisk_err.dropped);
203 }
205 void
206 tlog_flush_errors(void)
207 {
208 int i;
209 struct error *e;
211 for (i = 0; i < tapdisk_err.cnt; i++) {
212 e = &tapdisk_err.errors[i];
213 tlog_write(TLOG_WARN, "TAPDISK ERROR: errno %d at %s "
214 "(cnt = %d): %s\n", e->err, e->func, e->cnt,
215 e->msg);
216 }
218 if (tapdisk_err.dropped)
219 tlog_write(TLOG_WARN, "TAPDISK ERROR: %d other error messages "
220 "dropped\n", tapdisk_err.dropped);
221 }
223 void
224 tlog_flush(void)
225 {
226 int fd, flags;
227 size_t size, wsize;
229 if (!tapdisk_log.buf)
230 return;
232 flags = O_CREAT | O_WRONLY | O_DIRECT | O_NONBLOCK;
233 if (!tapdisk_log.append)
234 flags |= O_TRUNC;
236 fd = open(tapdisk_log.file, flags, 0644);
237 if (fd == -1)
238 return;
240 if (tapdisk_log.append)
241 if (lseek(fd, 0, SEEK_END) == (off_t)-1)
242 goto out;
244 tlog_flush_errors();
246 size = tapdisk_log.p - tapdisk_log.buf;
247 wsize = ((size + 511) & (~511));
249 memset(tapdisk_log.buf + size, '\n', wsize - size);
250 write(fd, tapdisk_log.buf, wsize);
252 tapdisk_log.p = tapdisk_log.buf;
254 out:
255 close(fd);
256 }