Skip to content

fix(viewer): restart to recover /dev/fb0 hotplugged after a headless boot#3134

Closed
vpetersson wants to merge 1 commit into
masterfrom
fix/linuxfb-fb0-hotplug-restart
Closed

fix(viewer): restart to recover /dev/fb0 hotplugged after a headless boot#3134
vpetersson wants to merge 1 commit into
masterfrom
fix/linuxfb-fb0-hotplug-restart

Conversation

@vpetersson

Copy link
Copy Markdown
Contributor

Problem

On linuxfb boards (32-bit Pi 1/2/3, Qt5), wait_for_framebuffer in bin/start_viewer.sh waits for /dev/fb0 before launching the viewer — this is the #2959 guard that stops the headless crash-loop.

But the (privileged) viewer container's /dev is a devtmpfs snapshot taken at container start. If the container boots headless and a display is plugged in later, the host gains /dev/fb0 but it never appears inside the container's stale /dev — so the wait loop blocks forever and the viewer never starts. The comment claimed the wait "self-heals on hotplug"; in a running container it silently does not.

Reproduced live on the Pi 2 testbed: plugging a monitor into a headless-booted board left the host with /dev/fb0 while the container saw only /sys/class/graphics/fb0, and the viewer stayed parked (still no /dev/fb0 after 6540s; waiting for a display) until a manual docker restart.

Fix

sysfs is bind-through from the host and stays truthful across the stale snapshot. When /sys/class/graphics/fb0 exists but the container's /dev/fb0 does not, exit non-zero so the restart: always policy recreates the container with a fresh /dev that includes fb0 — the same exit-to-restart recovery the OOM and viewer-death paths already rely on. Genuinely headless devices (no sysfs fb0 either) keep waiting quietly, so the #2959 behavior is preserved.

Note /dev/fb0 and /sys/class/graphics/fb0 are the same fbdev object (created/removed together by register_framebuffer/unregister_framebuffer), so a real headless box has neither.

Validation (live on the Pi 2, DEVICE_TYPE=pi2, linuxfb/Qt5)

Exercised the real wait_for_framebuffer against each state:

State Setup Result
Display present /dev/fb0 present returns 0, proceeds
Hotplug-stale /dev/fb0 removed, /sys/.../fb0 present prints message, exit 1
Headless neither present keeps waiting, never exits

bash -n clean.

- exit wait_for_framebuffer when the host has fb0 but the container's
  stale /dev doesn't, so `restart: always` re-snapshots /dev
- keep waiting quietly when genuinely headless (no sysfs fb0) to avoid
  the #2959 crash-loop
- fixes the "self-heals on hotplug" case that a running container's
  devtmpfs snapshot silently broke

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vpetersson vpetersson requested a review from a team as a code owner July 7, 2026 19:16
@vpetersson vpetersson requested a review from Copilot July 7, 2026 19:16

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.

Copilot wasn't able to review any files in this pull request.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sonarqubecloud

sonarqubecloud Bot commented Jul 7, 2026

Copy link
Copy Markdown

@vpetersson vpetersson requested a review from Copilot July 7, 2026 19:17

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.

Copilot wasn't able to review any files in this pull request.

@vpetersson

Copy link
Copy Markdown
Contributor Author

Folded into #3075 — the two fixes are the pre-launch and post-launch bookends of the same linuxfb HDMI-hotplug problem and belong together. The wait_for_framebuffer headless-boot recovery is now commit daa7f8d on #3075's branch.

@vpetersson vpetersson closed this Jul 7, 2026
@vpetersson vpetersson deleted the fix/linuxfb-fb0-hotplug-restart branch July 7, 2026 19:44
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.

2 participants