From 2e61ae71f6dfb5e504f5222204e1c66079654ef3 Mon Sep 17 00:00:00 2001 From: George Wilson Date: Sat, 25 Mar 2023 09:14:50 -0400 Subject: [PATCH] Add blkptr command to sdb --- sdb/commands/zfs/blkptr.py | 164 ++++++++++++++++ sdb/commands/zfs/internal/__init__.py | 182 ++++++++++++++++++ ...mber dn_phys |member dn_blkptr[0] |blkptr" | 6 + ...mber dn_phys |member dn_blkptr[0] |blkptr" | 1 + .../dbuf | head 1 | member db_blkptr | blkptr | 4 + ... spa_uberblock | member ub_rootbp | blkptr | 6 + ...mber dn_phys |member dn_blkptr[0] |blkptr" | 4 + ...mber dn_phys |member dn_blkptr[0] |blkptr" | 4 + .../dbuf | head 1 | member db_blkptr | blkptr | 4 + ... spa_uberblock | member ub_rootbp | blkptr | 4 + tests/integration/test_linux_generic.py | 2 + tests/integration/test_zfs_generic.py | 4 + 12 files changed, 385 insertions(+) create mode 100644 sdb/commands/zfs/blkptr.py create mode 100644 "tests/integration/data/regression_output/dump.201912060006/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | head 6056 | tail 1| cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" create mode 100644 "tests/integration/data/regression_output/dump.201912060006/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | tail 8 | head 1 | cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" create mode 100644 tests/integration/data/regression_output/dump.201912060006/zfs/dbuf | head 1 | member db_blkptr | blkptr create mode 100644 tests/integration/data/regression_output/dump.201912060006/zfs/spa | head 1 | deref |member spa_uberblock | member ub_rootbp | blkptr create mode 100644 "tests/integration/data/regression_output/dump.202303131823/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | head 6056 | tail 1| cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" create mode 100644 "tests/integration/data/regression_output/dump.202303131823/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | tail 8 | head 1 | cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" create mode 100644 tests/integration/data/regression_output/dump.202303131823/zfs/dbuf | head 1 | member db_blkptr | blkptr create mode 100644 tests/integration/data/regression_output/dump.202303131823/zfs/spa | head 1 | deref |member spa_uberblock | member ub_rootbp | blkptr diff --git a/sdb/commands/zfs/blkptr.py b/sdb/commands/zfs/blkptr.py new file mode 100644 index 0000000..b09a227 --- /dev/null +++ b/sdb/commands/zfs/blkptr.py @@ -0,0 +1,164 @@ +# +# Copyright 2019, 2023 Delphix +# Copyright 2021 Datto, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# pylint: disable=missing-docstring + +from typing import Iterable + +import drgn +import sdb +from sdb.commands.zfs.internal import ( + BP_GET_TYPE, BP_GET_CHECKSUM, BP_GET_COMPRESS, BP_GET_LEVEL, BP_GET_LSIZE, + BP_GET_BIRTH, BP_GET_PSIZE, BP_LOGICAL_BIRTH, BP_IS_HOLE, BP_GET_NDVAS, + BP_IS_ENCRYPTED, BP_IS_GANG, BP_GET_LAYER, BP_IS_AUTHENTICATED, + BP_HAS_INDIRECT_MAC_CKSUM, BP_GET_BYTEORDER, BP_GET_DEDUP, BP_IS_EMBEDDED, + BP_IS_REDACTED, BP_GET_FILL, BP_GET_IV2, DVA_IS_VALID, DVA_GET_VDEV, + DVA_GET_OFFSET, DVA_GET_ASIZE, BPE_GET_ETYPE) + + +class Blkptr(sdb.PrettyPrinter): + """ + DESCRIPTION + + Pretty-print zfs block pointers. + + EXAMPLES + + sdb> dbuf | head 1 | member db_blkptr | blkptr + DVA[0]=<0:2cefd5e00:20000> [L0 ZFS plain file] fletcher4 uncompressed unencrypted LE + contiguous unique single 20000L/20000P birth=1624L/1624P fill=1 cksum=3feb86d3fa14: + ff98411222361a1:7cd8eb3816d141e1:2d65ae38a67197c7 + + sdb> echo 0xffffa0889343c680 | blkptr + DVA[0]=<0:41e90000:30000> [L0 ZFS plain file] fletcher4 uncompressed unencrypted LE + contiguous unique single 20000L/20000P birth=10L/10P fill=1 cksum=3ffba121eb4d: + ffd4345f8d679e2:efa124922f72ec66:34642a9a05fbafef + """ + + names = ["blkptr"] + input_type = "blkptr_t *" + load_on = [sdb.Module("zfs"), sdb.Library("libzpool")] + + def get_ot_name(self, bp: drgn.Object) -> str: + return str( + sdb.get_object("dmu_ot")[BP_GET_TYPE(bp)].ot_name.string_().decode( + "utf-8")) + + def get_checksum(self, bp: drgn.Object) -> str: + checksum = sdb.get_object("zio_checksum_table")[BP_GET_CHECKSUM( + bp)].ci_name + return str(checksum.string_().decode("utf-8")) + + def get_compress(self, bp: drgn.Object) -> str: + compress = sdb.get_object("zio_compress_table")[BP_GET_COMPRESS( + bp)].ci_name + return str(compress.string_().decode("utf-8")) + + def print_hole(self, bp: drgn.Object) -> None: + print(f"HOLE [L{BP_GET_LEVEL(bp)} {self.get_ot_name(bp)}]", end=' ') + print(f"size={BP_GET_LSIZE(bp):#x}L birth={BP_GET_BIRTH(bp):#x}L") + + def print_embedded(self, bp: drgn.Object) -> None: + print(f"EMBEDDED [L{BP_GET_LEVEL(bp)}", end=' ') + print(f"{self.get_ot_name(bp)}]", end=' ') + print(f"et={BPE_GET_ETYPE(bp)} {BP_GET_COMPRESS(bp)} ", end=' ') + print(f"size={BP_GET_LSIZE(bp):#x}L/{BP_GET_PSIZE(bp):#x}P ", end=' ') + print(f"birth={BP_LOGICAL_BIRTH(bp)}L") + + def print_redacted(self, bp: drgn.Object) -> None: + print(f"REDACTED [L{BP_GET_LEVEL(bp)}", end=' ') + print(f"{self.get_ot_name(bp)}] size={BP_GET_LSIZE(bp):#x}", end=' ') + print(f"birth={BP_LOGICAL_BIRTH(bp):#x}") + + def get_byteorder(self, bp: drgn.Object) -> str: + if BP_GET_BYTEORDER(bp) == 0: + return "BE" + return "LE" + + def get_gang(self, bp: drgn.Object) -> str: + if BP_IS_GANG(bp): + return "gang" + return "contiguous" + + def get_dedup(self, bp: drgn.Object) -> str: + if BP_GET_DEDUP(bp): + return "dedup" + return "unique" + + def get_crypt(self, bp: drgn.Object) -> str: + if BP_IS_ENCRYPTED(bp): + return "encrypted" + if BP_IS_AUTHENTICATED(bp): + return "authenticated" + if BP_HAS_INDIRECT_MAC_CKSUM(bp): + return "indirect-MAC" + return "unencrypted" + + def pretty_print(self, objs: Iterable[drgn.Object]) -> None: + copyname = ['zero', 'single', 'double', 'triple'] + copies = 0 + + for bp in objs: + if bp is None: + print("") + continue + + if BP_IS_HOLE(bp): + self.print_hole(bp) + elif BP_IS_EMBEDDED(bp): + self.print_embedded(bp) + elif BP_IS_REDACTED(bp): + self.print_redacted(bp) + else: + + for d in range(0, BP_GET_NDVAS(bp)): + if DVA_IS_VALID(bp.blk_dva[d]): + copies += 1 + print(f"DVA[{d}]=<{DVA_GET_VDEV(bp.blk_dva[d])}:", end='') + print(f"{DVA_GET_OFFSET(bp.blk_dva[d]):#x}:", end='') + print(f"{DVA_GET_ASIZE(bp.blk_dva[d]):#x}>") + + if BP_IS_ENCRYPTED(bp): + print(f"salt={bp.blk_dva[2].dva_word[0]:#x}", end=' ') + print(f"iv={bp.blk_dva[2].dva_word[1]:#x}", end='') + print(f"{BP_GET_IV2(bp):#x}") + + if BP_IS_GANG(bp) and (DVA_GET_ASIZE(bp.blk_dva[2]) <= + DVA_GET_ASIZE(bp.blk_dva[1]) / 2): + copies -= 1 + + print(f"[L{BP_GET_LEVEL(bp)}", end=' ') + print(f"{self.get_ot_name(bp)}]", end=' ') + print(f"{self.get_checksum(bp)}", end=' ') + print(f"{self.get_compress(bp)}", end=' ') + + print(f"layer={BP_GET_LAYER(bp)}", end=' ') + print(f"{self.get_crypt(bp)}", end=' ') + print(f"{self.get_byteorder(bp)}", end=' ') + print(f"{self.get_gang(bp)} {self.get_dedup(bp)}", end=' ') + print(f"{copyname[copies]}") + + print(f"size={BP_GET_LSIZE(bp):#x}L/{BP_GET_PSIZE(bp):#x}P", + end=' ') + print(f"birth={BP_LOGICAL_BIRTH(bp)}L", end='/') + print(f"{BP_GET_BIRTH(bp)}P", end=' ') + print(f"fill={int(BP_GET_FILL(bp))}") + + print(f"cksum={int(bp.blk_cksum.zc_word[0]):#x}", end='') + print(f":{int(bp.blk_cksum.zc_word[1]):#x}", end='') + print(f":{int(bp.blk_cksum.zc_word[2]):#x}", end='') + print(f":{int(bp.blk_cksum.zc_word[3]):#x}") diff --git a/sdb/commands/zfs/internal/__init__.py b/sdb/commands/zfs/internal/__init__.py index b03d9b1..43070e6 100644 --- a/sdb/commands/zfs/internal/__init__.py +++ b/sdb/commands/zfs/internal/__init__.py @@ -69,6 +69,10 @@ def BF64_GET(x: drgn.Object, low: int, length: int) -> int: return BF64_DECODE(x, low, length) +def BF64_GET_SB(x: int, low: int, length: int, shift: int, bias: int) -> int: + return (BF64_GET(x, low, length) + bias) << shift + + def WEIGHT_IS_SPACEBASED(weight: int) -> bool: return weight == 0 or (BF64_GET(weight, 60, 1) != 0) @@ -81,6 +85,184 @@ def WEIGHT_GET_COUNT(weight: int) -> int: return BF64_GET((weight), 0, 54) +def BPE_GET_ETYPE(bp: drgn.Object) -> int: + return BF64_GET(bp.blk_prop, 40, 8) + + +def BPE_GET_LSIZE(bp: drgn.Object) -> int: + return BF64_GET_SB(bp.blk_prop, 0, 25, 0, 1) + + +def BPE_GET_PSIZE(bp: drgn.Object) -> int: + return BF64_GET_SB(bp.blk_prop, 25, 7, 0, 1) + + +def BP_GET_LSIZE(bp: drgn.Object) -> int: + if BP_IS_EMBEDDED(bp): + if BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_DATA: + return BPE_GET_LSIZE(bp) + return 0 + return BF64_GET_SB(bp.blk_prop, 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1) + + +def BP_GET_PSIZE(bp: drgn.Object) -> int: + if BP_IS_EMBEDDED(bp): + return 0 + return BF64_GET_SB(bp.blk_prop, 16, SPA_PSIZEBITS, SPA_MINBLOCKSHIFT, 1) + + +def BP_GET_COMPRESS(bp: drgn.Object) -> int: + return BF64_GET(bp.blk_prop, 32, SPA_COMPRESSBITS) + + +def BP_IS_EMBEDDED(bp: drgn.Object) -> bool: + return bool(BF64_GET(bp.blk_prop, 39, 1)) + + +def BP_GET_CHECKSUM(bp: drgn.Object) -> int: + if BP_IS_EMBEDDED(bp): + return ZIO_CHECKSUM_OFF + return BF64_GET(bp.blk_prop, 40, 8) + + +def BP_GET_TYPE(bp: drgn.Object) -> int: + return BF64_GET(bp.blk_prop, 48, 8) + + +def BP_GET_LEVEL(bp: drgn.Object) -> int: + return BF64_GET(bp.blk_prop, 56, 5) + + +def BP_USES_CRYPT(bp: drgn.Object) -> bool: + return bool(BF64_GET(bp.blk_prop, 61, 1)) + + +def BP_IS_ENCRYPTED(bp: drgn.Object) -> bool: + return (BP_USES_CRYPT(bp) and BP_GET_LEVEL(bp) <= 0 and + DMU_OT_IS_ENCRYPTED(BP_GET_TYPE(bp))) + + +def BP_IS_AUTHENTICATED(bp: drgn.Object) -> bool: + return (BP_USES_CRYPT(bp) and BP_GET_LEVEL(bp) <= 0 and + not DMU_OT_IS_ENCRYPTED(BP_GET_TYPE(bp))) + + +def BP_HAS_INDIRECT_MAC_CKSUM(bp: drgn.Object) -> bool: + return (BP_USES_CRYPT(bp) and BP_GET_LEVEL(bp) > 0) + + +def BP_GET_DEDUP(bp: drgn.Object) -> bool: + return bool(BF64_GET(bp.blk_prop, 62, 1)) + + +def BP_GET_BYTEORDER(bp: drgn.Object) -> int: + return BF64_GET(bp.blk_prop, 63, 1) + + +def BP_GET_LAYER(bp: drgn.Object) -> int: + if sdb.get_type('blkptr_t').has_member('blk_logical_birth'): + return BF64_GET(bp.blk_logical_birth, 56, 8) + return BF64_GET(bp.blk_birth, 56, 8) + + +def BP_LOGICAL_BIRTH(bp: drgn.Object) -> int: + if sdb.get_type('blkptr_t').has_member('blk_logical_birth'): + return BF64_GET(bp.blk_logical_birth, 0, 56) + return BF64_GET(bp.blk_birth, 0, 56) + + +def BP_PHYSICAL_BIRTH(bp: drgn.Object) -> int: + if sdb.get_type('blkptr_t').has_member('blk_physical_birth'): + return BF64_GET(bp.blk_physical_birth, 0, 56) + return BF64_GET(bp.blk_phys_birth, 0, 56) + + +def BP_GET_BIRTH(bp: drgn.Object) -> int: + if BP_IS_EMBEDDED(bp): + return 0 + if BP_PHYSICAL_BIRTH(bp): + return BP_PHYSICAL_BIRTH(bp) + return BP_LOGICAL_BIRTH(bp) + + +def BP_GET_FILL(bp: drgn.Object) -> int: + if BP_IS_ENCRYPTED(bp): + return BF64_GET(bp.blk_fill, 0, 32) + if BP_IS_EMBEDDED(bp): + return 1 + return int(bp.blk_fill) + + +def BP_GET_IV2(bp: drgn.Object) -> int: + return BF64_GET(bp.blk_fill, 32, 32) + + +def BP_IS_GANG(bp: drgn.Object) -> bool: + if BP_IS_EMBEDDED(bp): + return False + return bool(BF64_GET(bp.blk_dva[0].dva_word[1], 63, 1)) + + +def BP_IS_REDACTED(bp: drgn.Object) -> bool: + return (BP_IS_EMBEDDED(bp) and + BPE_GET_ETYPE(bp) == BP_EMBEDDED_TYPE_REDACTED) + + +def BP_IS_HOLE(bp: drgn.Object) -> bool: + return (not BP_IS_EMBEDDED(bp) and DVA_IS_EMPTY(bp.blk_dva[0])) + + +def BP_GET_NDVAS(bp: drgn.Object) -> int: + if BP_IS_EMBEDDED(bp): + return 0 + ndvas = 0 + for d in range(0, 3): + ndvas += DVA_GET_ASIZE(bp.blk_dva[d]) != 0 + return ndvas + + +def DVA_GET_ASIZE(dva: drgn.Object) -> int: + return BF64_GET_SB(dva.dva_word[0], 0, SPA_ASIZEBITS, SPA_MINBLOCKSHIFT, 0) + + +def DVA_GET_VDEV(dva: drgn.Object) -> int: + return BF64_GET(dva.dva_word[0], 32, SPA_VDEVBITS) + + +def DVA_GET_OFFSET(dva: drgn.Object) -> int: + return BF64_GET_SB(dva.dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0) + + +def DVA_IS_VALID(dva: drgn.Object) -> bool: + return DVA_GET_ASIZE(dva) != 0 + + +def DVA_IS_EMPTY(dva: drgn.Object) -> bool: + return bool(dva.dva_word[0] == 0 and dva.dva_word[1] == 0) + + +def DMU_OT_IS_ENCRYPTED(ot: int) -> bool: + if ot & DMU_OT_NEWTYPE: + return bool(ot & DMU_OT_ENCRYPTED) + return bool(sdb.get_object("dmu_ot")[ot].ot_encrypt) + + +SPA_LSIZEBITS = 16 +SPA_PSIZEBITS = 16 +SPA_ASIZEBITS = 24 +SPA_COMPRESSBITS = 7 +SPA_VDEVBITS = 24 +SPA_MINBLOCKSHIFT = 9 + +ZIO_CHECKSUM_OFF = 2 + +DMU_OT_ENCRYPTED = 0x20 +DMU_OT_NEWTYPE = 0x80 + +BP_EMBEDDED_TYPE_DATA = 0 +BP_EMBEDDED_TYPE_RESERVED = 1 +BP_EMBEDDED_TYPE_REDACTED = 2 + METASLAB_WEIGHT_PRIMARY = int(1 << 63) METASLAB_WEIGHT_SECONDARY = int(1 << 62) METASLAB_WEIGHT_CLAIM = int(1 << 61) diff --git "a/tests/integration/data/regression_output/dump.201912060006/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | head 6056 | tail 1| cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" "b/tests/integration/data/regression_output/dump.201912060006/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | head 6056 | tail 1| cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" new file mode 100644 index 0000000..1bad16c --- /dev/null +++ "b/tests/integration/data/regression_output/dump.201912060006/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | head 6056 | tail 1| cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" @@ -0,0 +1,6 @@ +DVA[0]=<0:0x42083400:0x800> +DVA[1]=<0:0x20048000:0x800> +DVA[2]=<0:0x50002c00:0x800> +[L0 SPA space map] fletcher4 lz4 layer=0 unencrypted LE contiguous unique triple +size=0x20000L/0x400P birth=10L/10P fill=1 +cksum=0x8c1caab0a6:0x45de629e8318:0x13bfbe391d06f8:0x41fc70c3e1d38f2 diff --git "a/tests/integration/data/regression_output/dump.201912060006/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | tail 8 | head 1 | cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" "b/tests/integration/data/regression_output/dump.201912060006/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | tail 8 | head 1 | cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" new file mode 100644 index 0000000..24e4eb2 --- /dev/null +++ "b/tests/integration/data/regression_output/dump.201912060006/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | tail 8 | head 1 | cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" @@ -0,0 +1 @@ +HOLE [L0 unallocated] size=0x200L birth=0x0L diff --git a/tests/integration/data/regression_output/dump.201912060006/zfs/dbuf | head 1 | member db_blkptr | blkptr b/tests/integration/data/regression_output/dump.201912060006/zfs/dbuf | head 1 | member db_blkptr | blkptr new file mode 100644 index 0000000..b3010d7 --- /dev/null +++ b/tests/integration/data/regression_output/dump.201912060006/zfs/dbuf | head 1 | member db_blkptr | blkptr @@ -0,0 +1,4 @@ +DVA[0]=<0:0x2cefd5e00:0x20000> +[L0 ZFS plain file] fletcher4 uncompressed layer=0 unencrypted LE contiguous unique single +size=0x20000L/0x20000P birth=1624L/1624P fill=1 +cksum=0x3feb86d3fa14:0xff98411222361a1:0x7cd8eb3816d141e1:0x2d65ae38a67197c7 diff --git a/tests/integration/data/regression_output/dump.201912060006/zfs/spa | head 1 | deref |member spa_uberblock | member ub_rootbp | blkptr b/tests/integration/data/regression_output/dump.201912060006/zfs/spa | head 1 | deref |member spa_uberblock | member ub_rootbp | blkptr new file mode 100644 index 0000000..dc5648c --- /dev/null +++ b/tests/integration/data/regression_output/dump.201912060006/zfs/spa | head 1 | deref |member spa_uberblock | member ub_rootbp | blkptr @@ -0,0 +1,6 @@ +DVA[0]=<0:0x80001e00:0x200> +DVA[1]=<0:0xa0001e00:0x200> +DVA[2]=<0:0x10000da00:0x200> +[L0 DMU objset] fletcher4 lz4 layer=0 unencrypted LE contiguous unique triple +size=0x1000L/0x200P birth=609L/609P fill=67 +cksum=0x98a43f544:0x3eab35f140c:0xd164e4328324:0x1da8f37ef09087 diff --git "a/tests/integration/data/regression_output/dump.202303131823/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | head 6056 | tail 1| cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" "b/tests/integration/data/regression_output/dump.202303131823/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | head 6056 | tail 1| cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" new file mode 100644 index 0000000..ce15dc7 --- /dev/null +++ "b/tests/integration/data/regression_output/dump.202303131823/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | head 6056 | tail 1| cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" @@ -0,0 +1,4 @@ +DVA[0]=<0:0x50ad98800:0x600> +[L0 ZFS plain file] fletcher4 lzjb layer=0 unencrypted LE contiguous unique single +size=0xa00L/0x600P birth=691L/691P fill=1 +cksum=0x50b2435bac:0x4877d83d80e7:0x259e03cbed157d:0xe4d625e1f14d8cc diff --git "a/tests/integration/data/regression_output/dump.202303131823/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | tail 8 | head 1 | cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" "b/tests/integration/data/regression_output/dump.202303131823/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | tail 8 | head 1 | cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" new file mode 100644 index 0000000..9083aad --- /dev/null +++ "b/tests/integration/data/regression_output/dump.202303131823/linux/slabs | filter 'obj.name == \"dnode_t\"' |walk | tail 8 | head 1 | cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr" @@ -0,0 +1,4 @@ +DVA[0]=<0:0xe01bd200:0x2e00> +[L0 ZFS plain file] fletcher4 lzjb layer=0 unencrypted LE contiguous unique single +size=0x8e00L/0x2e00P birth=25L/25P fill=1 +cksum=0x2b4705c4d19:0xe6eacc837fede:0x3376b31cb9e47ade:0x6759b6b5446e1229 diff --git a/tests/integration/data/regression_output/dump.202303131823/zfs/dbuf | head 1 | member db_blkptr | blkptr b/tests/integration/data/regression_output/dump.202303131823/zfs/dbuf | head 1 | member db_blkptr | blkptr new file mode 100644 index 0000000..69863e7 --- /dev/null +++ b/tests/integration/data/regression_output/dump.202303131823/zfs/dbuf | head 1 | member db_blkptr | blkptr @@ -0,0 +1,4 @@ +DVA[0]=<0:0x103207c00:0x2e00> +[L0 ZFS plain file] fletcher4 lz4 layer=0 unencrypted LE contiguous unique single +size=0x20000L/0x2e00P birth=1197L/1197P fill=1 +cksum=0x5df05f0e3e3:0x229afb5d03e237:0x83ffb2e325a9e23a:0xbed1657fea4bbdb8 diff --git a/tests/integration/data/regression_output/dump.202303131823/zfs/spa | head 1 | deref |member spa_uberblock | member ub_rootbp | blkptr b/tests/integration/data/regression_output/dump.202303131823/zfs/spa | head 1 | deref |member spa_uberblock | member ub_rootbp | blkptr new file mode 100644 index 0000000..16f8932 --- /dev/null +++ b/tests/integration/data/regression_output/dump.202303131823/zfs/spa | head 1 | deref |member spa_uberblock | member ub_rootbp | blkptr @@ -0,0 +1,4 @@ +DVA[0]=<0:0x74fca00:0x200> +[L0 DMU objset] fletcher4 lz4 layer=0 unencrypted LE contiguous unique single +size=0x1000L/0x200P birth=249L/249P fill=50 +cksum=0x96a85512f:0x3e46df820da:0xd0f5886a63c8:0x1da5a7cdcc4e69 diff --git a/tests/integration/test_linux_generic.py b/tests/integration/test_linux_generic.py index faa2f2b..98fdb62 100644 --- a/tests/integration/test_linux_generic.py +++ b/tests/integration/test_linux_generic.py @@ -80,6 +80,8 @@ "slabs | pp", "slabs -s util | slabs", "slabs | head 2 | slabs", + 'slabs | filter \'obj.name == "dnode_t"\' |walk | tail 8 | head 1 | cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr', + 'slabs | filter \'obj.name == "dnode_t"\' |walk | head 6056 | tail 1| cast dnode_t * | deref |member dn_phys |member dn_blkptr[0] |blkptr', # slub 'slabs | filter \'obj.name == "zio_cache"\' | slub_cache', diff --git a/tests/integration/test_zfs_generic.py b/tests/integration/test_zfs_generic.py index 5ab0bfb..b5be0dc 100644 --- a/tests/integration/test_zfs_generic.py +++ b/tests/integration/test_zfs_generic.py @@ -29,6 +29,10 @@ # arc "arc", + # blkptr + "spa | head 1 | deref |member spa_uberblock | member ub_rootbp | blkptr", + "dbuf | head 1 | member db_blkptr | blkptr", + # dbuf "dbuf", "dbuf -l 1",