[ksystemstats] [Bug 524423] New: "All Disks" write rate stays frozen after removing a busy volume; re-mounted volumes no longer counted

"Cooper Morgan" <[email protected]>
Newsgroups gmane.comp.kde.devel.bugs
Message-ID <[email protected]/>
https://bugs.kde.org/show_bug.cgi?id=524423

            Bug ID: 524423
           Summary: "All Disks" write rate stays frozen after removing a
                    busy volume; re-mounted volumes no longer counted
    Classification: Frameworks and Libraries
           Product: ksystemstats
      Version First 6.7.4
       Reported In:
          Platform: Fedora RPMs
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: General
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected]
  Target Milestone: ---

Created attachment 195253
  --> https://bugs.kde.org/attachment.cgi?id=195253&action=edit
Stale disk activity after unmounting USB on flush.

DESCRIPTION
When a mounted volume is removed while it is still being written to (e.g.
ejecting a USB stick right after a large copy, while the unmount flush is still
running), the "All Disks" write rate in ksystemstats freezes at that volume's
last sampled rate and never returns to zero. The Disk Activity widget then
shows a flat nonzero write line with the system idle. If the same volume is
mounted again, its writes are no longer counted in "All Disks" at all. Both
persist until plasma-ksystemstats is restarted.

Cause (ksystemstats 6.7.4, unchanged on master): in plugins/disks/disks.cpp the
deviceRemoved and accessibilityChanged(false) handlers call
container->removeObject() and drop the VolumeObject from m_volumesByDevice, but
never delete it. Rates are only refreshed in update() for devices still in that
map, so the removed object's read/write properties keep their last value.
SensorContainer::removeObject() (libksysguard) only clears its private parent
field, not the QObject parent, and AggregateSensor::updateSensors() evicts
members based on QObject::parent(), so the aggregate keeps summing the dead
sensor. addSensor() then rejects the re-mounted volume's sensor because
d->sensors is keyed by path and the dead one still owns "disk/<uuid>/write".

Adding `(*it)->deleteLater()` after `container->removeObject(*it)` in both
handlers fixes it (the aggregate already drops null QPointers on the next
updateSensors()). Also fixes the leak of one VolumeObject per removal.

STEPS TO REPRODUCE
1. `systemctl --user restart plasma-ksystemstats.service`; mount a USB stick
(e.g., /dev/sdX1) and subscribe to the aggregate: `busctl --user call
org.kde.ksystemstats1 /org/kde/ksystemstats1 org.kde.ksystemstats1 subscribe as
1 disk/all/write`
2. Write to it, bypassing the page cache so the device stays busy: `dd
if=/dev/zero of=/run/media/$USER/STICK/junk bs=1M count=2500 oflag=direct &`.
After ~10 s, sensorData for disk/all/write shows the device's write speed.
3. Remove the volume while dd is still running (stands in for eject during
flush): `udisksctl unmount -b /dev/sdX1 --force`
4. Wait for dd to finish, confirm /proc/diskstats shows no writes, then read
   disk/all/write again: `busctl --user call org.kde.ksystemstats1
/org/kde/ksystemstats1 org.kde.ksystemstats1 sensorData as 1 disk/all/write`
5. Mount the stick again, write to it, read disk/all/write.

OBSERVED RESULT
Step 4: disk/all/write stays at the last rate (3.36e7 B/s = 32 MiB/s here)
indefinitely; the Disk Activity widget shows a flat 32 MiB/s write line
(screenshot attached, from an actual eject after an rsync).
Step 5: disk/all/write does not change while the re-mounted stick is being
written at ~33 MB/s. With a normal (non-lazy) unmount the phantom value is
whatever the last sample was; if that was 0 nothing is visible, but step 5
still fails.

EXPECTED RESULT
Removed volumes stop contributing; re-mounted volumes are counted again.

SOFTWARE/OS VERSIONS
Operating System: Fedora Linux 44
KDE Plasma Version: 6.7.4
KDE Frameworks Version: 6.29.0
Qt Version: 6.11.1

ADDITIONAL INFORMATION
Workaround: systemctl --user restart plasma-ksystemstats.service Related: the
deviceRemoved handler builds Solid::Device(udi) for an already removed device
and gates on isDeviceInterface(StorageAccess); if that is false for a vanished
device, raw-disk objects (/dev/sdX itself) are never removed either. Not
visible in the aggregate since root devices are filtered, but the same leak.

-- 
You are receiving this mail because:
You are watching all bug changes.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.