Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Device feeds

A feed is a virtual node of devfs that gives records of kernel events. Vex has two: /dev/kplog for the kernel log and /dev/hwtree for the device tree. Each read gives only whole records. When the next record does not fit in the buffer of the caller, the read fails with EINVAL. A program therefore reads with a buffer that is large enough for the largest record.

Every record begins with struct __k_feed_header:

FieldMeaning
sizeThe bytes of the whole record, header and padding included, a multiple of 8
typeThe kind of record, never zero
flagsTheir meaning depends on type
seqThe sequence number of the record
time_nsThe moment of the record on __k_CLOCK_MONOTONIC

The type __k_FEED_TYPE_LOST says that the feed dropped records before this one, and struct __k_feed_lost gives the count. A type of a device is __k_FEED_TYPE_DEF(n), which is 0x0100 + n.

The kernel log

A struct __k_kplog_record adds the subsystem, the level, the length and the text. The text is not terminated, and its field holds at most __k_KPLOG_TEXT_MAX (512) bytes. The flag __k_KPLOG_FLAG_TRUNCATED says that the message was longer than the record.

The levels run from __k_KP_EMERG (0) to __k_KP_VERBOSE (7). The subsystem is one of __k_KP_*, and __k_KP_USER marks a write from user space. A write to /dev/kplog needs CAP_SYSLOG.

The requests of the 'L' group:

RequestArgumentMeaning
__k_KPLOG_SEEK_FIRSTNoneGo to the oldest record in the ring
__k_KPLOG_SEEK_ENDNoneGo to the record to come
__k_KPLOG_SEEK_SEQ__k_uint64_tGo to that sequence number
__k_KPLOG_GET_INFO__k_kplog_infoThe first and the next sequence number
__k_KPLOG_GET_CONSOLE_LEVEL__k_int32_tThe level that the console prints
__k_KPLOG_SET_CONSOLE_LEVEL__k_int32_tSet that level

The device tree

A struct __k_hwtree_record adds the id of the node, the id of its parent, its state and a block of fields. The fields are zero-separated key=value pairs in one array of at most __k_HWTREE_FIELDS_MAX (512) bytes. The flag __k_HWTREE_FLAG_TRUNCATED says that some fields did not fit and were left out whole.

A reader gets the tree as it was at open, between a snapshot begin record and a snapshot end record, with parents before their children. After that come the changes. After a lost record comes a new snapshot.

TypeMeaning
__k_FEED_TYPE_HWTREE_SNAPSHOT_BEGINThe beginning of a snapshot
__k_FEED_TYPE_HWTREE_SNAPSHOT_ENDThe end of a snapshot
__k_FEED_TYPE_HWTREE_ADDA node appeared
__k_FEED_TYPE_HWTREE_REMOVEA node left
__k_FEED_TYPE_HWTREE_BINDA driver took the node
__k_FEED_TYPE_HWTREE_UNBINDThe driver let it go
__k_FEED_TYPE_HWTREE_WAITINGThe best driver waits for a provider
__k_FEED_TYPE_HWTREE_ATTACH_FAILEDThe attach returned an error
__k_FEED_TYPE_HWTREE_INTERFACEAn interface appeared on the node
__k_FEED_TYPE_HWTREE_INTERFACE_REMOVEThe interface left

The state of a node is one of __k_HWTREE_STATE_PRESENT, PROBING, WAITING, BOUND, DETACHING and GONE.

The requests of the 'H' group change the tree, so they need a file opened for writing, and that open needs CAP_DEVICE:

RequestArgumentMeaning
__k_HWTREE_RESNAPSHOTNoneGive the tree again from the beginning
__k_HWTREE_RESCAN__k_uint64_tRescan the buses below that node
__k_HWTREE_UNBIND__k_uint64_tUnbind the driver of that node
__k_HWTREE_EJECT__k_uint64_tEject the device of that node

Limits

  • A record is at most the fixed part plus 512 bytes of text or fields, and its size is a multiple of 8.
  • A read buffer that is too small for the next record fails with EINVAL. The kernel does not cut a record and does not skip one.
  • The log is a ring. A reader that falls behind gets a lost record and misses the records in between.

Source

  • feed.h — the common header and the lost record
  • kplog.h — the log record and the 'L' requests
  • hwtree.h — the tree record and the 'H' requests