// configure and open access to printk() message buffer func klog_open() { res := make([]byte, 8) syscall.Klogctl(KLOG_OPEN, nil) syscall.Klogctl(KLOG_CONSOLE_LEVEL, res) syscall.Klogctl(KLOG_CONSOLE_ON, nil) if file_exists(KRNL_PRINTK_TIME) { switch file_read(KRNL_PRINTK_TIME) { case "0", "N", "n": file_write(KRNL_PRINTK_TIME, "Y") } } }
// ReadAll gathers all entries in the kernel log buffer nondestructively. // // Returns an error if a query to the underlying system facilities fails. func ReadAll() ([]byte, error) { n, err := syscall.Klogctl(sysActionSizeBuffer, nil) if err != nil { return nil, errors.New(fmt.Sprintf("Failed to query size of log buffer [%s]", err)) } b := make([]byte, n, n) m, err := syscall.Klogctl(sysActionReadAll, b) if err != nil { return nil, errors.New(fmt.Sprintf("Failed to read messages from log buffer [%s]", err)) } return b[:m], nil }
func reader(ch chan string) { var buf bytes.Buffer var msg [16348]byte for { var n int var err error if *kern { n, err = syscall.Klogctl(1, msg[:]) } else { n, err = fd.Read(msg[:]) } ck(err) for i := 0; i < n; { r, size := utf8.DecodeRune(msg[i:]) i += size buf.WriteRune(r) if r == '\n' || buf.Len() >= len(msg) { ch <- buf.String() buf.Reset() } } } }
// read a part of the unread printk() message buffer func klog_read(size int) ([]byte, error) { res := make([]byte, size) _, err := syscall.Klogctl(KLOG_READ, res) if err != nil { return []byte{}, err } return res, nil }
/* Read logs via klogctl and send each event to the chan 'channel' * * This uses the 'klogctl' syscall on linux. * The first argument is the 'command' and '2' means "blocking read" * which consumes the buffer but blocks until there is data. * * In general, the only data coming over this interface is usually kernel * logs via printk. * * Example code: * * * func main() { * c := make(chan []byte) * go KernelLogReader(c) * * for { * data := <- c * fmt.Printf("%.*s\n", len(data), data) * } * } */ func KernelLogReader(channel chan []byte) { data := make([]byte, 16384) for { length, error := syscall.Klogctl(2, data) if error != nil { fmt.Println("Error:", error) continue } fmt.Printf("Received(%d): %.*s\n", length, length, data) /* Send the message to the channel */ channel <- data[0:length] } }
func main() { flag.Usage = usage flag.Parse() flag.Visit(func(f *flag.Flag) { var err error switch f.Name { case "C": _, err = syscall.Klogctl(SYSLOG_ACTION_CLEAR, nil) case "n": _, _, e := syscall.Syscall(syscall.SYS_SYSLOG, SYSLOG_ACTION_CONSOLE_LEVEL, uintptr(0), uintptr(*level)) if e != 0 { err = syscall.Errno(e) } } xk(err) }) n, err := syscall.Klogctl(SYSLOG_ACTION_SIZE_BUFFER, nil) ck(err) buf := make([]byte, n) n, err = syscall.Klogctl(SYSLOG_ACTION_READ_ALL, buf) ck(err) buf = buf[:n] if len(buf) > 0 && buf[len(buf)-1] != '\n' { buf = append(buf, '\n') } fmt.Printf("%s", buf) if *cflag { _, err = syscall.Klogctl(SYSLOG_ACTION_CLEAR, nil) ck(err) } }
func main() { data := make([]byte, 16) syscall.Klogctl(10, data) fmt.Println(data) }
// get the size of the unread part of printk() message buffer func klog_unread_size() (size int, err error) { res := make([]byte, 1) size, err = syscall.Klogctl(KLOG_SIZE_UNREAD, res) return }
// get the total size of printk() message buffer func klog_buffer_size() (size int, err error) { res := make([]byte, 1) size, err = syscall.Klogctl(KLOG_SIZE_BUFFER, res) return }
// close access to printk() message buffer func klog_close() { syscall.Klogctl(KLOG_CONSOLE_ON, nil) syscall.Klogctl(KLOG_CLOSE, nil) }