]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cephadm: convert lists back to tuples when loading last_client_files 68553/head
authoryaelazulay-redhat <yaelazulay@redhat.com>
Wed, 22 Apr 2026 16:08:22 +0000 (19:08 +0300)
committeryaelazulay-redhat <yaelazulay@redhat.com>
Mon, 27 Apr 2026 15:56:03 +0000 (18:56 +0300)
Problem: ceph mgr fail or active ceph mgr restart causes unnecessary client files recreation on _admin hosts. Files such as /etc/ceph/ceph.conf and /etc/ceph/ceph.client.admin.keyring are rewritten even when their content has not changed.

Root cause:
update_client_file() stores client file metadata as a Python tuple (digest, mode, uid, gid).
When save_host() persists this to the mon store via json.dumps(), the tuple is serialized as a JSON array since JSON has no tuple type.
On mgr failover or restart, cache.load() deserializes the data with json.loads(), which returns a Python list instead of a tuple.
The comparison in _write_client_files(): match = old_files[path] == (digest, mode, uid, gid) then compares a list (from JSON) against a tuple (freshly built), which always evaluates to False.
This causes every client file to be rewritten on every mgr failover or restart.

Code Fixes:
1. src/pybind/mgr/cephadm/inventory.py:
    convert the deserialized lists back to tuples when loading last_client_files

Fixes: https://tracker.ceph.com/issues/76176
Signed-off-by: Yael Azulay <yazulay@redhat.com>
src/pybind/mgr/cephadm/inventory.py

index aed6ba03efadb406ce9fc42a08864007bed7a1d2..58a8fb1449091351b72a5d929309006ae7607e90 100644 (file)
@@ -842,7 +842,9 @@ class HostCache():
                 self.devices[host] += self.load_host_devices(host)
                 self.networks[host] = j.get('networks_and_interfaces', {})
                 self.osdspec_previews[host] = j.get('osdspec_previews', {})
-                self.last_client_files[host] = j.get('last_client_files', {})
+                self.last_client_files[host] = {
+                    path: tuple(v) for path, v in j.get('last_client_files', {}).items()
+                }
                 for name, ts in j.get('osdspec_last_applied', {}).items():
                     self.osdspec_last_applied[host][name] = str_to_datetime(ts)