Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/log.c
+++ new/usr/src/uts/common/io/log.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26
27 27 /*
28 28 * Streams log driver. See log(7D).
29 29 */
30 30
31 31 #include <sys/types.h>
32 32 #include <sys/param.h>
33 33 #include <sys/errno.h>
34 34 #include <sys/stropts.h>
35 35 #include <sys/strsubr.h>
36 36 #include <sys/stream.h>
37 37 #include <sys/strsun.h>
38 38 #include <sys/debug.h>
39 39 #include <sys/cred.h>
40 40 #include <sys/file.h>
41 41 #include <sys/ddi.h>
42 42 #include <sys/stat.h>
43 43 #include <sys/syslog.h>
44 44 #include <sys/log.h>
45 45 #include <sys/systm.h>
46 46 #include <sys/modctl.h>
47 47 #include <sys/policy.h>
48 48 #include <sys/zone.h>
49 49
50 50 #include <sys/conf.h>
51 51 #include <sys/sunddi.h>
52 52
53 53 static dev_info_t *log_devi; /* private copy of devinfo pointer */
54 54 int log_msgid; /* log.conf tunable: enable msgid generation */
55 55
56 56 /* ARGSUSED */
57 57 static int
58 58 log_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
59 59 {
60 60 switch (infocmd) {
61 61 case DDI_INFO_DEVT2DEVINFO:
62 62 *result = log_devi;
63 63 return (DDI_SUCCESS);
64 64 case DDI_INFO_DEVT2INSTANCE:
65 65 *result = 0;
66 66 return (DDI_SUCCESS);
67 67 }
68 68 return (DDI_FAILURE);
69 69 }
70 70
71 71 /* ARGSUSED */
72 72 static int
73 73 log_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
74 74 {
75 75 if (ddi_create_minor_node(devi, "conslog", S_IFCHR,
76 76 LOG_CONSMIN, DDI_PSEUDO, NULL) == DDI_FAILURE ||
77 77 ddi_create_minor_node(devi, "log", S_IFCHR,
78 78 LOG_LOGMIN, DDI_PSEUDO, NULL) == DDI_FAILURE) {
79 79 ddi_remove_minor_node(devi, NULL);
80 80 return (DDI_FAILURE);
81 81 }
82 82 log_devi = devi;
83 83 log_msgid = ddi_getprop(DDI_DEV_T_ANY, log_devi,
84 84 DDI_PROP_CANSLEEP, "msgid", 1);
85 85 return (DDI_SUCCESS);
86 86 }
87 87
88 88 /*
89 89 * log_open can be called for either /dev/log or dev/conslog.
90 90 *
91 91 * In the /dev/conslog case log_alloc() allocates a new minor device from
92 92 * its cache.
93 93 *
94 94 * In the case of /dev/log, LOG_NUMCLONES devices are pre-allocated at zone
95 95 * creation. log_alloc() finds the zone's next available minor device.
96 96 *
97 97 * On entry devp's minor number indicates which device (log or conslog), on
98 98 * successful return it is the device instance.
99 99 */
100 100
101 101 /* ARGSUSED */
102 102 static int
103 103 log_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *cr)
104 104 {
105 105 log_t *lp;
106 106 minor_t minor;
107 107
108 108 if (sflag & (MODOPEN | CLONEOPEN))
109 109 return (ENXIO);
110 110
111 111 switch (minor = getminor(*devp)) {
112 112 case LOG_CONSMIN: /* clone open of /dev/conslog */
113 113 if (flag & FREAD)
114 114 return (EINVAL); /* write-only device */
115 115 if (q->q_ptr)
116 116 return (0);
117 117 break;
118 118
119 119 case LOG_LOGMIN: /* clone open of /dev/log */
120 120 break;
121 121
122 122 default:
123 123 return (ENXIO);
124 124 }
125 125
126 126 lp = log_alloc(minor);
127 127 if (lp == NULL)
128 128 return (ENXIO);
129 129 *devp = makedevice(getmajor(*devp), lp->log_minor);
130 130 q->q_ptr = lp;
131 131 WR(q)->q_ptr = lp;
132 132 lp->log_inuse = 1;
133 133 qprocson(q);
134 134
135 135 return (0);
136 136 }
137 137
138 138 /* ARGSUSED */
139 139 static int
140 140 log_close(queue_t *q, int flag, cred_t *cr)
141 141 {
142 142 log_t *lp = (log_t *)q->q_ptr;
143 143
144 144 qprocsoff(q);
145 145
146 146 lp->log_inuse = 0;
147 147 log_update(lp, NULL, 0, NULL);
148 148 freemsg(lp->log_data);
149 149 lp->log_data = NULL;
150 150 if (lp->log_major == LOG_CONSMIN)
151 151 log_free(lp);
152 152 q->q_ptr = NULL;
153 153 WR(q)->q_ptr = NULL;
154 154
155 155 return (0);
156 156 }
157 157
158 158 static int
159 159 log_wput(queue_t *q, mblk_t *mp)
160 160 {
161 161 log_t *lp = (log_t *)q->q_ptr;
162 162 struct iocblk *iocp;
163 163 mblk_t *mp2;
164 164 cred_t *cr = msg_getcred(mp, NULL);
165 165 zoneid_t zoneid;
166 166
167 167 /*
168 168 * Default to global zone if dblk doesn't have a valid cred.
169 169 * Calls to syslog() go through putmsg(), which does set up
170 170 * the cred.
171 171 */
172 172 zoneid = (cr != NULL) ? crgetzoneid(cr) : GLOBAL_ZONEID;
173 173
174 174 switch (DB_TYPE(mp)) {
175 175 case M_FLUSH:
176 176 if (*mp->b_rptr & FLUSHW) {
177 177 flushq(q, FLUSHALL);
178 178 *mp->b_rptr &= ~FLUSHW;
179 179 }
180 180 if (*mp->b_rptr & FLUSHR) {
181 181 flushq(RD(q), FLUSHALL);
182 182 qreply(q, mp);
183 183 return (0);
184 184 }
185 185 break;
186 186
187 187 case M_IOCTL:
188 188 iocp = (struct iocblk *)mp->b_rptr;
189 189
190 190 if (lp->log_major != LOG_LOGMIN) {
191 191 /* write-only device */
192 192 miocnak(q, mp, 0, EINVAL);
193 193 return (0);
194 194 }
195 195
196 196 if (iocp->ioc_count == TRANSPARENT) {
197 197 miocnak(q, mp, 0, EINVAL);
198 198 return (0);
199 199 }
200 200
201 201 if (lp->log_flags) {
202 202 miocnak(q, mp, 0, EBUSY);
203 203 return (0);
204 204 }
205 205
206 206 freemsg(lp->log_data);
207 207 lp->log_data = mp->b_cont;
208 208 mp->b_cont = NULL;
209 209
210 210 switch (iocp->ioc_cmd) {
211 211
212 212 case I_CONSLOG:
213 213 log_update(lp, RD(q), SL_CONSOLE, log_console);
214 214 break;
215 215
216 216 case I_TRCLOG:
217 217 if (lp->log_data == NULL) {
218 218 miocnak(q, mp, 0, EINVAL);
219 219 return (0);
220 220 }
221 221 log_update(lp, RD(q), SL_TRACE, log_trace);
222 222 break;
223 223
224 224 case I_ERRLOG:
225 225 log_update(lp, RD(q), SL_ERROR, log_error);
226 226 break;
227 227
228 228 default:
229 229 miocnak(q, mp, 0, EINVAL);
230 230 return (0);
231 231 }
232 232 miocack(q, mp, 0, 0);
233 233 return (0);
234 234
235 235 case M_PROTO:
236 236 if (MBLKL(mp) == sizeof (log_ctl_t) && mp->b_cont != NULL) {
237 237 log_ctl_t *lc = (log_ctl_t *)mp->b_rptr;
238 238 /* This code is used by savecore to log dump msgs */
239 239 if (mp->b_band != 0 &&
240 240 secpolicy_sys_config(CRED(), B_FALSE) == 0) {
241 241 (void) putq(log_consq, mp);
242 242 return (0);
243 243 }
244 244 if ((lc->pri & LOG_FACMASK) == LOG_KERN)
245 245 lc->pri |= LOG_USER;
246 246 mp2 = log_makemsg(LOG_MID, LOG_CONSMIN, lc->level,
247 247 lc->flags, lc->pri, mp->b_cont->b_rptr,
248 248 MBLKL(mp->b_cont) + 1, 0);
249 249 if (mp2 != NULL)
250 250 log_sendmsg(mp2, zoneid);
251 251 }
252 252 break;
253 253
254 254 case M_DATA:
255 255 mp2 = log_makemsg(LOG_MID, LOG_CONSMIN, 0, SL_CONSOLE,
256 256 LOG_USER | LOG_INFO, mp->b_rptr, MBLKL(mp) + 1, 0);
257 257 if (mp2 != NULL)
258 258 log_sendmsg(mp2, zoneid);
259 259 break;
260 260 }
261 261
262 262 freemsg(mp);
263 263 return (0);
264 264 }
265 265
266 266 static int
267 267 log_rsrv(queue_t *q)
268 268 {
269 269 mblk_t *mp;
270 270 char *msg, *msgid_start, *msgid_end;
271 271 size_t idlen;
272 272
273 273 while (canputnext(q) && (mp = getq(q)) != NULL) {
274 274 if (log_msgid == 0) {
275 275 /*
276 276 * Strip out the message ID. If it's a kernel
277 277 * SL_CONSOLE message, replace msgid with "unix: ".
278 278 */
279 279 msg = (char *)mp->b_cont->b_rptr;
280 280 if ((msgid_start = strstr(msg, "[ID ")) != NULL &&
281 281 (msgid_end = strstr(msgid_start, "] ")) != NULL) {
282 282 log_ctl_t *lc = (log_ctl_t *)mp->b_rptr;
283 283 if ((lc->flags & SL_CONSOLE) &&
284 284 (lc->pri & LOG_FACMASK) == LOG_KERN)
285 285 msgid_start = msg + snprintf(msg,
286 286 7, "unix: ");
287 287 idlen = msgid_end + 2 - msgid_start;
288 288 ovbcopy(msg, msg + idlen, msgid_start - msg);
289 289 mp->b_cont->b_rptr += idlen;
290 290 }
291 291 }
292 292 mp->b_band = 0;
293 293 putnext(q, mp);
294 294 }
295 295 return (0);
296 296 }
297 297
298 298 static struct module_info logm_info =
299 299 { LOG_MID, "LOG", LOG_MINPS, LOG_MAXPS, LOG_HIWAT, LOG_LOWAT };
300 300
301 301 static struct qinit logrinit =
302 302 { NULL, log_rsrv, log_open, log_close, NULL, &logm_info, NULL };
303 303
304 304 static struct qinit logwinit =
305 305 { log_wput, NULL, NULL, NULL, NULL, &logm_info, NULL };
↓ open down ↓ |
305 lines elided |
↑ open up ↑ |
306 306
307 307 static struct streamtab loginfo = { &logrinit, &logwinit, NULL, NULL };
308 308
309 309 DDI_DEFINE_STREAM_OPS(log_ops, nulldev, nulldev, log_attach, nodev,
310 310 nodev, log_info, D_NEW | D_MP | D_MTPERMOD, &loginfo,
311 311 ddi_quiesce_not_needed);
312 312
313 313 static struct modldrv modldrv =
314 314 { &mod_driverops, "streams log driver", &log_ops };
315 315
316 -static struct modlinkage modlinkage = { MODREV_1, (void *)&modldrv, NULL };
316 +static struct modlinkage modlinkage = { MODREV_1, { (void *)&modldrv, NULL } };
317 317
318 318 int
319 319 _init()
320 320 {
321 321 return (mod_install(&modlinkage));
322 322 }
323 323
324 324 int
325 325 _fini()
326 326 {
327 327 return (mod_remove(&modlinkage));
328 328 }
329 329
330 330 int
331 331 _info(struct modinfo *modinfop)
332 332 {
333 333 return (mod_info(&modlinkage, modinfop));
334 334 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX