Example #1
0
    def pretty_print(self, objs: Iterable[drgn.Object]) -> None:

        # RangeTreeSeg is a SingleInputCommand, and it's like a pretty-printer
        # for range_seg*_t's, but since it has no `names`, it can't be invoked
        # from the command line. The reason is that range_seg*_t's specify their
        # ranges relative to rt_start/rt_shift, which are not accessible from
        # the range_seg*_t. Therefore, they can only be pretty-printed as part
        # of a range_tree_t*, from the range_tree pretty-printer.
        class RangeTreeSeg(sdb.SingleInputCommand):
            def __init__(self, rt: drgn.Object):
                super().__init__()
                self.rt = rt

            def _call_one(self, obj: drgn.Object) -> None:
                start = (obj.rs_start << self.rt.rt_shift) + self.rt.rt_start
                end = (obj.rs_end << self.rt.rt_shift) + self.rt.rt_start
                if hasattr(self.rt, 'rs_fill'):
                    fill = obj.rs_fill << self.rt.rt_shift
                    print(f"    [{hex(start)} {hex(end)}) "
                          f"(length {hex(end - start)}) "
                          f"(fill {hex(fill)})")
                else:
                    print(f"    [{hex(start)} {hex(end)}) "
                          f"(length {hex(end - start)})")

        for rt in objs:
            print(f"{hex(rt)}: range tree of {int(rt.rt_root.bt_num_elems)} "
                  f"entries, {int(rt.rt_space)} bytes")
            for _ in sdb.execute_pipeline(
                [rt], [RangeSeg(), RangeTreeSeg(rt)]):
                pass
Example #2
0
File: vdev.py Project: mmaybee/sdb
    def pretty_print(self,
                     vdevs: Iterable[drgn.Object],
                     indent: int = 0) -> None:
        print(
            "".ljust(indent),
            "ADDR".ljust(18),
            "STATE".ljust(7),
            "AUX".ljust(4),
            "DESCRIPTION",
        )
        print("".ljust(indent), "-" * 60)

        for vdev in vdevs:
            level = 0
            pvd = vdev.vdev_parent
            while pvd:
                level += 2
                pvd = pvd.vdev_parent

            if int(vdev.vdev_path) != 0:
                print(
                    "".ljust(indent),
                    hex(vdev).ljust(18),
                    enum_lookup("vdev_state_t", vdev.vdev_state).ljust(7),
                    enum_lookup("vdev_aux_t", vdev.vdev_stat.vs_aux).ljust(4),
                    "".ljust(level),
                    vdev.vdev_path.string_().decode("utf-8"),
                )

            else:
                print(
                    "".ljust(indent),
                    hex(vdev).ljust(18),
                    enum_lookup("vdev_state_t", vdev.vdev_state).ljust(7),
                    enum_lookup("vdev_aux_t", vdev.vdev_stat.vs_aux).ljust(4),
                    "".ljust(level),
                    vdev.vdev_ops.vdev_op_type.string_().decode("utf-8"),
                )
            if self.args.histogram:
                metaslabs = sdb.execute_pipeline([vdev], [Metaslab()])
                histsum, shift = self.sum_histograms(metaslabs)
                if shift > 0:
                    ZFSHistogram.print_histogram(histsum, shift, indent + 5)

            if self.args.metaslab:
                metaslabs = sdb.execute_pipeline([vdev], [Metaslab()])
                Metaslab(self.arg_list).pretty_print(metaslabs, indent + 5)
