Bug 525911 - plasma-shutdown: KWin failed to complete logout
Summary: plasma-shutdown: KWin failed to complete logout
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: general (other bugs)
Version First Reported In: unspecified
Platform: Fedora RPMs Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL: https://invent.kde.org/plasma/plasma-...
Keywords:
Depends on:
Blocks:
 
Reported: 2026-09-18 17:02 UTC by lordgreg+kdeorg
Modified: 2026-09-26 00:55 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed/Implemented In: 6.7.6
Sentry Crash Report:


Attachments
dbus-monitor (2.70 KB, text/x-log)
2026-09-19 07:11 UTC, lordgreg+kdeorg
Details
journalctl (6.78 KB, text/x-log)
2026-09-19 07:11 UTC, lordgreg+kdeorg
Details

Note You need to log in before you can comment on or make changes to this bug.
Description lordgreg+kdeorg 2026-09-18 17:02:12 UTC
## Summary

When using Discover's **"Reboot after update"** functionality on Fedora 44 with KDE Plasma 6.7.5, the applications are closed, but the Plasma session does not actually log out and the system therefore does not reboot.

The user is left at the normal Plasma desktop with no application windows open.

`plasma-shutdown` is started through D-Bus and reports:

```text
KWin failed to complete logout
```

After this, `plasma-shutdown` exits, but the Plasma desktop remains active.

## Environment

* Fedora Linux 44
* KDE Plasma 6.7.5
* KWin 6.7.5
* Wayland
* Qt 6.11.2
* Kernel 7.2.5-200.fc44.x86_64
* AMD Radeon RX 9070 XT
* Mesa 26.2.2
* Display: Alienware AW3423DWF, 3440x1440 @ 164.9 Hz
* Adaptive Sync: Automatic

Relevant packages:

```text
plasma-workspace-6.7.5-1.fc44.x86_64
plasma-discover-6.7.5-1.fc44.x86_64
plasma-discover-offline-updates-6.7.5-1.fc44.x86_64
kwin-6.7.5-1.fc44.x86_64
kwin-common-6.7.5-1.fc44.x86_64
kwin-libs-6.7.5-1.fc44.x86_64
```

## Steps to reproduce

1. Boot into a KDE Plasma Wayland session.
2. Have a system update available in Discover.
3. In Discover, install the update and select **"Reboot after update"**.
4. The applications/windows close.
5. Wait for the reboot.

## Actual result

The applications close, but the Plasma session **does not log out**.

The user remains at the normal Plasma desktop with no application windows open.

The computer does not reboot.

The following was recorded immediately after the failure:

```text
[40195.667852] fedora systemd[1510]: Started dbus-:1.2-org.kde.Shutdown@0.service.
[40198.140498] fedora steam[547480]: [2026-09-18 18:52:05] Shutdown
[40200.509158] fedora plasma-shutdown[654652]: KWin failed to complete logout
```

At that point:

```text
$ pgrep -a plasma-shutdown
```

returned no process.

The D-Bus services were back to their activatable state:

```text
org.kde.LogoutPrompt  - - - (activatable)
org.kde.Shutdown      - - - (activatable)
```

## Expected result

After selecting **"Reboot after update"**, Discover should install the updates, log out of the current Plasma session, and reboot the computer.

## Additional observation from an earlier occurrence

An earlier occurrence of the problem behaved slightly differently.

`plasma-shutdown` remained running for approximately 10 minutes:

```text
PID 605137 /usr/bin/plasma-shutdown
```

It was blocked in `ppoll()` rather than consuming CPU and remained responsive to D-Bus.

It owned:

```text
org.kde.Shutdown
```

Calling:

```bash
busctl --user call org.kde.Shutdown /Shutdown \
    org.kde.Shutdown logout
```

immediately caused the pending reboot to proceed.

During that occurrence, repeated `ksmserver-logout-greeter` activations produced:

```text
org.kde.Shutdown D-Bus service is already registered; quitting
```

The relevant D-Bus service definitions are:

```text
/usr/share/dbus-1/services/org.kde.Shutdown.service

[D-BUS Service]
Name=org.kde.Shutdown
Exec=/usr/bin/plasma-shutdown
```

and:

```text
/usr/share/dbus-1/services/org.kde.LogoutPrompt.service

[D-BUS Service]
Name=org.kde.LogoutPrompt
Exec=/usr/libexec/ksmserver-logout-greeter
```

Both are provided by `plasma-workspace-6.7.5-1.fc44.x86_64`.

## Notes

The failure appears to occur during the transition from closing applications to logging out of the Plasma session.

