Add some useful debugger commands to the VFS layer for dumping a vnode, an fs_mount, and

the mounts/vnodes list.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13971 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-08-18 15:07:38 +00:00
parent 5913a657df
commit e8e4accd16
+222
View File
@@ -52,6 +52,8 @@
# define FUNCTION(x) ;
#endif
#define ADD_DEBUGGER_COMMANDS
#define MAX_SYM_LINKS SYMLINKS_MAX
const static uint32 kMaxUnusedVnodes = 8192;
@@ -1978,6 +1980,217 @@ get_new_fd(int type, struct fs_mount *mount, struct vnode *vnode,
return fd;
}
#ifdef ADD_DEBUGGER_COMMANDS
static void
_dump_advisory_locking(advisory_locking *locking)
{
if (locking == NULL)
return;
kprintf(" lock: %ld", locking->lock);
kprintf(" wait_sem: %ld", locking->wait_sem);
struct advisory_lock *lock = NULL;
int32 index = 0;
while ((lock = (advisory_lock *)list_get_next_item(&locking->locks, lock)) != NULL) {
kprintf(" [%2ld] team: %ld\n", index, lock->team);
kprintf(" offset: %Ld\n", lock->offset);
kprintf(" length: %Ld\n", lock->length);
kprintf(" shared? %s\n", lock->shared ? "yes" : "no");
}
}
static void
_dump_mount(struct fs_mount *mount)
{
kprintf("MOUNT: %p\n", mount);
kprintf(" id: %ld\n", mount->id);
kprintf(" device_name: %s\n", mount->device_name);
kprintf(" fs_name: %s\n", mount->fs_name);
kprintf(" cookie: %p\n", mount->cookie);
kprintf(" root_vnode: %p\n", mount->root_vnode);
kprintf(" covers_vnode: %p\n", mount->covers_vnode);
kprintf(" partition: %p\n", mount->partition);
kprintf(" lock: %ld\n", mount->rlock.sem);
kprintf(" flags: %s%s\n", mount->unmounting ? " unmounting" : "",
mount->owns_file_device ? " owns_file_device" : "");
}
static void
_dump_vnode(struct vnode *vnode)
{
kprintf("VNODE: %p\n", vnode);
kprintf(" device: %ld\n", vnode->device);
kprintf(" id: %Ld\n", vnode->id);
kprintf(" ref_count: %ld\n", vnode->ref_count);
kprintf(" private_node: %p\n", vnode->private_node);
kprintf(" mount: %p\n", vnode->mount);
kprintf(" covered_by: %p\n", vnode->covered_by);
kprintf(" cache_ref: %p\n", vnode->cache);
kprintf(" flags: %s%s%s\n", vnode->remove ? "r" : "-",
vnode->busy ? "b" : "-", vnode->unpublished ? "u" : "-");
kprintf(" advisory_lock: %p\n", vnode->advisory_locking);
_dump_advisory_locking(vnode->advisory_locking);
}
static int
dump_mount(int argc, char **argv)
{
if (argc != 2) {
kprintf("usage: mount [id/address]\n");
return 0;
}
struct fs_mount *mount = NULL;
// if the argument looks like a hex number, treat it as such
if (strlen(argv[1]) > 2 && argv[1][0] == '0' && argv[1][1] == 'x') {
mount = (fs_mount *)strtoul(argv[1], NULL, 16);
if (IS_USER_ADDRESS(mount)) {
kprintf("invalid fs_mount address\n");
return 0;
}
} else {
mount_id id = atoll(argv[1]);
mount = (fs_mount *)hash_lookup(sMountsTable, (void *)&id);
if (mount == NULL) {
kprintf("fs_mount not found\n");
return 0;
}
}
_dump_mount(mount);
return 0;
}
static int
dump_mounts(int argc, char **argv)
{
struct hash_iterator iterator;
struct fs_mount *mount;
kprintf("address id root covers fs_name\n");
hash_open(sMountsTable, &iterator);
while ((mount = (struct fs_mount *)hash_next(sMountsTable, &iterator)) != NULL) {
kprintf("%p%4ld %p %p %s\n", mount, mount->id, mount->root_vnode,
mount->covers_vnode, mount->fs_name);
}
hash_close(sMountsTable, &iterator, false);
return 0;
}
static int
dump_vnode(int argc, char **argv)
{
if (argc < 2) {
kprintf("usage: vnode [id/device id/address]\n");
return 0;
}
struct vnode *vnode = NULL;
// if the argument looks like a hex number, treat it as such
if (strlen(argv[1]) > 2 && argv[1][0] == '0' && argv[1][1] == 'x') {
vnode = (struct vnode *)strtoul(argv[1], NULL, 16);
if (IS_USER_ADDRESS(vnode)) {
kprintf("invalid vnode address\n");
return 0;
}
_dump_vnode(vnode);
return 0;
}
struct hash_iterator iterator;
mount_id device = -1;
vnode_id id;
if (argc > 2) {
device = atoi(argv[1]);
id = atoll(argv[2]);
} else
id = atoll(argv[1]);
hash_open(sVnodeTable, &iterator);
while ((vnode = (struct vnode *)hash_next(sVnodeTable, &iterator)) != NULL) {
if (vnode->id != id || device != -1 && vnode->device != device)
continue;
_dump_vnode(vnode);
}
hash_close(sVnodeTable, &iterator, false);
return 0;
}
static int
dump_vnodes(int argc, char **argv)
{
// restrict dumped nodes to a certain device if requested
mount_id device = -1;
if (argc > 1)
device = atoi(argv[1]);
struct hash_iterator iterator;
struct vnode *vnode;
kprintf("address dev inode ref cache locking flags\n");
hash_open(sVnodeTable, &iterator);
while ((vnode = (struct vnode *)hash_next(sVnodeTable, &iterator)) != NULL) {
if (device != -1 && vnode->device != device)
continue;
kprintf("%p%4ld%10Ld%5ld %p %p %s%s%s\n", vnode, vnode->device, vnode->id,
vnode->ref_count, vnode->cache, vnode->advisory_locking,
vnode->remove ? "r" : "-", vnode->busy ? "b" : "-",
vnode->unpublished ? "u" : "-");
}
hash_close(sVnodeTable, &iterator, false);
return 0;
}
static int
dump_vnode_caches(int argc, char **argv)
{
struct hash_iterator iterator;
struct vnode *vnode;
kprintf("address dev inode cache size pages\n");
hash_open(sVnodeTable, &iterator);
while ((vnode = (struct vnode *)hash_next(sVnodeTable, &iterator)) != NULL) {
if (vnode->cache == NULL)
continue;
// count pages in cache
size_t numPages = 0;
for (struct vm_page *page = vnode->cache->cache->page_list;
page != NULL; page = page->cache_next) {
numPages++;
}
kprintf("%p%4ld%10Ld %p %8Ld%8ld\n", vnode, vnode->device, vnode->id, vnode->cache,
(vnode->cache->cache->virtual_size + B_PAGE_SIZE - 1) / B_PAGE_SIZE, numPages);
}
hash_close(sVnodeTable, &iterator, false);
return 0;
}
#endif // ADD_DEBUGGER_COMMANDS
// #pragma mark -
// Public VFS API
@@ -2931,6 +3144,15 @@ vfs_init(kernel_args *args)
if (block_cache_init() != B_OK)
return B_ERROR;
#ifdef ADD_DEBUGGER_COMMANDS
// add some debugger commands
add_debugger_command("vnode", &dump_vnode, "info about the specified vnode");
add_debugger_command("vnodes", &dump_vnodes, "list all vnodes (from the specified device)");
add_debugger_command("vnode_caches", &dump_vnode_caches, "list all vnode caches");
add_debugger_command("mount", &dump_mount, "info about the specified fs_mount");
add_debugger_command("mounts", &dump_mounts, "list all fs_mounts");
#endif
return file_cache_init();
}