#include <kern/locks.h>
/* XXX should be in a common header somewhere */
-extern void logwakeup(void);
+extern void logwakeup(struct msgbuf *);
extern void oslogwakeup(void);
extern void oslog_streamwakeup(void);
static void oslog_streamwakeup_locked(void);
#define LOG_ASYNC 0x04
#define LOG_RDWAIT 0x08
-#define MAX_UNREAD_CHARS (CONFIG_MSG_BSIZE/2)
/* All globals should be accessed under LOG_LOCK() */
+static char amsg_bufc[1024];
+static struct msgbuf aslbuf = {MSG_MAGIC, sizeof (amsg_bufc), 0, 0, amsg_bufc};
+struct msgbuf *aslbufp __attribute__((used)) = &aslbuf;
+
/* logsoftc only valid while log_open=1 */
struct logsoftc {
int sc_state; /* see above for possibilities */
struct selinfo sc_selp; /* thread waiting for select */
int sc_pgid; /* process/group for async I/O */
+ struct msgbuf *sc_mbp;
} logsoftc;
-int log_open; /* also used in log() */
+static int log_open;
char smsg_bufc[CONFIG_MSG_BSIZE]; /* static buffer */
char oslog_stream_bufc[FIREHOSE_CHUNK_SIZE]; /* static buffer */
struct firehose_chunk_s oslog_boot_buf = {
},
}; /* static buffer */
firehose_chunk_t firehose_boot_chunk = &oslog_boot_buf;
-struct msgbuf msgbuf = {MSG_MAGIC,sizeof(smsg_bufc),0,0,smsg_bufc};
-struct msgbuf oslog_stream_buf = {MSG_MAGIC,0,0,0,NULL};
+struct msgbuf msgbuf = {MSG_MAGIC, sizeof(smsg_bufc), 0, 0, smsg_bufc};
+struct msgbuf oslog_stream_buf = {MSG_MAGIC, 0, 0, 0, NULL};
struct msgbuf *msgbufp __attribute__((used)) = &msgbuf;
struct msgbuf *oslog_streambufp __attribute__((used)) = &oslog_stream_buf;
int sc_state; /* see above for possibilities */
struct selinfo sc_selp; /* thread waiting for select */
int sc_pgid; /* process/group for async I/O */
-}oslog_streamsoftc;
+} oslog_streamsoftc;
STAILQ_HEAD(, oslog_stream_buf_entry_s) oslog_stream_free_head =
STAILQ_HEAD_INITIALIZER(oslog_stream_free_head);
#endif
static int sysctl_kern_msgbuf(struct sysctl_oid *oidp,
- void *arg1,
- int arg2,
- struct sysctl_req *req);
+ void *arg1, int arg2, struct sysctl_req *req);
/*ARGSUSED*/
int
LOG_UNLOCK();
return (EBUSY);
}
+ if (atm_get_diagnostic_config() & ATM_ENABLE_LEGACY_LOGGING) {
+ logsoftc.sc_mbp = msgbufp;
+ } else {
+ /*
+ * Support for messagetracer (kern_asl_msg())
+ * In this mode, /dev/klog exports only ASL-formatted messages
+ * written into aslbufp via vaddlog().
+ */
+ logsoftc.sc_mbp = aslbufp;
+ }
logsoftc.sc_pgid = p->p_pid; /* signal process only */
log_open = 1;
{
int l;
int error = 0;
+ struct msgbuf *mbp = logsoftc.sc_mbp;
LOG_LOCK();
- while (msgbufp->msg_bufr == msgbufp->msg_bufx) {
+ while (mbp->msg_bufr == mbp->msg_bufx) {
if (flag & IO_NDELAY) {
error = EWOULDBLOCK;
goto out;
* If the wakeup is missed
* then wait for 5 sec and reevaluate
*/
- if ((error = tsleep((caddr_t)msgbufp, LOG_RDPRI | PCATCH,
+ if ((error = tsleep((caddr_t)mbp, LOG_RDPRI | PCATCH,
"klog", 5 * hz)) != 0) {
/* if it times out; ignore */
if (error != EWOULDBLOCK)
while (uio_resid(uio) > 0) {
int readpos;
- l = msgbufp->msg_bufx - msgbufp->msg_bufr;
+ l = mbp->msg_bufx - mbp->msg_bufr;
if (l < 0)
- l = msgbufp->msg_size - msgbufp->msg_bufr;
+ l = mbp->msg_size - mbp->msg_bufr;
l = min(l, uio_resid(uio));
if (l == 0)
break;
- readpos = msgbufp->msg_bufr;
+ readpos = mbp->msg_bufr;
LOG_UNLOCK();
- error = uiomove((caddr_t)&msgbufp->msg_bufc[readpos],
- l, uio);
+ error = uiomove((caddr_t)&mbp->msg_bufc[readpos], l, uio);
LOG_LOCK();
if (error)
break;
- msgbufp->msg_bufr = readpos + l;
- if (msgbufp->msg_bufr >= msgbufp->msg_size)
- msgbufp->msg_bufr = 0;
+ mbp->msg_bufr = readpos + l;
+ if (mbp->msg_bufr >= mbp->msg_size)
+ mbp->msg_bufr = 0;
}
out:
LOG_UNLOCK();
int
logselect(__unused dev_t dev, int rw, void * wql, struct proc *p)
{
+ const struct msgbuf *mbp = logsoftc.sc_mbp;
+
switch (rw) {
case FREAD:
LOG_LOCK();
- if (msgbufp->msg_bufr != msgbufp->msg_bufx) {
+ if (mbp->msg_bufr != mbp->msg_bufx) {
LOG_UNLOCK();
return (1);
}
}
void
-logwakeup(void)
+logwakeup(struct msgbuf *mbp)
{
- int pgid;
-
/* cf. r24974766 & r25201228*/
if (oslog_is_safe() == FALSE) {
return;
LOG_UNLOCK();
return;
}
+ if (NULL == mbp)
+ mbp = logsoftc.sc_mbp;
+ if (mbp != logsoftc.sc_mbp)
+ goto out;
selwakeup(&logsoftc.sc_selp);
if (logsoftc.sc_state & LOG_ASYNC) {
- pgid = logsoftc.sc_pgid;
+ int pgid = logsoftc.sc_pgid;
LOG_UNLOCK();
if (pgid < 0)
gsignal(-pgid, SIGIO);
LOG_LOCK();
}
if (logsoftc.sc_state & LOG_RDWAIT) {
- wakeup((caddr_t)msgbufp);
+ wakeup((caddr_t)mbp);
logsoftc.sc_state &= ~LOG_RDWAIT;
}
+out:
LOG_UNLOCK();
}
logioctl(__unused dev_t dev, u_long com, caddr_t data, __unused int flag, __unused struct proc *p)
{
int l;
+ const struct msgbuf *mbp = logsoftc.sc_mbp;
LOG_LOCK();
switch (com) {
/* return number of characters immediately available */
case FIONREAD:
- l = msgbufp->msg_bufx - msgbufp->msg_bufr;
+ l = mbp->msg_bufx - mbp->msg_bufr;
if (l < 0)
- l += msgbufp->msg_size;
+ l += mbp->msg_size;
*(off_t *)data = l;
break;
* SMP reentrancy.
*/
void
-log_putc_locked(char c)
+log_putc_locked(struct msgbuf *mbp, char c)
{
- struct msgbuf *mbp;
-
- mbp = msgbufp;
mbp->msg_bufc[mbp->msg_bufx++] = c;
- if (mbp->msg_bufx >= msgbufp->msg_size)
+ if (mbp->msg_bufx >= mbp->msg_size)
mbp->msg_bufx = 0;
}
return;
}
-static void oslog_streamwrite_append_bytes(const char *buffer, int buflen)
+static void
+oslog_streamwrite_append_bytes(const char *buffer, int buflen)
{
struct msgbuf *mbp;
*
* Returns: (void)
*
- * Notes: This function is used for syingle byte output to the log. It
+ * Notes: This function is used for single byte output to the log. It
* primarily exists to maintain binary backward compatibility.
*/
void
{
int unread_count = 0;
LOG_LOCK();
- log_putc_locked(c);
+ log_putc_locked(msgbufp, c);
unread_count = msgbufp->msg_bufx - msgbufp->msg_bufr;
LOG_UNLOCK();
if (unread_count < 0)
unread_count = 0 - unread_count;
- if (c == '\n' || unread_count >= MAX_UNREAD_CHARS)
- logwakeup();
+ if (c == '\n' || unread_count >= (msgbufp->msg_size / 2))
+ logwakeup(msgbufp);
}
* memory is dynamically allocated. Memory management must already be up.
*/
int
-log_setsize(int size) {
+log_setsize(int size)
+{
char *new_logdata;
int new_logsize, new_bufr, new_bufx;
char *old_logdata;
printf("oslog_setsize: new buffer size = %d, new num entries= %d\n", oslog_stream_buf_size, oslog_stream_num_entries);
}
-SYSCTL_PROC(_kern, OID_AUTO, msgbuf, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_kern_msgbuf, "I", "");
+SYSCTL_PROC(_kern, OID_AUTO, msgbuf,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0,
+ sysctl_kern_msgbuf, "I", "");
-static int sysctl_kern_msgbuf(struct sysctl_oid *oidp __unused,
- void *arg1 __unused,
- int arg2 __unused,
- struct sysctl_req *req)
+static int
+sysctl_kern_msgbuf(struct sysctl_oid *oidp __unused,
+ void *arg1 __unused, int arg2 __unused, struct sysctl_req *req)
{
int old_bufsize, bufsize;
int error;
* It returns as much data still in the buffer as possible.
*/
int
-log_dmesg(user_addr_t buffer, uint32_t buffersize, int32_t * retval) {
+log_dmesg(user_addr_t buffer, uint32_t buffersize, int32_t * retval)
+{
uint32_t i;
uint32_t localbuff_size;
int error = 0, newl, skip;