Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
f29e1de
crash.types.task: improve task flag handling
jeffmahoney Apr 29, 2019
86422cb
crash.commands.ps: add support for TASK_IDLE
jeffmahoney Apr 29, 2019
68f6630
crash.commands.help: sort commands in help output
jeffmahoney Sep 19, 2018
4fb4c3a
crash.util: add struct_has_member
jeffmahoney Apr 29, 2019
7fe8aa7
crash.types.task: handle anonymous sub-structure in mm_struct
jeffmahoney Apr 29, 2019
b8de0ab
crash.util: add uuid decoding
jeffmahoney May 1, 2019
e75bc23
crash.util: add decode_flags helper
jeffmahoney Apr 26, 2019
81cb971
crash.types.{,k}list: use the type from the symbol when available
jeffmahoney Sep 19, 2018
736fdf7
crash.types.list: add list_empty
jeffmahoney Apr 26, 2019
df92870
crash.types.list: fix cycle tests
jeffmahoney Apr 22, 2019
87aec81
tests: clear file during test teardown
jeffmahoney Apr 22, 2019
ff7ef81
crash.kernel: convert setup to use DelayedSymvals
jeffmahoney Apr 22, 2019
a132e76
crash.arch: add baseline ppc64 support
jeffmahoney Apr 22, 2019
bbe3d6f
crash.types.bitmap: add find first/last/next helpers
jeffmahoney Apr 22, 2019
527e044
crash: use new gdb.Target to create standalone target
jeffmahoney Apr 22, 2019
afdd5b2
crash.types.module: create module for modules
jeffmahoney May 7, 2019
96be843
kdump.target: don't specify offset for .data..percpu
jeffmahoney May 1, 2019
fa71477
crash.types.percpu: handle missing pcpu_nr_slots
jeffmahoney May 6, 2019
c6ec4bc
crash.types.percpu: get_percpu_var, raise exception with passed val
jeffmahoney May 1, 2019
7502b34
crash.types.cpu: fix online cpu mask and add possible cpu mask
jeffmahoney May 7, 2019
36a58b8
crash.types.percpu: better percpu handling
jeffmahoney Apr 22, 2019
118bbfe
crash.types.percpu: separate the all-cpus and single-cpu cases
jeffmahoney May 21, 2019
7b38ed4
crash.types.percpu: add percpu_counter_sum
jeffmahoney Apr 30, 2019
a515eef
crash: auto-select crashing task and print backtrace on startup
jeffmahoney Apr 22, 2019
f6feb54
crash.sh: use $TMPDIR for gdbinit in --gdb mode
jeffmahoney May 1, 2019
fe1c40e
crash.kernel: use new KernelError exception to report errors during s…
jeffmahoney May 1, 2019
18707a4
crash.kernel: add debug option to load_modules
jeffmahoney May 1, 2019
823e505
crash.kernel: use objfile.has_symbols() to detect debuginfo
jeffmahoney May 1, 2019
58b7c35
crash.util: promote to be its own sub-package
jeffmahoney May 3, 2019
4175429
crash: add static percpu regions for modules
jeffmahoney May 1, 2019
40352e2
crash.kernel: handle failure to add module symbols
jeffmahoney May 1, 2019
9a86bc6
crash.kernel: improve and document debuginfo and module loading
jeffmahoney May 1, 2019
95b3d0d
crash.kernel: check module version on load
jeffmahoney Apr 26, 2019
917c3a9
crash.commands.task: allow 'task' command with no argument to show cu…
jeffmahoney May 2, 2019
a18e2b7
crash.infra.callbacks: explicitly connect to callbacks
jeffmahoney May 17, 2019
e0fa23e
crash.infra.lookup: move type name resolution into TypeCallback
jeffmahoney May 3, 2019
5dee123
crash.util.symbols: introduce simplified delayed lookups
jeffmahoney May 3, 2019
cc56e25
crash.subsystem.filesystem: add super_flags
jeffmahoney Apr 26, 2019
5f69e54
crash.subsystem.filesystem: add for_each_super_block, get_super_block
jeffmahoney Sep 18, 2018
7d72016
crash.subsystem.filesystem.mount: use type from symbol when available
jeffmahoney Sep 19, 2018
b4facc0
crash.subsystem.filesystem.mount: use crash.util.decode_flags
jeffmahoney May 4, 2019
b2817c9
crash.subsystem.filesystem: include sector number when describing dio…
jeffmahoney May 1, 2019
b7085be
crash.subsystem.{filesystem,storage}: refactor bio decoders
jeffmahoney May 3, 2019
c27620b
crash.types.vmstat: remove dead code
jeffmahoney May 6, 2019
fcb22c4
crash: remove CrashBaseClass
jeffmahoney May 3, 2019
30dd42b
crash.util: add more documentation
jeffmahoney May 20, 2019
65a7e06
crash: factor out task iteration
jeffmahoney May 7, 2019
abfd2dc
crash.commands: handle DelayedAttributeError gracefully
jeffmahoney May 8, 2019
62bb502
crash.commands.dmesg: handling dictionary string encoding better
jeffmahoney May 8, 2019
e7ff8dd
crash.types.slab: improve address printing
jeffmahoney May 9, 2019
6da88b1
crash.commands.kmem: use exceptions to exit command with error
jeffmahoney May 9, 2019
29ea504
crash.commands.kmem: fix argument parsing
jeffmahoney May 9, 2019
f2142e5
crash.commands.kmem: clean up some trivial things
jeffmahoney May 9, 2019
08749dd
crash.commands.ps: uncomment -G mode
jeffmahoney May 10, 2019
004ad94
crash: add kernel testing against vmcores
jeffmahoney May 7, 2019
cfac8fb
crash.types.classdev: update classdev iteration to use device_private
jeffmahoney May 7, 2019
39131e1
crash.subsystem.filesystems: add is_fstype_super and is_fstype_inode
jeffmahoney May 9, 2019
bfd2628
crash.subsystem.filesystem: document gdb.NotAvailableError
jeffmahoney May 15, 2019
c5691bf
crash.subsytem.filesystem.mount: add API documentation
jeffmahoney May 9, 2019
4e60c1c
crash.subsystem.filesystem.btrfs: add helpers for super, inode, and u…
jeffmahoney Apr 29, 2019
7e077de
crash.commands.btrfs: add basic btrfs command
jeffmahoney Sep 18, 2018
575d1ef
crash.subsystem.filesystem.xfs: Add basic XFS infra
jeffmahoney Sep 18, 2018
1522012
crash.commands.xfs: add basic xfs command
jeffmahoney Sep 18, 2018
5483d9f
crash.subsystem.storage.blocksq: add per-queue requests_in_flight call
jeffmahoney Apr 22, 2019
538acd1
crash.commands.lsmod: add basic lsmod command
jeffmahoney May 1, 2019
e7789d4
crash.types.task: get_stack_pointer should take thread_struct
jeffmahoney May 15, 2019
1d22d73
crash.types.task: add accessor-helpers
jeffmahoney May 15, 2019
af12734
crash.commands.ps: factor out formatting
jeffmahoney May 15, 2019
550c337
crash.cache.syscache: update config parsing
jeffmahoney May 9, 2019
d04844b
tests: silence as much noise as possible
jeffmahoney May 17, 2019
cb870bb
crash.util: fix get_typed_pointer semantics
jeffmahoney May 20, 2019
0f70ab1
crash.types.task: add documentation and static typing hints
jeffmahoney May 20, 2019
d6bc98b
crash: more documentation and typing
jeffmahoney May 21, 2019
2834470
WIP: Add initial support for "live" debugging
May 9, 2019
14529d1
WIP: Add new "kcore" target using "drgn" backend
sdimitro May 20, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
crash.subsystem.{filesystem,storage}: refactor bio decoders
The current bio decoders are essentially open coded everywhere.  This
commit formalizes the interface to make it easier to extend.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
  • Loading branch information