Example #3
0
    def print_indented(self,
                       vdevs: Iterable[drgn.Object],
                       indent: int = 0) -> None:
        print(
            "".ljust(indent),
            "ADDR".ljust(18),
            "STATE".ljust(7),
            "AUX".ljust(4),
            "DESCRIPTION",
        )
        print("".ljust(indent), "-" * 60)

        prev = None
        for vdev in vdevs:
            level = 0
            pvd = vdev.vdev_parent
            while pvd:
                level += 2
                pvd = pvd.vdev_parent

            if vdev.vdev_isl2cache and prev and not prev.vdev_isl2cache:
                print("".ljust(indent), "-".ljust(18), "-".ljust(7),
                      "-".ljust(4), "".ljust(0), "cache")
            if vdev.vdev_islog and prev and not prev.vdev_islog:
                print("".ljust(indent), "-".ljust(18), "-".ljust(7),
                      "-".ljust(4), "".ljust(0), "logs")
            if vdev.vdev_isspare and prev and not prev.vdev_isspare:
                print("".ljust(indent), "-".ljust(18), "-".ljust(7),
                      "-".ljust(4), "".ljust(0), "spares")
            if vdev.vdev_isl2cache or vdev.vdev_isspare:
                level = 2

            if int(vdev.vdev_path) != 0:
                print(
                    "".ljust(indent),
                    hex(vdev).ljust(18),
                    enum_lookup("vdev_state_t", vdev.vdev_state).ljust(7),
                    enum_lookup("vdev_aux_t", vdev.vdev_stat.vs_aux).ljust(4),
                    "".ljust(level),
                    vdev.vdev_path.string_().decode("utf-8"),
                )

            else:
                print(
                    "".ljust(indent),
                    hex(vdev).ljust(18),
                    enum_lookup("vdev_state_t", vdev.vdev_state).ljust(7),
                    enum_lookup("vdev_aux_t", vdev.vdev_stat.vs_aux).ljust(4),
                    "".ljust(level),
                    vdev.vdev_ops.vdev_op_type.string_().decode("utf-8"),
                )
            if self.args.histogram:
                if not sdb.is_null(vdev.vdev_mg):
                    ZFSHistogram.print_histogram(vdev.vdev_mg.mg_histogram, 0,
                                                 indent + 5)
            prev = vdev
            if self.args.metaslab:
                metaslabs = sdb.execute_pipeline([vdev], [Metaslab()])
                Metaslab(self.arg_list).print_indented(metaslabs, indent + 5)
Example #4
0
 def pretty_print(self, spas):
     print("{:18} {}".format("ADDR", "NAME"))
     print("%s" % ("-" * 60))
     for spa in spas:
         print("{:18} {}".format(hex(spa),
                                 spa.spa_name.string_().decode("utf-8")))
         if self.args.vdevs:
             vdevs = sdb.execute_pipeline([spa], [Vdev()])
             Vdev(self.arg_string).pretty_print(vdevs, 5)
Example #5
0
 def no_input(self):
     spas = sdb.execute_pipeline(
         [sdb.get_object("spa_namespace_avl").address_of_()],
         [Avl(), sdb.Cast("spa_t *")],
     )
     for spa in spas:
         if (self.args.poolnames and spa.spa_name.string_().decode("utf-8")
                 not in self.args.poolnames):
             continue
         yield spa
Example #6
0
    def no_input(self) -> Iterable[drgn.Object]:
        proc_list = self.prog["zfs_dbgmsgs"].pl_list
        list_addr = proc_list.address_of_()

        # pylint: disable=C0330
        for obj in sdb.execute_pipeline(
                self.prog, [list_addr],
            [SPLList(self.prog),
             Cast(self.prog, "zfs_dbgmsg_t *")]):
            yield obj
Example #7
0
    def massage_input_and_call(self, objs: Iterable[drgn.Object]
                              ) -> Iterable[drgn.Object]:
        """
        Commands can declare that they accept input of type "foo_t*" by
        setting their input_type. They can be passed input of type "void *"
        or "foo_t" and this method will automatically convert the input
        objects to the expected type (foo_t*).
        """

        # If this Command doesn't expect any particular type, just call().
        if self.input_type is None:
            yield from self._call_and_yield(objs)
            return

        # If this Command doesn't expect a pointer, just call().
        expected_type = sdb.prog.type(self.input_type)
        if expected_type.kind is not drgn.TypeKind.POINTER:
            yield from self._call_and_yield(objs)
            return

        first_obj_type, objs = sdb.get_first_type(objs)
        if first_obj_type is not None:
            # If we are passed a void*, cast it to the expected type.
            if (first_obj_type.kind is drgn.TypeKind.POINTER and
                    first_obj_type.type.primitive is drgn.PrimitiveType.C_VOID):
                # pylint: disable=import-outside-toplevel
                #
                # The reason we have to import here is that putting the the
                # import at the top-level hits a cyclic import error which
                # breaks everything. We may need to redesign how we do imports.
                from sdb.commands.cast import Cast
                yield from sdb.execute_pipeline(objs,
                                                [Cast(self.input_type), self])
                return

            # If we are passed a foo_t when we expect a foo_t*, use its address.
            if sdb.prog.pointer_type(first_obj_type) == expected_type:
                # pylint: disable=import-outside-toplevel
                from sdb.commands.address import Address
                yield from sdb.execute_pipeline(objs, [Address(), self])
                return

        yield from self._call_and_yield(objs)
