Skip to content

modemmanager: skip live report when MM isn't running yet - #30130

Open
micpf wants to merge 1 commit into
openwrt:masterfrom
micpf:modemmanager-guard-report-when-not-running
Open

modemmanager: skip live report when MM isn't running yet#30130
micpf wants to merge 1 commit into
openwrt:masterfrom
micpf:modemmanager-guard-report-when-not-running

Conversation

@micpf

@micpf micpf commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

At boot procd replays every previously-seen uevent before /etc/init.d/modemmanager starts. Each replay walks the hotplug.d/ tree, which calls mm_report_event() in modemmanager.common. That helper does two independent things:

  1. appends the event to ${MODEMMANAGER_EVENTS_CACHE}, and
  2. runs mmcli --report-kernel-event=... to notify a live MM.

Step 1 is what matters for boot; step 2 exists so events fired after MM is running get reported without waiting for the next cache replay. The cache path is intentional: ModemManager-wrapper starts MM, then mm_report_events_from_cache() polls mmcli -L until the bus is available and replays every cached event.

At boot MM isn't on the bus yet, so step 2 always fails with:

daemon.err ModemManager[NNN]: hotplug: Couldn't report kernel event: error: couldn't get bus: Could not connect: No such file or directory

That's one daemon.err line per hotplug script per port, per boot. On a dual-modem board that's a dozen spurious errors before MM even starts. Nothing is lost — the wrapper's cache replay picks them all up seconds later — but the log noise makes real ModemManager errors harder to spot.

Guard the live call with a cheap pidfile-based liveness check. If MM isn't running, the event is silently cached and the wrapper handles it. If MM is running, behavior is unchanged.

Reproducer

Any OpenWrt install with modemmanager and at least one modem attached. logread | grep 'Couldn\'t report kernel event' after boot shows one line per port.

Verification

Built for aarch64_generic (LS1046-based board with two Telit FN990 modems, MHI PCI attached, ports wwan0{at0,at1,qcdm0,mbim0} and wwan1{at0,at1,qcdm0,mbim0} plus ttyUSB{0,1}). Before: 12 Couldn't report kernel event errors per boot. After: 0. Runtime hotplug (unplug + replug a modem) still works — mmcli is invoked normally once MM's pidfile exists.

@micpf
micpf force-pushed the modemmanager-guard-report-when-not-running branch from 3e31fd3 to e2c918b Compare July 31, 2026 12:07
At boot procd replays every previously-seen uevent before
/etc/init.d/modemmanager starts.  Each replay walks the hotplug.d/
tree, which calls mm_report_event() in modemmanager.common.  That
helper does two independent things:

  1) appends the event to ${MODEMMANAGER_EVENTS_CACHE}, and
  2) runs 'mmcli --report-kernel-event=...' to notify a live MM.

Step 1 is what matters for boot; step 2 exists so events fired
after MM is running get reported without waiting for the next
cache replay.  The cache path is intentional: ModemManager-wrapper
starts MM, then mm_report_events_from_cache() polls 'mmcli -L'
until the bus is available and replays every cached event.

At boot MM isn't on the bus yet, so step 2 always fails with:

  daemon.err ModemManager[NNN]: hotplug: Couldn't report kernel
    event: error: couldn't get bus: Could not connect: No such
    file or directory

That's one daemon.err line per hotplug script per port, per boot.
On a dual-modem board that's a dozen spurious errors before MM
even starts.  Nothing is lost -- the wrapper's cache replay picks
them all up seconds later -- but the log noise makes real
ModemManager errors harder to spot.

Guard the live call with a cheap pidfile-based liveness check.  If
MM isn't running, the event is silently cached and the wrapper
handles it.  If MM is running, behavior is unchanged.

Signed-off-by: Michael Pfeifroth <micpf@westermo.com>
@micpf
micpf force-pushed the modemmanager-guard-report-when-not-running branch from e2c918b to e827061 Compare July 31, 2026 12:15

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 new commit. The change is a sensible log-noise fix and the packaging side is correct — PKG_RELEASE 11 → 12 is the right bump for a files-only change with no PKG_VERSION move, and the commit message matches what the diff does.

