Skip to content

Commit c01fd44

Browse files
committed
Add zfs_refcount command
1 parent d0cb398 commit c01fd44

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

sdb/commands/zfs/zfs_refcount.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#
2+
# Copyright 2020 Datto, Inc.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
# pylint: disable=missing-docstring
18+
19+
from typing import Iterable
20+
import drgn
21+
import sdb
22+
from sdb.commands.spl.spl_list import SPLList
23+
24+
25+
class Zfs_Refcount(sdb.PrettyPrinter):
26+
names = ["zfs_refcount"]
27+
input_type = "zfs_refcount_t *"
28+
output_type = "zfs_refcount_t *"
29+
30+
@staticmethod
31+
def print_ref(obj: drgn.Object) -> None:
32+
ptr = int(obj.ref_holder)
33+
c = sdb.create_object("char *", ptr)
34+
try:
35+
s = c.string_().decode("utf-8")
36+
except UnicodeDecodeError:
37+
s = ""
38+
print(f"{hex(ptr)} {s} ")
39+
40+
def pretty_print(self, objs: Iterable[drgn.Object]) -> None:
41+
for zr in objs:
42+
# handle the lack of rc_tracked in non-debug zfs build
43+
tracked = 0
44+
try:
45+
tracked = zr.rc_tracked
46+
except AttributeError:
47+
pass
48+
print(f"zfs_recount_t at {hex(zr)} has {int(zr.rc_count)} "
49+
f"current holds tracked={int(tracked)}")
50+
if tracked:
51+
ref_list = zr.rc_list
52+
list_addr = ref_list.address_of_()
53+
refs = sdb.execute_pipeline(
54+
[list_addr],
55+
[SPLList(), sdb.Cast(["reference_t *"])],
56+
)
57+
58+
for ref in refs:
59+
Zfs_Refcount.print_ref(ref)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
zfs_recount_t at 0xffffa0894e7223c8 has 12 current holds tracked=0
2+
zfs_recount_t at 0xffffa089413ba3c8 has 15 current holds tracked=0
3+
zfs_recount_t at 0xffffa08955c463c8 has 39 current holds tracked=0

tests/integration/test_zfs_generic.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@
6161
"spa data | vdev | metaslab | filter 'obj.ms_loaded == 1' | head 1 | member ms_sm.sm_phys.smp_histogram | zhist",
6262
"spa data | vdev | metaslab | filter 'obj.ms_loaded == 1' | head 1 | member ms_sm.sm_phys.smp_histogram | zhist 9",
6363
"spa data | vdev | metaslab | filter 'obj.ms_loaded == 1' | head 1 | member ms_allocatable.rt_histogram | zhist",
64+
65+
# refcount
66+
"spa |member spa_refcount | zfs_refcount",
6467
] # yapf: disable
6568

6669

0 commit comments

Comments
 (0)