The latest reproduction does **not** leave `plasma-shutdown` running. Instead, it exits after reporting:

```text
KWin failed to complete logout
```

while the Plasma desktop remains active.

An earlier occurrence left `plasma-shutdown` waiting indefinitely, and manually invoking its D-Bus `logout` method allowed the reboot to proceed.

I am therefore unsure whether the root cause is in KWin, `plasma-shutdown`, Plasma session management, or the D-Bus shutdown sequence.

I would love to help you with more information if you require so.


After the failure:
$ pgrep -a plasma-shutdown
(no output)

$ busctl --user list | grep -E 'org\.kde\.(Shutdown|Logout)'
org.kde.LogoutPrompt  - - - (activatable) - - -
org.kde.Shutdown      - - - (activatable) - - -

$ systemctl --user status 'dbus-:1.2-org.kde.Shutdown@*.service'
(no output)
Comment 1 lordgreg+kdeorg 2026-09-18 20:57:41 UTC
I could reproduce it again on the same evening:

```
  21:55:59  plasma-shutdown started (org.kde.Shutdown activated) 21:59:04  ksmserver-logout-greeter: "org.kde.Shutdown D-Bus service is already registered; quitting" 22:09:45  ksmserver-logout-greeter: "org.kde.Shutdown D-Bus service is already registered; quitting" 22:16:37  ksmserver-logout-greeter: "org.kde.Shutdown D-Bus service is already registered; quitting"
```

plasma-shutdown (single process, PID stable throughout) sat idle in ppoll() the whole time, holding org.kde.Shutdown, while three separate attempts to open the logout prompt over the next ~20 minutes all bailed out immediately because the name was already taken — matching the "earlier occurrence" behavior described in the original report.

Manually running:

```
  busctl --user call org.kde.Shutdown /Shutdown org.kde.Shutdown logout
```

unstuck it immediately: closeSession → closeWaylandWindows completed cleanly within ~2 seconds and the machine rebooted, confirming the reboot itself had already been armed independently and was just waiting for the session to actually end.

A gdb backtrace taken while it was stuck showed the main thread parked at the top of the Qt event loop (QCoreApplication::exec() → ppoll), with no synchronous call frame — consistent with an async QDBusPendingCallWatcher (e.g. for closeSession or closeWaylandWindows) whose reply never arrived, rather than a deadlock or busy loop.
Comment 2 lordgreg+kdeorg 2026-09-19 07:08:16 UTC
Following up on my earlier comments: I instrumented the session with a scoped busctl --user monitor capture (matching org.kde.Shutdown, org.kde.KWin.Session, org.kde.KSMServerInterface, org.kde.LogoutPrompt, plus all D-Bus errors) and caught the failure live this morning. This is a full wire-level confirmation of the race I described earlier, not a hypothesis anymore.

Trace (timestamps UTC, from the same failure — journal shows the matching KWin failed to complete logout at the same second):

```
  07:01:50.872  :1.171 → org.kde.Shutdown /Shutdown org.kde.Shutdown.logoutAndReboot     [call #1] 07:01:50.927  plasma-shutdown → org.kde.ksmserver /KSMServer  closeSession             [flow #1] 07:01:50.928  ksmserver → org.kde.KWin /Session  setState(1)  [Saving]

  07:01:51.259  :1.171 → org.kde.Shutdown /Shutdown org.kde.Shutdown.logoutAndReboot     [call #2, +386ms, SAME sender] 07:01:51.259  plasma-shutdown → org.kde.ksmserver /KSMServer  closeSession             [flow #2, duplicate]

  07:01:53.135  ksmserver → org.kde.KWin /Session  setState(2)  [Quitting] 07:01:53.137  plasma-shutdown → org.kde.KWin /Session  closeWaylandWindows             [flow #1's call] 07:01:53.137  plasma-shutdown → org.kde.KWin /Session  closeWaylandWindows             [flow #2's call, +387ms] 07:01:53.137  KWin → error org.freedesktop.DBus.Error.Failed: "Operation already in progress"
                (reply to flow #2's closeWaylandWindows call) 07:01:53.138  plasma-shutdown → org.kde.ksmserver /KSMServer  resetLogout
```

:1.171 traces to plasma-discover (PID 609089, running 08:55:07–09:01:53, systemd scope closing at the exact same second as the failure). So this is Discover's own DiscoverObject::rebootNow() calling org.kde.Shutdown.logoutAndReboot twice, 386ms apart, from the same process — consistent with UpdatesPage.qml's onStateChanged handler re-entering the "reboot" state (no guard against firing more than once; see my first comment on this bug for the PreparedUpgrade property-invalidation churn that would drive that).

Both calls raced through the same running plasma-shutdown process, since Shutdown::startLogout() (plasma-workspace/startkde/plasma-shutdown/shutdown.cpp) has no re-entrancy guard — nothing stops two concurrent logoutAndReboot() invocations. Both flows eventually reach Shutdown::ksmServerComplete() and call KWin's closeWaylandWindows(). KWin's own single-flight guard (m_closingWindowsGuard in kwin/src/sm.cpp, SessionManager::closeWaylandWindows()) correctly rejects the second call with exactly "Operation already in progress" — that string is a direct match to the sendErrorReply(QDBusError::Failed, u"Operation already in progress"_s) in that function.

The problem is what happens next: that rejection lands in flow #2's QDBusPendingCallWatcher, and Shutdown::ksmServerComplete()'s error branch does:

```cpp
  qCWarning(PLASMA_SESSION) << "KWin failed to complete logout";
  ksmserverIface.resetLogout();
  logoutCancelled();   // → qApp->quit()
```

Since both flows live in the same process, qApp->quit() tears down the entire plasma-shutdown process — including flow #1's still-pending, legitimate closeWaylandWindows() call (sent one message earlier, Cookie=16 vs Cookie=20), which had a real chance of completing successfully on its own. The session never ends; the user is left at the desktop with all applications already closed.
Comment 3 lordgreg+kdeorg 2026-09-19 07:11:21 UTC
Created attachment 196353 [details]
dbus-monitor
Comment 4 lordgreg+kdeorg 2026-09-19 07:11:56 UTC
Created attachment 196354 [details]
journalctl
Comment 5 lordgreg+kdeorg 2026-09-21 18:03:01 UTC
```markdown
  **Update — this looks like a regression, not a long-standing bug**

  I hadn't hit this before roughly a month ago, and it was working flawlessly prior to that. I don't have an exact "last known good" date, but checking `dnf5 history list`, here's every update in that window that touches a component involved in this bug:

```

2026-08-07  plasma-workspace / plasma-discover  -> 6.7.4-1 2026-08-26  dnf5 / libdnf5                       -> 5.4.3.0-2  (455 pkgs) 2026-09-02  plasma-workspace                     -> 6.7.4-2 2026-09-09  dnf5 / libdnf5                        -> 5.4.4.0-1 2026-09-10  plasma-workspace / plasma-discover   -> 6.7.5-1  (current) 2026-09-15  PackageKit                            -> 1.4.0-1  (current, 522 pkgs) 2026-09-18  dnf5 / libdnf5  (05:41)               -> 5.4.5.0-1  (current) 2026-09-18  first documented failure (18:52)

```

  The `dnf5`/`libdnf5` upgrade at 05:41 landed roughly 13 hours before the first failure I reported that same day, and `dnf5`/`libdnf5` was updated three separate times in this window total. I can't pin down the exact update that introduced this (my "last known good" is approximate), but this feels like a significant lead given the mechanism I described earlier: the double `logoutAndReboot()` call from Discover appears to be triggered by `PackageKit.Offline` D-Bus property churn, and `libdnf5` is what backs PackageKit's `dnf5` backend and would control how/when those properties get set and change during an offline-update transaction.

  If a `dnf5`/`libdnf5` behavior change altered the timing or frequency of `PackageKit.Offline` property-change signals during an offline transaction, that could explain why this wasn't showing up before and is now — without Discover's own QML code having changed at all recently (the relevant `onStateChanged` handler in `UpdatesPage.qml` has been unchanged since it landed in 6.7.0, well before this window).

  Not conclusive, but seemed worth recording in case it helps narrow down where to look, or in case anyone else can correlate this against their own update history.
```
Comment 6 lordgreg+kdeorg 2026-09-21 19:20:53 UTC
  **Correction to my last update**

  I asked a friend running the exact same setup to check his package versions directly, rather than assume from matching PackageKit backend type. His versions are identical to mine:

```

dnf5-5.4.5.0-1.fc44.x86_64 
libdnf5-5.4.5.0-1.fc44.x86_64 
PackageKit-1.4.0-1.fc44.x86_64 
PackageKit-Qt6-1.1.4-4.fc44.x86_64

```

  So the dnf5/libdnf5 version isn't the deciding factor — he's on the same build and doesn't reproduce this despite using "Reboot after update" regularly. Whatever differs between our two machines, it isn't package versions. Still think the regression timeline on my own machine is real (I have update-history timestamps that make it look new), but it's apparently not sufficient on its own — something else has to combine with it. Still narrowing this down.
