After resuming from hibernate, visaged is left holding a stale fd on /dev/videoN (the USB host has cycled and the kernel re-enumerated the camera). The capture loop's blocking reads no longer return useful data, and SIGTERM doesn't unwind them.
visage-resume.service runs systemctl restart visaged.service to recover. Because the daemon ignores the SIGTERM, systemd waits the default TimeoutStopSec=90s and finally sends SIGKILL. The fresh visaged then starts in about a second. End-to-end the restart takes ~90s, during which face auth doesn't work.
Reproduce:
# 1. visaged running, hyprlock or similar idle
$ sudo systemctl hibernate
# 2. wait for the machine to power off, then power back on, finish LUKS / login
# 3. time the recovery
$ time sudo systemctl restart visaged.service
real 1m54.412s
Journal during the restart:
visage-resume.service: Starting Restart Visage daemon after resume from suspend...
(~1m54s pause — visaged ignoring SIGTERM)
visaged.service: Stopped
visaged.service: Started
visaged: visaged starting
visaged: visaged ready — listening on org.freedesktop.Visage1 bus="system"
Expected: visaged notices the camera fd has gone bad (e.g. EIO from read) and exits, or the capture loop is interruptible by SIGTERM.
Workaround for users — drop the stop timeout so SIGKILL fires fast:
# /etc/systemd/system/visaged.service.d/fast-stop.conf
[Service]
TimeoutStopSec=2s
That brings systemctl restart down to ~3s end to end. Could also be shipped in visaged.service directly until the underlying hang is fixed.
Should affect any device in the supported tier list with a USB-attached IR sensor across hibernate (Surface, ThinkPad T/X pre-Gen11, EliteBook, ZenBook 14). Not s2idle/suspend — only s4 hibernate, where the host actually power-cycles the camera.
System: Arch Linux, linux-surface kernel 6.19.8, visage v0.3.0 built from packaging/aur/PKGBUILD (with options=(!lto !debug) per the PKGBUILD PR), Microsoft Surface Laptop 4 Intel, UVC IR camera at /dev/video2.
After resuming from hibernate,
visagedis left holding a stale fd on/dev/videoN(the USB host has cycled and the kernel re-enumerated the camera). The capture loop's blocking reads no longer return useful data, andSIGTERMdoesn't unwind them.visage-resume.servicerunssystemctl restart visaged.serviceto recover. Because the daemon ignores the SIGTERM, systemd waits the defaultTimeoutStopSec=90sand finally sends SIGKILL. The freshvisagedthen starts in about a second. End-to-end the restart takes ~90s, during which face auth doesn't work.Reproduce:
Journal during the restart:
Expected:
visagednotices the camera fd has gone bad (e.g.EIOfrom read) and exits, or the capture loop is interruptible by SIGTERM.Workaround for users — drop the stop timeout so SIGKILL fires fast:
That brings
systemctl restartdown to ~3s end to end. Could also be shipped invisaged.servicedirectly until the underlying hang is fixed.Should affect any device in the supported tier list with a USB-attached IR sensor across hibernate (Surface, ThinkPad T/X pre-Gen11, EliteBook, ZenBook 14). Not s2idle/suspend — only s4 hibernate, where the host actually power-cycles the camera.
System: Arch Linux, linux-surface kernel 6.19.8, visage v0.3.0 built from packaging/aur/PKGBUILD (with
options=(!lto !debug)per the PKGBUILD PR), Microsoft Surface Laptop 4 Intel, UVC IR camera at/dev/video2.