Example #8
0
 def from_range_tree(self, rt: drgn.Object) -> Iterable[drgn.Object]:
     enum_dict = dict(sdb.get_type('enum range_seg_type').enumerators)
     range_seg_type_to_type = {
         enum_dict['RANGE_SEG32']: 'range_seg32_t*',
         enum_dict['RANGE_SEG64']: 'range_seg64_t*',
         enum_dict['RANGE_SEG_GAP']: 'range_seg_gap_t*',
     }
     seg_type_name = range_seg_type_to_type[int(rt.rt_type)]
     yield from sdb.execute_pipeline([rt.rt_root.address_of_()],
                                     [Btree(), Cast(seg_type_name)])
Example #9
0
 def no_input(self):
     spas = sdb.execute_pipeline(
         self.prog,
         [self.prog["spa_namespace_avl"].address_of_()],
         [Avl(self.prog), Cast(self.prog, "spa_t *")],
     )
     for spa in spas:
         if (self.args.poolnames and spa.spa_name.string_().decode("utf-8")
                 not in self.args.poolnames):
             continue
         yield spa
Example #10
0
    def pretty_print(self, spas: Iterable[drgn.Object]) -> None:
        print("{:18} {}".format("ADDR", "NAME"))
        print("%s" % ("-" * 60))
        for spa in spas:
            print("{:18} {}".format(hex(spa),
                                    spa.spa_name.string_().decode("utf-8")))
            if self.args.histogram:
                ZFSHistogram.print_histogram(spa.spa_normal_class.mc_histogram,
                                             0, 5)

            if self.args.vdevs or self.args.metaslab:
                vdevs = sdb.execute_pipeline([spa], [Vdev()])
                Vdev(self.arg_list).pretty_print(vdevs, 5)
Example #11
0
    def pretty_print(self, vdevs, indent=0):
        print(
            "".ljust(indent),
            "ADDR".ljust(18),
            "STATE".ljust(7),
            "AUX".ljust(4),
            "DESCRIPTION",
        )
        print("".ljust(indent), "-" * 60)

        for vdev in vdevs:
            level = 0
            pvd = vdev.vdev_parent
            while pvd:
                level += 2
                pvd = pvd.vdev_parent

            if int(vdev.vdev_path) != 0:
                print(
                    "".ljust(indent),
                    hex(vdev).ljust(18),
                    enum_lookup(self.prog, "vdev_state_t",
                                vdev.vdev_state).ljust(7),
                    enum_lookup(self.prog, "vdev_aux_t",
                                vdev.vdev_stat.vs_aux).ljust(4),
                    "".ljust(level),
                    vdev.vdev_path.string_().decode("utf-8"),
                )

            else:
                print(
                    "".ljust(indent),
                    hex(vdev).ljust(18),
                    enum_lookup(self.prog, "vdev_state_t",
                                vdev.vdev_state).ljust(7),
                    enum_lookup(self.prog, "vdev_aux_t",
                                vdev.vdev_stat.vs_aux).ljust(4),
                    "".ljust(level),
                    vdev.vdev_ops.vdev_op_type.string_().decode("utf-8"),
                )
            if self.args.metaslab:
                metaslabs = sdb.execute_pipeline(self.prog, [vdev],
                                                 [Metaslab(self.prog)])
                Metaslab(self.prog,
                         self.arg_string).pretty_print(metaslabs, indent + 5)
Example #12
0
 def all_dnode_dbufs(self, dn: drgn.Object) -> Iterable[drgn.Object]:
     yield from sdb.execute_pipeline(
         [dn.dn_dbufs.address_of_()],
         [sdb.Walk(), sdb.Cast(self.output_type)])
Example #13
0
 def walk(self, obj: drgn.Object) -> Iterable[drgn.Object]:
     for i in range(obj.ml_num_sublists):
         sublist = obj.ml_sublists[i].mls_list.address_of_()
         yield from sdb.execute_pipeline([sublist], [SPLList()])
Example #14
0
    def no_input(self) -> Iterable[drgn.Object]:
        proc_list = sdb.get_object("zfs_dbgmsgs").pl_list
        list_addr = proc_list.address_of_()

        yield from sdb.execute_pipeline(
            [list_addr], [SPLList(), sdb.Cast(["zfs_dbgmsg_t *"])])