jeffmahoney committed May 21, 2019
commit b7085be43b7e6183347c02edea8d3f2cdf0e18dd
218 changes: 0 additions & 218 deletions crash/subsystem/filesystem/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,30 +78,6 @@ class FileSystem(CrashBaseClass):
'struct buffer_head *',
'struct super_block' ]
__symvals__ = [ 'super_blocks' ]
__symbol_callbacks__ = [
('dio_bio_end_io', '_register_dio_bio_end'),
('dio_bio_end_aio', '_register_dio_bio_end'),
('mpage_end_io', '_register_mpage_end_io'),
('end_bio_bh_io_sync', '_register_end_bio_bh_io_sync') ]

buffer_head_decoders = {}

@classmethod
def _register_dio_bio(cls, symval):
block.register_bio_decoder(cls.dio_bio_end, cls.decode_dio_bio)

@classmethod
def _register_dio_bio_end(cls, sym):
block.register_bio_decoder(sym, cls.decode_dio_bio)

@classmethod
def _register_mpage_end_io(cls, sym):
block.register_bio_decoder(sym, cls.decode_mpage)

@classmethod
def _register_end_bio_bh_io_sync(cls, sym):
block.register_bio_decoder(sym, cls.decode_bio_buffer_head)

@export
@staticmethod
def super_fstype(sb: gdb.Value) -> str:
Expand Down Expand Up @@ -133,200 +109,6 @@ def super_flags(sb: gdb.Value) -> str:
"""
return decode_flags(sb['s_flags'], SB_FLAGS)

@export
@classmethod
def register_buffer_head_decoder(cls, sym, decoder):
"""
Registers a buffer_head decoder with the filesystem subsystem.

