Skip to content

Privileged mode

install creates the agent’s container with privileged=yes. The setting decides which of the agent’s sources the kernel lets it read; it opens no network access and no view of RouterOS’s processes.

The container runs privileged=yes unless you pass --privileged=false to install or upgrade, which recreates the container. It is a boolean flag, so it takes =false; a separate false argument is not read as its value. The setting needs RouterOS 7.24 or later: RouterOS added privileged mode for containers in 7.24, as its changelog records.

Reading the device’s internal state is what mikroscope is for, and privileged is what makes the root-only kernel files readable. An ordinary RouterOS container is placed in a user namespace where its root maps to host uid 32768 (read on one board), so /proc/slabinfo and /dev/kmsg come back EACCES. privileged=yes drops that user namespace.

It is still a real grant of privilege, which is why plan and install --dry-run print it with the rest of the container’s settings before anything is written.

privileged=yes makes these sources readable, and the agent reads each except where the table says otherwise:

Source What it gives Where it shows
/dev/kmsg the kernel ring buffer as timestamped events, naming the router’s real interfaces mikroscope_kmsg_records_total{level}, mikroscope_kmsg_port_records_total{port,kind,level}, and Loki
/proc/slabinfo the global slab caches: nf_conntrack (the router’s real connection count), skbuff_*, TCP/UDP sockets, kmalloc-1k/-2k mikroscope_slab_active_objects{cache}
/sys/class/mtd ECC counters corrected_bits and ecc_failures per NAND partition mikroscope_mtd_ecc_corrected_bits_total, mikroscope_mtd_ecc_failures_total
the PMU, via perf_event_open cycles, instructions, cache references and misses, branch misses, bus cycles, per core, system-wide mikroscope_perf_events_total{counter,cpu}
/proc/pagetypeinfo readable, but the agent does not read it nowhere

The PMU needs privileged for a different reason from the files: its counters are opened system-wide (pid = -1), which perf_event_open(2) says takes CAP_SYS_ADMIN against the host, CAP_PERFMON on Linux 5.8 and later, or a perf_event_paranoid below 1. A privileged container keeps CAP_SYS_ADMIN against the host, so a perf_event_paranoid of 2 does not block it (measured). What the PMU shows that no tick counter can is on Resolution limits.

The kernel log is read without blocking and capped at 64 records per tick. It is opened at the end of the buffer, so a boot-time backlog is never replayed as if it had just happened. mikroscope_kmsg_dropped_total counts loss events, not records: one per tick that hit the 64-record cap (that tick’s one extra read is discarded, and the rest of the backlog is read on later ticks), and one per kernel ring overrun, which can stand for many records. While it is non-zero, the per-severity count under-counts.

Whether this deployment got them is not left to inference. /capabilities carries "privileged": true only when both /proc/slabinfo and /dev/kmsg opened, and mikroscope_device_info{privileged="true"} says the same on /metrics and in every sink’s device-info stream. Without privileged, the slab, PMU and MTD families are absent, not zero. The kernel-log family appears only once a record has been seen, so its absence alone cannot tell an unprivileged deployment from a quiet kernel; the privileged flag can.

It adds no network access and no view of RouterOS’s processes. Privileged drops the user namespace and leaves the network and PID namespaces in place (verified). So per-interface counters still come from the RouterOS API, and per-process CPU is out of reach even with the host’s /proc mounted into the container. Both are on Container visibility.

It adds no capabilities either: an unprivileged container already holds the full set the kernel defines (read on one board). What changes is the user namespace those capabilities are confined to, not the set.

And it cannot give you more sensors than the board has. The agent reads the thermal zones, which need no privileged, and nothing under /sys/class/hwmon. On the board measured, hwmon is empty even privileged, so its thermal zones are its whole kernel sensor set (measured). On a board that does have voltage, current or fan sensors, the RouterOS API tier still adds them.

--privileged=false keeps everything that is readable from an ordinary container: every global /proc file in the samples, the thermal zones, scaling_cur_freq, /proc/yaffs, /proc/buddyinfo, /proc/diskstats, and the agent’s own cost. What goes:

  • The kernel log. A layer-2 loop can be visible only there.
  • The router’s connection count from the slab cache. The RouterOS API’s count-only table scan is the remaining source, which the collector runs only when --conntrack-every is set.
  • The NAND ECC counters. The YAFFS wear counters remain.
  • The PMU, and with it everything beneath the 10 ms tick.

What goes silent with them: doctor’s health section can then report only softnet-drops. Its ok line does not mean there is no loop, because the loop, STP-churn and link-flap checks read the kernel log. The alert rules mikroscope-l2-loop and mikroscope-port-link-down (kernel log), mikroscope-conntrack-near-limit (slab cache; --conntrack-every feeds a different series that this rule does not read) and mikroscope-ecc-failure (MTD) have no data and stay at OK. Check mikroscope_device_info{privileged} before trusting their silence.