xref: /openbsd-src/usr.sbin/iscsid/log.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: log.c,v 1.5 2011/08/20 19:03:39 sthen Exp $ */
2 
3 /*
4  * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
5  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 #include <sys/types.h>
20 #include <sys/queue.h>
21 #include <sys/socket.h>
22 #include <sys/uio.h>
23 
24 #include <scsi/iscsi.h>
25 
26 #include <errno.h>
27 #include <event.h>
28 #include <netdb.h>
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <syslog.h>
34 #include <unistd.h>
35 
36 #include "iscsid.h"
37 #include "log.h"
38 
39 int	debug;
40 int	verbose;
41 
42 void	 logit(int, const char *, ...);
43 
44 void
45 log_init(int n_debug)
46 {
47 	extern char	*__progname;
48 
49 	debug = n_debug;
50 
51 	if (!debug)
52 		openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
53 
54 	tzset();
55 }
56 
57 void
58 log_verbose(int v)
59 {
60 	verbose = v;
61 }
62 
63 void
64 logit(int pri, const char *fmt, ...)
65 {
66 	va_list	ap;
67 
68 	va_start(ap, fmt);
69 	vlog(pri, fmt, ap);
70 	va_end(ap);
71 }
72 
73 void
74 vlog(int pri, const char *fmt, va_list ap)
75 {
76 	char	*nfmt;
77 
78 	if (debug) {
79 		/* best effort in out of mem situations */
80 		if (asprintf(&nfmt, "%s\n", fmt) == -1) {
81 			vfprintf(stderr, fmt, ap);
82 			fprintf(stderr, "\n");
83 		} else {
84 			vfprintf(stderr, nfmt, ap);
85 			free(nfmt);
86 		}
87 		fflush(stderr);
88 	} else
89 		vsyslog(pri, fmt, ap);
90 }
91 
92 void
93 log_warn(const char *emsg, ...)
94 {
95 	char	*nfmt;
96 	va_list	 ap;
97 
98 	/* best effort to even work in out of memory situations */
99 	if (emsg == NULL)
100 		logit(LOG_CRIT, "%s", strerror(errno));
101 	else {
102 		va_start(ap, emsg);
103 
104 		if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
105 			/* we tried it... */
106 			vlog(LOG_CRIT, emsg, ap);
107 			logit(LOG_CRIT, "%s", strerror(errno));
108 		} else {
109 			vlog(LOG_CRIT, nfmt, ap);
110 			free(nfmt);
111 		}
112 		va_end(ap);
113 	}
114 }
115 
116 void
117 log_warnx(const char *emsg, ...)
118 {
119 	va_list	 ap;
120 
121 	va_start(ap, emsg);
122 	vlog(LOG_CRIT, emsg, ap);
123 	va_end(ap);
124 }
125 
126 void
127 log_info(const char *emsg, ...)
128 {
129 	va_list	 ap;
130 
131 	va_start(ap, emsg);
132 	vlog(LOG_INFO, emsg, ap);
133 	va_end(ap);
134 }
135 
136 void
137 log_debug(const char *emsg, ...)
138 {
139 	va_list	 ap;
140 
141 	if (verbose) {
142 		va_start(ap, emsg);
143 		vlog(LOG_DEBUG, emsg, ap);
144 		va_end(ap);
145 	}
146 }
147 
148 void
149 fatal(const char *emsg)
150 {
151 	if (emsg == NULL)
152 		logit(LOG_CRIT, "fatal: %s", strerror(errno));
153 	else
154 		if (errno)
155 			logit(LOG_CRIT, "fatal: %s: %s", emsg, strerror(errno));
156 		else
157 			logit(LOG_CRIT, "fatal: %s", emsg);
158 
159 	exit(1);
160 }
161 
162 void
163 fatalx(const char *emsg)
164 {
165 	errno = 0;
166 	fatal(emsg);
167 }
168 
169 void
170 log_hexdump(void *buf, size_t len)
171 {
172 	u_char b[16];
173 	size_t i, j, l;
174 
175 	if (!debug)
176 		return;
177 
178 	for (i = 0; i < len; i += l) {
179 		fprintf(stderr, "%4zi:", i);
180 		l = sizeof(b) < len - i ? sizeof(b) : len - i;
181 		bcopy((char *)buf + i, b, l);
182 
183 		for (j = 0; j < sizeof(b); j++) {
184 			if (j % 2 == 0)
185 				fprintf(stderr, " ");
186 			if (j % 8 == 0)
187 				fprintf(stderr, " ");
188 			if (j < l)
189 				fprintf(stderr, "%02x", (int)b[j]);
190 			else
191 				fprintf(stderr, "  ");
192 		}
193 		fprintf(stderr, "  |");
194 		for (j = 0; j < l; j++) {
195 			if (b[j] >= 0x20 && b[j] <= 0x7e)
196 				fprintf(stderr, "%c", b[j]);
197 			else
198 				fprintf(stderr, ".");
199 		}
200 		fprintf(stderr, "|\n");
201 	}
202 }
203 
204 void
205 log_pdu(struct pdu *p, int all)
206 {
207 	struct iscsi_pdu *pdu;
208 	void *b;
209 	size_t s;
210 
211 	if (!debug)
212 		return;
213 
214 	if (!(pdu = pdu_getbuf(p, NULL, PDU_HEADER))) {
215 		log_debug("empty pdu");
216 		return;
217 	}
218 
219 	fprintf(stderr, "PDU: op %x%s flags %02x%02x%02x ahs %d len %d\n",
220 		ISCSI_PDU_OPCODE(pdu->opcode), ISCSI_PDU_I(pdu) ? " I" : "",
221 		pdu->flags, pdu->_reserved1[0], pdu->_reserved1[1],
222 		pdu->ahslen, pdu->datalen[0] << 16 | pdu->datalen[1] << 8 |
223 		pdu->datalen[2]);
224 	fprintf(stderr, "     lun %02x%02x%02x%02x%02x%02x%02x%02x itt %u "
225 	    "cmdsn %u expstatsn %u\n", pdu->lun[0], pdu->lun[1], pdu->lun[2],
226 	    pdu->lun[3], pdu->lun[4], pdu->lun[5], pdu->lun[6], pdu->lun[7],
227 	    ntohl(pdu->itt), ntohl(pdu->cmdsn), ntohl(pdu->expstatsn));
228 	log_hexdump(pdu, sizeof(*pdu));
229 
230 	if (all && (b = pdu_getbuf(p, &s, PDU_DATA)))
231 		log_hexdump(b, s);
232 }
233