A buffer_head decoder is a method thats acepts a buffer_head,
potentially interprets the private members of the buffer_head,
and returns a dictionary. The only mandatory member of the
dictionary is 'description' which contains a human-readable
description of the purpose of this buffer_head.

If the buffer_head is part of a stack, the 'next' item should contain
the next object in the stack. It does not necessarily need to be
a buffer_head. It does need to have a 'decoder' item declared
that will accept the given object. The decoder does not need to
be registered unless it will be a top-level decoder.

Other items can be added as-needed to allow informed callers
to obtain direct informatiom.

Args:
sym (gdb.Value<void (*)(struct buffer_head *, int)>):
The kernel function used as buffer_head->b_h_end_io callback
"""

cls.buffer_head_decoders[sym] = decoder

@classmethod
def decode_dio_bio(cls, bio):
"""
Decodes a bio used for direct i/o.

This method decodes a bio generated by the direct-io component of
the file system subsystem. The bio can either have been submitted
directly or asynchronously.

Args:
bio(gdb.Value<struct bio>): The struct bio to be decoded, generated
by the direct i/o component

Returns:
dict: Contains the following items:
- description (str): Human-readable description of the bio
- bio (gdb.Value<struct bio>): The struct bio being decoded
- dio (gdb.Value<struct dio>): The direct i/o component of
the bio
- fstype (str): The name of the file system which submitted
this bio
- inode (gdb.Value<struct inode>): The struct inode, if any,
that owns the file associated with this bio
- offset (int): The offset within the file, in bytes
- devname (str): The device name associated with this bio
"""
dio = bio['bi_private'].cast(cls.dio_p_type)
fstype = cls.super_fstype(dio['inode']['i_sb'])
dev = block_device_name(dio['inode']['i_sb']['s_bdev'])
offset = dio['block_in_file'] << dio['blkbits']

chain = {
'description' : "{:x} bio: Direct I/O for {} inode {}, sector {} on {}".format(
int(bio), fstype, dio['inode']['i_ino'],
bio['bi_sector'], dev),
'bio' : bio,
'dio' : dio,
'fstype' : fstype,
'inode' : dio['inode'],
'offset' : offset,
'devname' : dev,
}
return chain

@classmethod
def decode_mpage(cls, bio):
"""
Decodes a bio used for multipage i/o.

