2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 */
26
27 /*
28 * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
29 * All Rights Reserved
30 */
31
32 /*
33 * University Copyright- Copyright (c) 1982, 1986, 1988
34 * The Regents of the University of California
35 * All Rights Reserved
36 *
37 * University Acknowledgment- Portions of this document are derived from
38 * software developed by the University of California, Berkeley, and its
39 * contributors.
40 */
41
42 /*
43 * syslogd -- log system messages
44 *
138 "warning", LOG_WARNING,
139 "notice", LOG_NOTICE,
140 "info", LOG_INFO,
141 "debug", LOG_DEBUG,
142 "none", NOPRI,
143 NULL, -1
144 };
145
146 static struct code FacNames[] = {
147 "kern", LOG_KERN,
148 "user", LOG_USER,
149 "mail", LOG_MAIL,
150 "daemon", LOG_DAEMON,
151 "auth", LOG_AUTH,
152 "security", LOG_AUTH,
153 "mark", LOG_MARK,
154 "syslog", LOG_SYSLOG,
155 "lpr", LOG_LPR,
156 "news", LOG_NEWS,
157 "uucp", LOG_UUCP,
158 "audit", LOG_AUDIT,
159 "cron", LOG_CRON,
160 "local0", LOG_LOCAL0,
161 "local1", LOG_LOCAL1,
162 "local2", LOG_LOCAL2,
163 "local3", LOG_LOCAL3,
164 "local4", LOG_LOCAL4,
165 "local5", LOG_LOCAL5,
166 "local6", LOG_LOCAL6,
167 "local7", LOG_LOCAL7,
168 NULL, -1
169 };
170
171 static char *TypeNames[7] = {
172 "UNUSED", "FILE", "TTY", "CONSOLE",
173 "FORW", "USERS", "WALL"
174 };
175
176 /*
177 * we allocate our own thread stacks so we can create them
178 * without the MAP_NORESERVE option. We need to be sure
590 if (Pfd.revents & POLLIN) {
591 getkmsg(0);
592 } else if (Pfd.revents & (POLLNVAL|POLLHUP|POLLERR)) {
593 logerror("kernel log driver poll error");
594 break;
595 }
596 }
597
598 }
599
600 /*
601 * this thread listens to the local stream log driver for log messages
602 * generated by this host, formats them, and queues them to the logger
603 * thread.
604 */
605 /*ARGSUSED*/
606 static void *
607 sys_poll(void *ap)
608 {
609 int nfds;
610 static int klogerrs = 0;
611 pthread_t mythreadno;
612
613 if (Debug) {
614 mythreadno = pthread_self();
615 }
616
617 DPRINT1(1, "sys_poll(%u): sys_thread started\n", mythreadno);
618
619 /*
620 * Try to process as many messages as we can without blocking on poll.
621 * We count such "initial" messages with sys_init_msg_count and
622 * enqueue them without the SYNC_FILE flag. When no more data is
623 * waiting on the local log device, we set timeout to INFTIM,
624 * clear sys_init_msg_count, and generate a flush message to sync
625 * the previously counted initial messages out to disk.
626 */
627
628 sys_init_msg_count = 0;
629
630 for (;;) {
631 errno = 0;
632 t_errno = 0;
633
634 nfds = poll(&Pfd, 1, INFTIM);
635
636 if (nfds == 0)
637 continue;
638
639 if (nfds < 0) {
640 if (errno != EINTR)
641 logerror("poll");
642 continue;
643 }
644 if (Pfd.revents & POLLIN) {
645 getkmsg(INFTIM);
646 } else {
647 if (shutting_down) {
648 pthread_exit(0);
649 }
650 if (Pfd.revents & (POLLNVAL|POLLHUP|POLLERR)) {
651 logerror("kernel log driver poll error");
652 (void) close(Pfd.fd);
653 Pfd.fd = -1;
654 }
655 }
656
657 while (Pfd.fd == -1 && klogerrs++ < 10) {
658 Pfd.fd = openklog(LogName, O_RDONLY);
659 }
660 if (klogerrs >= 10) {
661 logerror("can't reopen kernel log device - fatal");
662 exit(1);
663 }
664 }
665 /*NOTREACHED*/
666 return (NULL);
667 }
668
669 /*
670 * Pull up one message from log driver.
671 */
672 static void
673 getkmsg(int timeout)
674 {
675 int flags = 0, i;
676 char *lastline;
677 struct strbuf ctl, dat;
678 struct log_ctl hdr;
679 char buf[MAXLINE+1];
680 size_t buflen;
681 size_t len;
682 char tmpbuf[MAXLINE+1];
683 pthread_t mythreadno;
684
685 if (Debug) {
686 mythreadno = pthread_self();
687 }
688
689 dat.maxlen = MAXLINE;
690 dat.buf = buf;
691 ctl.maxlen = sizeof (struct log_ctl);
692 ctl.buf = (caddr_t)&hdr;
693
694 while ((i = getmsg(Pfd.fd, &ctl, &dat, &flags)) == MOREDATA) {
695 lastline = &dat.buf[dat.len];
696 *lastline = '\0';
697
698 DPRINT2(5, "sys_poll:(%u): getmsg: dat.len = %d\n",
699 mythreadno, dat.len);
700 buflen = strlen(buf);
701 len = findnl_bkwd(buf, buflen);
702
703 (void) memcpy(tmpbuf, buf, len);
704 tmpbuf[len] = '\0';
705
706 /*
707 * Format sys will enqueue the log message.
708 * Set the sync flag if timeout != 0, which
709 * means that we're done handling all the
710 * initial messages ready during startup.
711 */
712 if (timeout == 0) {
713 formatsys(&hdr, tmpbuf, 0);
714 sys_init_msg_count++;
715 } else {
716 formatsys(&hdr, tmpbuf, 1);
717 }
718 sys_msg_count++;
|
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2013 Gary Mills
23 * Copyright 2012 Milan Jurik. All rights reserved.
24 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 /*
29 * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
30 * All Rights Reserved
31 */
32
33 /*
34 * University Copyright- Copyright (c) 1982, 1986, 1988
35 * The Regents of the University of California
36 * All Rights Reserved
37 *
38 * University Acknowledgment- Portions of this document are derived from
39 * software developed by the University of California, Berkeley, and its
40 * contributors.
41 */
42
43 /*
44 * syslogd -- log system messages
45 *
139 "warning", LOG_WARNING,
140 "notice", LOG_NOTICE,
141 "info", LOG_INFO,
142 "debug", LOG_DEBUG,
143 "none", NOPRI,
144 NULL, -1
145 };
146
147 static struct code FacNames[] = {
148 "kern", LOG_KERN,
149 "user", LOG_USER,
150 "mail", LOG_MAIL,
151 "daemon", LOG_DAEMON,
152 "auth", LOG_AUTH,
153 "security", LOG_AUTH,
154 "mark", LOG_MARK,
155 "syslog", LOG_SYSLOG,
156 "lpr", LOG_LPR,
157 "news", LOG_NEWS,
158 "uucp", LOG_UUCP,
159 "bsdcron", LOG_BSDCRON,
160 "authpriv", LOG_AUTHPRIV,
161 "ftp", LOG_FTP,
162 "ntp", LOG_NTP,
163 "audit", LOG_AUDIT,
164 "console", LOG_CONSOLE,
165 "cron", LOG_CRON,
166 "local0", LOG_LOCAL0,
167 "local1", LOG_LOCAL1,
168 "local2", LOG_LOCAL2,
169 "local3", LOG_LOCAL3,
170 "local4", LOG_LOCAL4,
171 "local5", LOG_LOCAL5,
172 "local6", LOG_LOCAL6,
173 "local7", LOG_LOCAL7,
174 NULL, -1
175 };
176
177 static char *TypeNames[7] = {
178 "UNUSED", "FILE", "TTY", "CONSOLE",
179 "FORW", "USERS", "WALL"
180 };
181
182 /*
183 * we allocate our own thread stacks so we can create them
184 * without the MAP_NORESERVE option. We need to be sure
596 if (Pfd.revents & POLLIN) {
597 getkmsg(0);
598 } else if (Pfd.revents & (POLLNVAL|POLLHUP|POLLERR)) {
599 logerror("kernel log driver poll error");
600 break;
601 }
602 }
603
604 }
605
606 /*
607 * this thread listens to the local stream log driver for log messages
608 * generated by this host, formats them, and queues them to the logger
609 * thread.
610 */
611 /*ARGSUSED*/
612 static void *
613 sys_poll(void *ap)
614 {
615 int nfds;
616 int timeout;
617 static int klogerrs = 0;
618 pthread_t mythreadno;
619
620 if (Debug) {
621 mythreadno = pthread_self();
622 }
623
624 DPRINT1(1, "sys_poll(%u): sys_thread started\n", mythreadno);
625
626 /*
627 * Try to process as many messages as we can without blocking on poll.
628 * We identify such messages with timeout == 0 and
629 * enqueue them without the SYNC_FILE flag. When no more data is
630 * waiting on the local log device, we set timeout to INFTIM,
631 * and generate a flush message to sync
632 * the previously identified messages out to disk.
633 */
634
635 timeout = INFTIM;
636
637 for (;;) {
638 errno = 0;
639 t_errno = 0;
640
641 nfds = poll(&Pfd, 1, timeout);
642
643 if (nfds <= 0) {
644 if (nfds < 0 && errno != EINTR)
645 logerror("poll");
646 if (timeout == 0)
647 flushmsg(SYNC_FILE);
648 timeout = INFTIM;
649 continue;
650 }
651
652 if (Pfd.revents & POLLIN) {
653 timeout = 0;
654 getkmsg(timeout);
655 continue;
656 }
657
658 if (shutting_down) {
659 pthread_exit(0);
660 }
661
662 if (Pfd.revents & (POLLNVAL|POLLHUP|POLLERR)) {
663 logerror("kernel log driver poll error");
664 (void) close(Pfd.fd);
665 Pfd.fd = -1;
666 }
667
668 while (Pfd.fd == -1 && klogerrs++ < 10) {
669 Pfd.fd = openklog(LogName, O_RDONLY);
670 }
671 if (klogerrs >= 10) {
672 logerror("can't reopen kernel log device - fatal");
673 exit(1);
674 }
675 if (timeout == 0)
676 flushmsg(SYNC_FILE);
677 timeout = INFTIM;
678 }
679 /*NOTREACHED*/
680 return (NULL);
681 }
682
683 /*
684 * Pull up one message from log driver.
685 */
686 static void
687 getkmsg(int timeout)
688 {
689 int flags = 0, i;
690 char *lastline;
691 struct strbuf ctl, dat;
692 struct log_ctl hdr;
693 char buf[MAXLINE+1];
694 size_t buflen;
695 size_t len;
696 char tmpbuf[MAXLINE+1];
697 pthread_t mythreadno;
698
699 if (Debug) {
700 mythreadno = pthread_self();
701 }
702
703 dat.maxlen = MAXLINE;
704 dat.buf = buf;
705 ctl.maxlen = sizeof (struct log_ctl);
706 ctl.buf = (caddr_t)&hdr;
707
708 while ((i = getmsg(Pfd.fd, &ctl, &dat, &flags)) == MOREDATA) {
709 lastline = &dat.buf[dat.len];
710 *lastline = '\0';
711
712 DPRINT2(5, "getkmsg:(%u): getmsg: dat.len = %d\n",
713 mythreadno, dat.len);
714 buflen = strlen(buf);
715 len = findnl_bkwd(buf, buflen);
716
717 (void) memcpy(tmpbuf, buf, len);
718 tmpbuf[len] = '\0';
719
720 /*
721 * Format sys will enqueue the log message.
722 * Set the sync flag if timeout != 0, which
723 * means that we're done handling all the
724 * initial messages ready during startup.
725 */
726 if (timeout == 0) {
727 formatsys(&hdr, tmpbuf, 0);
728 sys_init_msg_count++;
729 } else {
730 formatsys(&hdr, tmpbuf, 1);
731 }
732 sys_msg_count++;
|