https://bugs.documentfoundation.org/show_bug.cgi?id=173274
Bug ID: 173274
Summary: UnoServer does not exit on SIGTERM: systemd stop times
out and SIGKILLs both unoserver and oosplash
Product: LibreOffice
Version: 25.2.3.2 release
Hardware: x86-64 (AMD64)
OS: Linux (All)
Status: UNCONFIRMED
Severity: normal
Priority: medium
Component: LibreOffice
Assignee: [email protected]
Reporter: [email protected]
Description:
`systemctl stop` (or `restart`) never completes on its own. The signal handler
in `server.py` runs and logs `Sending signal to LibreOffice`, but neither the
`unoserver` process nor the `oosplash` child ever exits. systemd waits the full
`TimeoutStopSec` (90 s by default) and then SIGKILLs the whole cgroup,
recording the stop as failed.
This makes every service restart cost 90 seconds, and adds the same delay to
every
system reboot.
Steps to Reproduce:
1. Run unoserver under systemd with the unit above.
2. Wait for `INFO:unoserver:Started.`
3. `systemctl stop unoserver.service` — the command blocks for 90 s, and the
journal
shows the sequence above.
The same happens whether or not a conversion has ever been performed.
## Where it seems to come from
In `unoserver/server.py` (3.7), `signal_handler` forwards the received signal
to
`self.libreoffice_process` and then calls `self.stop()`:
```python
def signal_handler(signum, frame):
self.intentional_exit = True
logger.info("Sending signal to LibreOffice")
try:
self.libreoffice_process.send_signal(signum)
except ProcessLookupError as e:
if e.errno != 3:
raise
if self.xmlrcp_server is not None:
self.stop() # Ensure the server stops
```
Two things are worth checking, and I could not tell them apart from the
outside:
1. `self.libreoffice_process` is the process spawned from the `soffice`
launcher, which
on Linux becomes `oosplash`. The journal shows `oosplash` still alive 90
seconds after
the signal was sent, so either the signal is not delivered where it is
expected, or
`oosplash` does not propagate it to `soffice.bin`.
2. The main Python process does not exit either, which suggests the XML-RPC
serving
thread is not being joined or `serve_forever` is not interrupted by
`self.stop()`.
I am reporting the observation rather than proposing a patch, since I do not
know which
of the two is the intended shutdown path.
Actual Results:
## Journal (default unit, `TimeoutStopSec=90s`, `KillMode=control-group`)
```
08:33:28 unoserver[2931667]: INFO:unoserver:Sending signal to LibreOffice
08:33:28 systemd[1]: Stopping unoserver.service...
08:34:58 systemd[1]: unoserver.service: State 'stop-sigterm' timed out.
Killing.
08:34:58 systemd[1]: unoserver.service: Killing process 2931667 (unoserver)
with signal SIGKILL.
08:34:58 systemd[1]: unoserver.service: Killing process 2931753 (oosplash) with
signal SIGKILL.
08:34:58 systemd[1]: unoserver.service: Main process exited, code=killed,
status=9/KILL
08:34:58 systemd[1]: unoserver.service: Failed with result 'timeout'.
08:34:58 systemd[1]: Stopped unoserver.service.
```
Exactly 90 seconds between `Stopping` and `Killing`, i.e. the full stop
timeout, on every single restart. Note that the handler did run: the `Sending
signal to LibreOffice` line is emitted by `signal_handler` itself.
Expected Results:
see above
Reproducible: Always
User Profile Reset: Yes
Additional Info:
## Environment
| | |
|---|---|
| unoserver | 3.7 (pip, in a venv with `--system-site-packages`) |
| LibreOffice | 25.2.3.2 520(Build:2) |
| python3-uno | 4:25.2.3-2+deb13u6 |
| Python | 3.13.5 |
| OS | Debian 13.6 (trixie) |
| Started by | systemd, `Type=simple` |
## Workaround
Bounding the wait in the unit file, so a restart costs ~15 s instead of ~95 s:
```ini
TimeoutStopSec=15
KillMode=mixed
```
`KillMode=mixed` sends SIGTERM to the main process only, then SIGKILL to the
whole
control group once the timeout expires, which reliably takes LibreOffice down
with it.
Everything else works well: with LibreOffice 25.2 and Python 3.13, conversions
run in
roughly 110–300 ms for text documents, and this is on a site where the previous
unoconv-based setup had been failing on every conversion for years.
--
You are receiving this mail because:
You are the assignee for the bug.