This method decodes a bio generated by the mpage component of
the file system subsystem.

Args:
bio(gdb.Value<struct bio>): The struct bio to be decoded, generated
by the mpage component

Returns:
dict: Contains the following items:
- description (str): Human-readable description of the bio
- bio (gdb.Value<struct bio>): The struct bio being decoded
- fstype (str): The name of the file system which submitted
this bio
- inode (gdb.Value<struct inode>): The struct inode, if any,
that owns the file associated with this bio
"""
inode = bio['bi_io_vec'][0]['bv_page']['mapping']['host']
fstype = cls.super_fstype(inode['i_sb'])
chain = {
'description' :
"{:x} bio: Multipage I/O: inode {}, type {}, dev {}".format(
int(bio), inode['i_ino'], fstype,
block_device_name(bio['bi_bdev'])),
'bio' : bio,
'fstype' : fstype,
'inode' : inode,
}
return chain

@classmethod
def decode_bio_buffer_head(cls, bio):
"""
Decodes a bio used to perform i/o for buffer_heads

This method decodes a bio generated by buffer head submission.

Args:
bio(gdb.Value<struct bio>): The struct bio to be decoded, generated
by buffer head submission

Returns:
dict: Contains the following items:
- description (str): Human-readable description of the bio
- bio (gdb.Value<struct bio>): The struct bio being decoded
- next (gdb.Value<struct buffer_head>): The buffer_head that
initiated this bio.
- decoder (gdb.Value<void (*)(struct buffer_head *, int)>):
A decoder for the buffer head
"""
bh = bio['bi_private'].cast(cls.buffer_head_p_type)
chain = {
'description' :
"{:x} bio: Bio representation of buffer head".format(int(bio)),
'bio' : bio,
'next' : bh,
'decoder' : cls.decode_buffer_head,
}

return chain

@classmethod
def decode_buffer_head(cls, bh):
"""
Decodes a struct buffer_head

This method decodes a struct buffer_head, using an
implementation-specific decoder, if available

Args:
bio(gdb.Value<struct buffer_head>): The struct buffer_head to be
decoded.

Returns:
dict: Minimally contains the following items.
- description (str): Human-readable description of the bio
- bh (gdb.Value<struct buffer_head>): The struct buffer_head
Additional items may be available based on the
implmentation-specific decoder.
"""
endio = bh['b_end_io']
try:
return cls.buffer_head_decoders[endio](bh)
except KeyError:
pass
desc = "{:x} buffer_head: for dev {}, block {}, size {} (undecoded)".format(
int(bh), block_device_name(bh['b_bdev']),
bh['b_blocknr'], bh['b_size'])
chain = {
'description' : desc,
'bh' : bh,
}
return chain

@classmethod
def decode_end_buffer_write_sync(cls, bh):
"""
Decodes a struct buffer_head submitted by file systems for routine
synchronous writeback.

Args:
bio(gdb.Value<struct buffer_head>): The struct buffer_head to be
decoded.

Returns:
dict: Minimally contains the following items.
- description (str): Human-readable description of the bio
- bh (gdb.Value<struct buffer_head>): The struct buffer_head
"""
desc = ("{:x} buffer_head: for dev {}, block {}, size {} (unassociated)"
.format(block_device_name(bh['b_bdev']),
bh['b_blocknr'], bh['b_size']))
chain = {
'description' : desc,
'bh' : bh,
}
return chain

@export
@classmethod
def for_each_super_block(cls) -> Iterable[gdb.Value]:
Expand Down
138 changes: 138 additions & 0 deletions crash/subsystem/filesystem/decoders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# -*- coding: utf-8 -*-
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

import gdb
from crash.util.symbols import Types
from crash.subsystem.storage import block_device_name
from crash.subsystem.storage.decoders import Decoder, decode_bh
from crash.subsystem.filesystem import super_fstype

class DIOBioDecoder(Decoder):
"""
Decodes a bio used for direct i/o.

