The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/drivers/log/diag.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* This file handle diagnostic output that is directly sent to the LOG driver.
    2  * This output can either be a kernel message (announced through a SYS_EVENT
    3  * with a SIGKMESS in the signal set) or output from another system process
    4  * (announced through a DIAGNOSTICS message).
    5  *
    6  * Changes:
    7  *      21 July 2005:   Created  (Jorrit N. Herder)
    8  */
    9 
   10 #include <stdio.h>
   11 #include <fcntl.h>
   12 
   13 #include "log.h"
   14 #include "../../kernel/const.h"
   15 #include "../../kernel/config.h"
   16 #include "../../kernel/type.h"
   17 
   18 /*==========================================================================*
   19  *                              do_new_kmess                                *
   20  *==========================================================================*/
   21 PUBLIC int do_new_kmess(m)
   22 message *m;                                     /* notification message */
   23 {
   24 /* Notification for a new kernel message. */
   25   struct kmessages kmess;               /* entire kmess structure */
   26   char print_buf[KMESS_BUF_SIZE];       /* copy new message here */
   27   static int prev_next = 0;
   28   int bytes;
   29   int i, r;
   30 
   31   if (m->m_source == TTY_PROC_NR)
   32   {
   33         message mess;
   34 
   35         /* Ask TTY driver for log output */
   36         mess.GETKM_PTR= &kmess;
   37         mess.m_type = GET_KMESS;
   38         r= sendrec(TTY_PROC_NR, &mess);
   39         if (r == OK) r= mess.m_type;
   40         if (r != OK)
   41         {
   42                 report("LOG","couldn't get copy of kmessages from TTY", r);
   43                 return EDONTREPLY;
   44         }
   45   }
   46   else
   47   {
   48         /* Try to get a fresh copy of the buffer with kernel messages. */
   49         if ((r=sys_getkmessages(&kmess)) != OK) {
   50                 report("LOG","couldn't get copy of kmessages", r);
   51                 return EDONTREPLY;
   52         }
   53   }
   54 
   55   /* Print only the new part. Determine how many new bytes there are with 
   56    * help of the current and previous 'next' index. Note that the kernel
   57    * buffer is circular. This works fine if less then KMESS_BUF_SIZE bytes
   58    * is new data; else we miss % KMESS_BUF_SIZE here.  
   59    * Check for size being positive, the buffer might as well be emptied!
   60    */
   61   if (kmess.km_size > 0) {
   62       bytes = ((kmess.km_next + KMESS_BUF_SIZE) - prev_next) % KMESS_BUF_SIZE;
   63       r=prev_next;                              /* start at previous old */ 
   64       i=0;
   65       while (bytes > 0) {                       
   66           print_buf[i] = kmess.km_buf[(r%KMESS_BUF_SIZE)];
   67           bytes --;
   68           r ++;
   69           i ++;
   70       }
   71       /* Now terminate the new message and save it in the log. */
   72       print_buf[i] = 0;
   73       log_append(print_buf, i);
   74   }
   75 
   76   /* Almost done, store 'next' so that we can determine what part of the
   77    * kernel messages buffer to print next time a notification arrives.
   78    */
   79   prev_next = kmess.km_next;
   80   return EDONTREPLY;
   81 }
   82 
   83 /*===========================================================================*
   84  *                              do_diagnostics                               *
   85  *===========================================================================*/
   86 PUBLIC int do_diagnostics(message *m)
   87 {
   88 /* The LOG server handles all diagnostic messages from servers and device 
   89  * drivers. It forwards the message to the TTY driver to display it to the
   90  * user. It also saves a copy in a local buffer so that messages can be 
   91  * reviewed at a later time.
   92  */
   93   int proc_nr; 
   94   vir_bytes src;
   95   int count;
   96   char c;
   97   int i = 0;
   98   static char diagbuf[10240];
   99 
  100   /* Change SELF to actual process number. */
  101   if ((proc_nr = m->DIAG_PROC_NR) == SELF)
  102       m->DIAG_PROC_NR = proc_nr = m->m_source;
  103 
  104   /* Now also make a copy for the private buffer at the LOG server, so
  105    * that the messages can be reviewed at a later time.
  106    */
  107   src = (vir_bytes) m->DIAG_PRINT_BUF;
  108   count = m->DIAG_BUF_COUNT; 
  109   while (count > 0 && i < sizeof(diagbuf)-1) {
  110       if (sys_datacopy(proc_nr, src, SELF, (vir_bytes) &c, 1) != OK) 
  111           break;                /* stop copying on error */
  112       src ++;
  113       count --;
  114       diagbuf[i++] = c;
  115   }
  116   log_append(diagbuf, i);
  117 
  118   return OK;
  119 }

Cache object: 0549bf1cab6ed4ed963e39b5e9e37d80


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.