Nothing here blocks a merge. The two substantive comments are about what the pidfile actually proves (the wrapper was spawned, not that MM is on the bus) and about the guard also sitting on the cache-replay path that is supposed to be the fallback; both are worth a reply but neither is a defect in the current boot flow. The third is an optional whitespace nit.


Generated by Claude Code

Comment on lines +162 to +163
if [ ! -s "${MODEMMANAGER_PID_FILE}" ] || \
! kill -0 "$(cat "${MODEMMANAGER_PID_FILE}" 2>/dev/null)" 2>/dev/null; then

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pidfile is procd's, set on the service instance at init.d/modemmanager:30, and procd writes it the moment it spawns the command — so it holds the PID of /usr/sbin/ModemManager-wrapper, not of a ModemManager that is reachable on the bus. The wrapper starts MM and only then polls mmcli -L for up to 60 s before it considers MM available.

So the guard covers the window the commit message describes (uevent replay before START=70), but not the wrapper-startup window: any event fired between procd spawning the wrapper and MM appearing on D-Bus passes kill -0 and still produces the exact Couldn't report kernel event: ... couldn't get bus line. Same on every restart and on every procd respawn.

Is that residual window acceptable for your use case, or would it be worth gating on something the wrapper writes after mmcli -L first succeeds (and clears on exit) instead of on procd's pidfile? Either way, it would help to narrow the claim in the commit message from "MM isn't running" to "the service instance isn't up yet", so the next reader isn't surprised when a few of these errors still show up.


Generated by Claude Code

# Skip live report if MM isn't up; wrapper will replay from cache.
if [ ! -s "${MODEMMANAGER_PID_FILE}" ] || \
! kill -0 "$(cat "${MODEMMANAGER_PID_FILE}" 2>/dev/null)" 2>/dev/null; then
return

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The guard sits in mm_report_event(), which is not only the hotplug entry point — it is also the last step of the cache-replay path that this PR relies on as the safety net: mm_report_events_from_cache()`` → mm_report_event_from_cache_line() → `mm_report_event()`.

That path has already proven MM is reachable via mmcli -L, yet every replayed event now has to pass a second, weaker test against procd's pidfile. In practice it will pass (procd writes the pidfile before the wrapper's first sleep 1), but it makes the replay silently dependent on the pidfile: if /var/run/modemmanager/modemmanager.pid is ever missing or the wrapper is run outside procd (debugging), the replay becomes a no-op and nothing is logged at all — mm_log "debug" is discarded unconditionally,`` so there is no trace to grep for.

Guarding at the three hotplug.d/ call sites instead — or passing a flag that the replay path sets to bypass the check — would keep the safety net independent of the thing it is meant to compensate for. Not a blocker, but worth considering.


Generated by Claude Code


# Skip live report if MM isn't up; wrapper will replay from cache.
if [ ! -s "${MODEMMANAGER_PID_FILE}" ] || \
! kill -0 "$(cat "${MODEMMANAGER_PID_FILE}" 2>/dev/null)" 2>/dev/null; then

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit (optional): the continuation is indented with a tab plus three spaces for visual alignment, while the rest of this file indents continuations with plain tabs (see the grep -qs ... || \ / echo ... pair a few lines above). Mixed tabs and spaces in a tab-indented file.

Suggested change
! kill -0 "$(cat "${MODEMMANAGER_PID_FILE}" 2>/dev/null)" 2>/dev/null; then
! kill -0 "$(cat "${MODEMMANAGER_PID_FILE}" 2>/dev/null)" 2>/dev/null; then

Generated by Claude Code

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Ready to approve

The change is small, matches the stated intent, and preserves the event-caching path while eliminating the pre-start mmcli error spam.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Reduces boot-time syslog noise from modemmanager hotplug handlers by skipping the “live” mmcli --report-kernel-event=... call until the service is considered running, while still caching all kernel events for later replay by ModemManager-wrapper.

Changes:

  • Bump PKG_RELEASE to ship the behavior change.
  • In mm_report_event(), add a pidfile-based liveness guard so hotplug-triggered live reporting is skipped when the service hasn’t started yet (events are still cached).
File summaries
File Description
net/modemmanager/Makefile Increments package release to reflect the behavior change.
net/modemmanager/files/usr/share/ModemManager/modemmanager.common Adds a pidfile/kill -0 guard to avoid boot-time mmcli failures while preserving event caching.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants