1// KernelDebug.cpp
2
3#include "KernelDebug.h"
4
5#include <KernelExport.h>
6
7#include "Debug.h"
8#include "FileSystem.h"
9#include "FileSystemInitializer.h"
10#include "RequestPort.h"
11#include "RequestPortPool.h"
12#include "UserlandFS.h"
13#include "Volume.h"
14
15static int32 sCommandsAdded = 0;
16
17// DebugUFS
18int
19KernelDebug::DebugUFS(int argc, char** argv)
20{
21	typedef HashMap<String, FileSystemInitializer*> KDebugFSMap;
22	UserlandFS* userlandFS = UserlandFS::GetUserlandFS();
23	KDebugFSMap& fileSystems = userlandFS->fFileSystems->GetUnsynchronizedMap();
24
25	for (KDebugFSMap::Iterator it = fileSystems.GetIterator();
26			it.HasNext();) {
27		KDebugFSMap::Entry entry = it.Next();
28		FileSystemInitializer* fsInitializer = entry.value;
29		FileSystem* fs = fsInitializer->GetFileSystem();
30		kprintf("file system %p: %s\n", fs, (fs ? fs->GetName() : NULL));
31		if (fs) {
32			kprintf("  port pool %p\n", fs->GetPortPool());
33			int32 volumeCount = fs->fVolumes.Count();
34			for (int32 i = 0; i < volumeCount; i++) {
35				Volume* volume = fs->fVolumes.ElementAt(i);
36				kprintf("  volume %p: %" B_PRId32 "\n", volume,
37					volume->GetID());
38			}
39		}
40	}
41	return 0;
42}
43
44// DebugPortPool
45int
46KernelDebug::DebugPortPool(int argc, char** argv)
47{
48	if (argc < 2) {
49		kprintf("usage: ufs_portpool <port pool pointer>\n");
50		return 0;
51	}
52	RequestPortPool *portPool = (RequestPortPool*)parse_expression(argv[1]);
53	kprintf("free ports:\n");
54	for (int32 i = 0; i < portPool->fFreePorts; i++) {
55		kprintf("  port %p\n", portPool->fPorts[i].port);
56	}
57	kprintf("used ports:\n");
58	for (int32 i = portPool->fFreePorts; i < portPool->fPortCount; i++) {
59		kprintf("  port %p, owner: %" B_PRId32 ", count: %" B_PRId32 "\n",
60			portPool->fPorts[i].port, portPool->fPorts[i].owner,
61			portPool->fPorts[i].count);
62	}
63	return 0;
64}
65
66// DebugPort
67int
68KernelDebug::DebugPort(int argc, char** argv)
69{
70	if (argc < 2) {
71		kprintf("usage: ufs_port <port pointer>\n");
72		return 0;
73	}
74	RequestPort *port = (RequestPort*)parse_expression(argv[1]);
75	kprintf("port %p:\n", port);
76	kprintf("  status      : %" B_PRIx32 "\n", port->fPort.fInitStatus);
77	kprintf("  is owner    : %d\n", port->fPort.fOwner);
78	kprintf("  owner port:   %" B_PRId32 "\n", port->fPort.fInfo.owner_port);
79	kprintf("  client port:  %" B_PRId32 "\n", port->fPort.fInfo.client_port);
80	kprintf("  size:         %" B_PRId32 "\n", port->fPort.fInfo.size);
81	kprintf("  capacity:     %" B_PRId32 "\n", port->fPort.fCapacity);
82	kprintf("  buffer:       %p\n", port->fPort.fBuffer);
83	return 0;
84}
85
86// #pragma mark -
87
88// AddDebuggerCommands
89void
90KernelDebug::AddDebuggerCommands()
91{
92	if (atomic_add(&sCommandsAdded, 1) > 0)
93		return;
94	PRINT(("KernelDebug::AddDebuggerCommands(): adding debugger commands\n"));
95	add_debugger_command("ufs", DebugUFS, "prints general info about "
96		"userland FS");
97	add_debugger_command("ufs_portpool", DebugPortPool,
98		"ufs_portpool <port pool pointer> - prints info about a "
99		"userland FS port pool");
100	add_debugger_command("ufs_port", DebugPort,
101		"ufs_port <port pointer> - prints info about a userland FS port");
102}
103
104// RemoveDebuggerCommands
105void
106KernelDebug::RemoveDebuggerCommands()
107{
108	if (atomic_add(&sCommandsAdded, -1) > 1)
109		return;
110	PRINT(("KernelDebug::RemoveDebuggerCommands(): removing debugger "
111		"commands\n"));
112	remove_debugger_command("ufs_port", DebugPort);
113	remove_debugger_command("ufs_portpool", DebugPortPool);
114	remove_debugger_command("ufs", DebugUFS);
115}
116
117