Package: spice-vdagent
Version: 0.22.1-4.1
Severity: normal
Tags: patch
Dear Maintainer,
The start() function in /etc/init.d/spice-vdagent unconditionally
removes /var/run/spice-vdagentd/spice-vdagent-sock before invoking
start-stop-daemon.
If spice-vdagentd is already running, start-stop-daemon --start
--oknodo leaves the existing daemon running and returns success.
However, its listening socket pathname has already been removed,
preventing graphical session agents from connecting.
Environment:
- Devuan Excalibur
- runit as PID 1
- Xfce/X11
- QEMU/KVM with SPICE and the com.redhat.spice.0 virtio channel
Observed behavior:
Clipboard sharing stopped working although service status reported
spice-vdagentd running. The graphical session agent subsequently
exited. Starting it in the foreground produced:
Failed to connect with spice-vdagentd due 'Could not connect:
No such file or directory'. Trying again in 1s
After terminating and restarting spice-vdagentd, the agent connected:
connected to /run/spice-vdagentd/spice-vdagent-sock
Expected behavior:
Calling start on an already-running service should leave its
communication socket intact.
Reproduction procedure for the unmodified init script:
1. Start the daemon and confirm its socket exists.
2. Invoke /etc/init.d/spice-vdagent start again.
3. Observe that the daemon remains running, but the socket pathname
has disappeared.
4. A newly launched spice-vdagent cannot connect.
The original trigger for the socket disappearance was not traced,
but inspection identified the non-idempotent start operation above.
Adding the following guard fixed the problem on my system:
--- a/etc/init.d/spice-vdagent
+++ b/etc/init.d/spice-vdagent
@@ -36,6 +36,10 @@
lockfile=/var/lock/$prog
start() {
+ # An already-running daemon must retain its communication socket.
+ if status_of_proc -p "$pidfile" "$exec" "$prog" >/dev/null 2>&1; then
+ return 0
+ fi
[ -x $exec ] || exit 5
[ -c $port ] || exit 0
modprobe uinput > /dev/null 2>&1
This uses the same process-status helper and PID file already used
by the script's status() function.
The bug was discovered and the report was written with the help of
OpenAI's codex.