Source code for crash.subsystem.filesystem.kernfs
# -*- coding: utf-8 -*-
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
from typing import Iterable
import gdb
from crash.util import get_typed_pointer, AddressSpecifier
from crash.util.symbols import Types
from crash.exceptions import InvalidArgumentError
from crash.types.rbtree import rbtree_postorder_for_each_entry
types = Types('struct kernfs_node')
KERNFS_DIR = 1
KERNFS_FILE = 2
KERNFS_LINK = 4
[docs]
def find_kn(addr: AddressSpecifier) -> gdb.Value:
"""
Finds ``struct kernfs_node`` by given address.
Note: Function does no checking whether address points to ``struct
kernfs_node``. This may change in future.
Args:
addr: representation of memory address
Returns:
:obj:`gdb.Value`: ``struct kernfs_node``
"""
kn = get_typed_pointer(addr, types.kernfs_node_type).dereference()
return kn
[docs]
def for_each_child(kn: gdb.Value) -> Iterable[gdb.Value]:
"""
Iterates over all child nodes of given kernfs_node.
Args:
kn: ``struct kernfs_node`` of directory type
Yields:
gdb.Value: ``struct kernfs_node``
Raises:
:obj:`.InvalidArgumentError`: kernfs_node is not a directory
"""
if int(kn['flags']) & KERNFS_DIR == 0:
raise InvalidArgumentError(f"kernfs_node at {kn.address} is not a directory")
return rbtree_postorder_for_each_entry(kn['dir']['children'], types.kernfs_node_type, 'rb')
[docs]
def path_from_node(kn: gdb.Value) -> str:
"""
Traverses kernfs to root to return node's patch.
Args:
kn: ``struct kernfs_node``
Returns:
str: path from root to kn (inclusive)
"""
path = []
while int(kn['parent']):
path.append(kn['name'].string())
kn = kn['parent'].dereference()
return '/' + '/'.join(path[::-1])