This method decodes a bio generated by the direct-io component of
the file system subsystem. The bio can either have been submitted
directly or asynchronously.

Args:
bio(gdb.Value<struct bio>): The struct bio to be decoded, generated
by the direct i/o component
"""

types = Types([ 'struct dio *' ])
__endio__ = [ 'dio_bio_end_io', 'dio_bio_end_io' ]
description = "{:x} bio: Direct I/O for {} inode {}, sector {} on {}"

def __init__(self, bio):
super().__init__()
self.bio = bio

def interpret(self):
self.dio = self.bio['bi_private'].cast(self.types.dio_p_type)
self.fstype = super_fstype(self.dio['inode']['i_sb'])
self.dev = block_device_name(self.dio['inode']['i_sb']['s_bdev'])
self.offset = self.dio['block_in_file'] << self.dio['blkbits']

def __str__(self):
return self.description.format(int(self.bio), self.fstype,
self.dio['inode']['i_ino'],
self.bio['bi_sector'], self.dev)

def __next__(self):
return None

DIOBioDecoder.register()

class DecodeMPage(Decoder):
"""
Decodes a bio used for multipage i/o.

This method decodes a bio generated by the mpage component of
the file system subsystem.

Args:
bio(gdb.Value<struct bio>): The struct bio to be decoded, generated
by the mpage component

Returns:
dict: Contains the following items:
- description (str): Human-readable description of the bio
- bio (gdb.Value<struct bio>): The struct bio being decoded
- fstype (str): The name of the file system which submitted
this bio
- inode (gdb.Value<struct inode>): The struct inode, if any,
that owns the file associated with this bio
"""

__endio__ = 'mpage_end_io'

description = "{:x} bio: Multipage I/O: inode {}, type {}, dev {}"

def __init__(self, bio):
super().__init__()

self.bio = bio

def interpret(self):
self.inode = bio['bi_io_vec'][0]['bv_page']['mapping']['host']
self.fstype = super_fstype(inode['i_sb'])

def __str__(self):
return self.description.format(int(self.bio), self.inode['i_ino'],
self.fstype,
block_device_name(bio['bi_bdev']))

DecodeMPage.register()

class DecodeBioBH(Decoder):
"""
Decodes a bio used to perform i/o for buffer_heads

This method decodes a bio generated by buffer head submission.

Args:
bio(gdb.Value<struct bio>): The struct bio to be decoded, generated
by buffer head submission

"""
types = Types([ 'struct buffer_head *' ])
__endio__ = 'end_bio_bh_io_sync'
description = "{:x} bio: Bio representation of buffer head"

def __init__(self, bio):
super().__init__()
self.bio = bio

def interpret(self):
self.bh = self.bio['bi_private'].cast(self.types.buffer_head_p_type)

def __str__(self):
return self.description.format(int(bio))

def __next__(self):
return decode_bh(self.bh)

DecodeBioBH.register()

class DecodeSyncWBBH(Decoder):
"""
Decodes a struct buffer_head submitted by file systems for routine
synchronous writeback.

Args:
bio(gdb.Value<struct buffer_head>): The struct buffer_head to be
decoded.
"""
__endio__ = 'end_buffer_write_sync'
description = "{:x} buffer_head: for dev {}, block {}, size {} (unassociated)"

def __init__(self, bh):
super().__init__()
self.bh = bh

def __str__(self):
self.description.format(block_device_name(bh['b_bdev']),
self.bh['b_blocknr'], self.bh['b_size'])

DecodeSyncWBBH.register()
Loading