Comment 7 Bug Janitor Service 2026-09-21 20:03:06 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/7087
Comment 8 Bug Janitor Service 2026-09-21 20:03:08 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/7087
Comment 9 lordgreg+kdeorg 2026-09-22 16:13:59 UTC
If you read this, the PR with the GUARD has been merged to master: https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/7087
Comment 10 Bug Janitor Service 2026-09-22 16:27:44 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/7096
Comment 11 Bug Janitor Service 2026-09-22 16:29:10 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/7097
Comment 12 Nate Graham 2026-09-25 06:44:11 UTC
Fixed by Gregor Papez with https://invent.kde.org/plasma/plasma-workspace/-/merge_requests/7087
Comment 13 Nate Graham 2026-09-26 00:48:38 UTC
Git commit 05ad367e99af513e174c12968d06a2f33f305c75 by Nate Graham, on behalf of David Edmundson.
Committed on 26/09/2026 at 00:30.
Pushed by ngraham into branch 'Plasma/6.8'.

plasma-shutdown: Guard against concurrent logout/reboot/shutdown requests

A second, overlapping call to logout()/logoutAndShutdown()/logoutAndReboot()
while one is already in progress starts a duplicate startLogout() flow in
the same process. Both flows eventually call KWin's
SessionManager::closeWaylandWindows(), which correctly rejects the second,
overlapping call with "Operation already in progress". That rejection is
currently treated as fatal: Shutdown::ksmServerComplete() reacts to it by
calling resetLogout() and logoutCancelled(), which calls qApp->quit() and
tears down the whole plasma-shutdown process - including the first,
legitimate request that was still in flight and would very plausibly have
completed successfully on its own.

Reuse m_shutdownType itself to detect this instead of adding a new member:
ShutdownTypeNone now consistently means idle, and logout() uses the
previously-unused ShutdownTypeLogout instead of ShutdownTypeNone to avoid
ambiguity between "plain logout in progress" and "idle".


(cherry picked from commit e873611cb6757a20bd0c0218690f64c2515c3e28)

Co-authored-by: Gregor Papez <gregorp+kde@gmail.com>

M  +8    -1    startkde/plasma-shutdown/shutdown.cpp
M  +2    -1    startkde/plasma-shutdown/shutdown.h

https://invent.kde.org/plasma/plasma-workspace/-/commit/05ad367e99af513e174c12968d06a2f33f305c75
Comment 14 Nate Graham 2026-09-26 00:55:49 UTC
Git commit f0d1bd007cd77b8925ea7681f64960df4c3bd05c by Nate Graham, on behalf of David Edmundson.
Committed on 26/09/2026 at 00:48.
Pushed by ngraham into branch 'Plasma/6.7'.

plasma-shutdown: Guard against concurrent logout/reboot/shutdown requests

A second, overlapping call to logout()/logoutAndShutdown()/logoutAndReboot()
while one is already in progress starts a duplicate startLogout() flow in
the same process. Both flows eventually call KWin's
SessionManager::closeWaylandWindows(), which correctly rejects the second,
overlapping call with "Operation already in progress". That rejection is
currently treated as fatal: Shutdown::ksmServerComplete() reacts to it by
calling resetLogout() and logoutCancelled(), which calls qApp->quit() and
tears down the whole plasma-shutdown process - including the first,
legitimate request that was still in flight and would very plausibly have
completed successfully on its own.

In practice this can be triggered by a client issuing the D-Bus call twice
in quick succession (e.g. observed with Discover's "Reboot after update"
firing org.kde.Shutdown.logoutAndReboot twice, ~400 microseconds apart, due
to a QML state re-entry issue). The user ends up with all applications
closed but the session never actually logging out or rebooting.

This adds a simple re-entrancy guard: a second concurrent request is
ignored (logged and returned early) instead of racing a duplicate flow
against the first one. Confirmed against a live reproduction: deliberately
issuing logoutAndReboot() twice in rapid succession, which reliably
reproduced the crash before this change, now completes the first request
cleanly with no collision.


(cherry picked from commit f2af69292edab289cec0735a438dc893b0792edc)

Co-authored-by: Gregor Papez <gregorp+kde@gmail.com>

M  +8    -0    startkde/plasma-shutdown/shutdown.cpp
M  +8    -0    startkde/plasma-shutdown/shutdown.h

https://invent.kde.org/plasma/plasma-workspace/-/commit/f0d1bd007cd77b8925ea7681f64960df4c3bd05c