Summary
DDM does not recover cleanly if the dde-seatd control socket disappears unexpectedly.
DdeSeatdControl disconnects and clears its cached state on socket error, but it does not attempt to reconnect. If dde-seatd dies and comes back, DDM can stay alive while permanently losing VT change notifications.
Current behavior
src/daemon/DdeSeatdControl.cpp uses /run/dde-seatd-control.sock and does this on failure:
connectEventSocket() fails -> log + give up
handleEventSocketError() -> disconnectEventSocket()
disconnectEventSocket() clears the socket and cached VT state
There is no retry loop and no service-level recovery path inside DDM.
Why this matters
I validated the systemd side separately:
- if
dde-seatd is explicitly stopped/restarted by systemctl, Requires= is enough for systemd to stop/restart dependent services in the same transaction
- but if the
dde-seatd process dies unexpectedly, a plain Requires= dependency does not tear down already-running dependents
That means DDM can remain running while its control socket is gone.
At that point VT change handling is effectively dead until something else restarts DDM.
Reproduction
A minimal systemd reproducer shows the difference clearly:
Requires=seatd.service + After=seatd.service
- start both services
- kill the seatd main pid directly
Observed result:
seatd.service becomes inactive
- the dependent service stays active
This matches the socket-loss case in DDM: the daemon can survive while the control channel is gone.
Proposed fixes
I see two complementary options:
-
Make DDM self-heal
- add reconnect/backoff logic in
DdeSeatdControl
- re-establish the event socket after
errorOccurred / disconnected
- refresh cached active VT after reconnect
-
Make the service dependency stricter
- upgrade the unit relationship from
Requires= to BindsTo= for the dde-seatd.service dependency
- keep
Restart=always on DDM so a dde-seatd death causes DDM to be torn down and brought back together with the seat daemon
I validated the second approach with a minimal systemd setup:
BindsTo=seatd.service
Restart=always on both services
- kill the seatd main pid
Observed result:
- seatd is restarted
- the dependent service is also restarted
Files
src/daemon/DdeSeatdControl.cpp
services/ddm.service.in
Summary
DDM does not recover cleanly if the
dde-seatdcontrol socket disappears unexpectedly.DdeSeatdControldisconnects and clears its cached state on socket error, but it does not attempt to reconnect. Ifdde-seatddies and comes back, DDM can stay alive while permanently losing VT change notifications.Current behavior
src/daemon/DdeSeatdControl.cppuses/run/dde-seatd-control.sockand does this on failure:connectEventSocket()fails -> log + give uphandleEventSocketError()->disconnectEventSocket()disconnectEventSocket()clears the socket and cached VT stateThere is no retry loop and no service-level recovery path inside DDM.
Why this matters
I validated the systemd side separately:
dde-seatdis explicitly stopped/restarted bysystemctl,Requires=is enough for systemd to stop/restart dependent services in the same transactiondde-seatdprocess dies unexpectedly, a plainRequires=dependency does not tear down already-running dependentsThat means DDM can remain running while its control socket is gone.
At that point VT change handling is effectively dead until something else restarts DDM.
Reproduction
A minimal systemd reproducer shows the difference clearly:
Requires=seatd.service+After=seatd.serviceObserved result:
seatd.servicebecomes inactiveThis matches the socket-loss case in DDM: the daemon can survive while the control channel is gone.
Proposed fixes
I see two complementary options:
Make DDM self-heal
DdeSeatdControlerrorOccurred/disconnectedMake the service dependency stricter
Requires=toBindsTo=for thedde-seatd.servicedependencyRestart=alwayson DDM so adde-seatddeath causes DDM to be torn down and brought back together with the seat daemonI validated the second approach with a minimal systemd setup:
BindsTo=seatd.serviceRestart=alwayson both servicesObserved result:
Files
src/daemon/DdeSeatdControl.cppservices/ddm.service.in