]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
tools/cephfs/first-damage: fix iteration of big dirfrags 49796/head
authorPatrick Donnelly <pdonnell@redhat.com>
Wed, 18 Jan 2023 19:39:00 +0000 (14:39 -0500)
committerPatrick Donnelly <pdonnell@redhat.com>
Thu, 19 Jan 2023 18:04:50 +0000 (13:04 -0500)
We have to iterate in chunks otherwise the get_omap_vals API returns
partial results even if the max count is large.

Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
qa/workunits/fs/damage/test-first-damage.sh
src/tools/cephfs/first-damage.py

index c1ae71ed013bf3c1c1e2e6eeea9fbe51e247de68..5cbae5f37fa125ace04de3e43ad7f4b97720d9c4 100755 (executable)
@@ -14,6 +14,7 @@ function usage {
 
 
 function create {
+  ceph config set mds mds_bal_fragment_dirs 0
   mkdir dir
   DIR_INODE=$(stat -c '%i' dir)
   touch dir/a
@@ -35,6 +36,11 @@ function create {
   touch dir/a
   # unlink then create, HEAD not snapped
   ls dir/.snap/*/
+  mkdir big
+  BIG_DIR_INODE=$(stat -c '%i' big)
+  for i in `seq 1 15000`; do
+    touch $(printf 'big/%08d' $i)
+  done
 }
 
 function flush {
@@ -62,6 +68,12 @@ function damage {
   printf '\xfe\xff\xff\xff' | dd of="$T" count=4 bs=1 conv=notrunc,nocreat
   rados --pool="$METADATA_POOL" setomapval "$IS" a_head --input-file="$T"
 
+  # screw up HEAD on what dentry in big
+  IS=$(printf '%llx.%08llx' "$BIG_DIR_INODE" 0)
+  rados --pool="$METADATA_POOL" getomapval "$IS" 00009999_head "$T"
+  printf '\xfe\xff\xff\xff' | dd of="$T" count=4 bs=1 conv=notrunc,nocreat
+  rados --pool="$METADATA_POOL" setomapval "$IS" 00009999_head --input-file="$T"
+
   rm -f "$T"
 }
 
index db61f972b46649a71651a03885deac56a96fabc5..b7660f590f098f3950cd951c32c374bc1244d893 100644 (file)
@@ -76,26 +76,32 @@ def traverse(MEMO, ioctx):
         log.info("examining: %s", o.key)
 
         with rados.ReadOpCtx() as rctx:
-            it = ioctx.get_omap_vals(rctx, None, None, 100000)[0]
-            ioctx.operate_read_op(rctx, o.key)
-            for (dnk, val) in it:
-                log.debug('\t%s: val size %d', dnk, len(val))
-                (first,) = struct.unpack('<I', val[:4])
-                if first > NEXT_SNAP:
-                    log.warning(f"found {o.key}:{dnk} first (0x{first:x}) > NEXT_SNAP (0x{NEXT_SNAP:x})")
-                    if REPAIR_NOSNAP and dnk.endswith("_head") and first == CEPH_NOSNAP:
-                        log.warning(f"repairing first==CEPH_NOSNAP damage, setting to NEXT_SNAP (0x{NEXT_SNAP:x})")
-                        first = NEXT_SNAP
-                        nval = bytearray(val)
-                        struct.pack_into("<I", nval, 0, NEXT_SNAP)
-                        with rados.WriteOpCtx() as wctx:
-                            ioctx.set_omap(wctx, (dnk,), (bytes(nval),))
-                            ioctx.operate_write_op(wctx, o.key)
-                    elif REMOVE:
-                        log.warning(f"removing {o.key}:{dnk}")
-                        with rados.WriteOpCtx() as wctx:
-                            ioctx.remove_omap_keys(wctx, [dnk])
-                            ioctx.operate_write_op(wctx, o.key)
+            nkey = None
+            while True:
+                it = ioctx.get_omap_vals(rctx, nkey, None, 100)[0]
+                ioctx.operate_read_op(rctx, o.key)
+                nkey = None
+                for (dnk, val) in it:
+                    log.debug('\t%s: val size %d', dnk, len(val))
+                    (first,) = struct.unpack('<I', val[:4])
+                    if first > NEXT_SNAP:
+                        log.warning(f"found {o.key}:{dnk} first (0x{first:x}) > NEXT_SNAP (0x{NEXT_SNAP:x})")
+                        if REPAIR_NOSNAP and dnk.endswith("_head") and first == CEPH_NOSNAP:
+                            log.warning(f"repairing first==CEPH_NOSNAP damage, setting to NEXT_SNAP (0x{NEXT_SNAP:x})")
+                            first = NEXT_SNAP
+                            nval = bytearray(val)
+                            struct.pack_into("<I", nval, 0, NEXT_SNAP)
+                            with rados.WriteOpCtx() as wctx:
+                                ioctx.set_omap(wctx, (dnk,), (bytes(nval),))
+                                ioctx.operate_write_op(wctx, o.key)
+                        elif REMOVE:
+                            log.warning(f"removing {o.key}:{dnk}")
+                            with rados.WriteOpCtx() as wctx:
+                                ioctx.remove_omap_keys(wctx, [dnk])
+                                ioctx.operate_write_op(wctx, o.key)
+                    nkey = dnk
+                if nkey is None:
+                    break
         MEMO.write(f"{o.key}\n")
 
 if __name__ == '__main__':