-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathtest_subsystem_storage.py
More file actions
311 lines (258 loc) · 12.7 KB
/
test_subsystem_storage.py
File metadata and controls
311 lines (258 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# -*- coding: utf-8 -*-
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
import unittest
import gdb
import io
import sys
import re
import crash.subsystem.storage as storage
import crash.subsystem.filesystem as fs
import crash.util as util
from crash.types.list import list_for_each_entry
class TestSubsystemFilesystem(unittest.TestCase):
nullptr = 0x0
poisonptr = 0xdead000000000100
def setUp(self):
self.char_p_type = gdb.lookup_type('char').pointer()
self.super_block_type = gdb.lookup_type('struct super_block')
self.inode_type = gdb.lookup_type('struct inode')
self.device_type = gdb.lookup_type('struct device')
self.block_device_type = gdb.lookup_type('struct block_device')
self.gendisk_type = gdb.lookup_type('struct gendisk')
self.hd_struct_type = gdb.lookup_type('struct hd_struct')
def get_blockdev_superblock(self):
return gdb.lookup_symbol('blockdev_superblock', None)[0].value()
def get_block_device(self):
all_bdevs = gdb.lookup_symbol('all_bdevs', None)[0].value()
for bdev in list_for_each_entry(all_bdevs, self.block_device_type,
'bd_list'):
if int(bdev['bd_disk']) != 0 and int(bdev['bd_part']) != 0:
return bdev
return None
def get_gendisk(self):
all_bdevs = gdb.lookup_symbol('all_bdevs', None)[0].value()
for bdev in list_for_each_entry(all_bdevs, self.block_device_type,
'bd_list'):
if int(bdev['bd_disk']) != 0:
return bdev['bd_disk'].dereference()
return None
def get_hd_struct(self):
all_bdevs = gdb.lookup_symbol('all_bdevs', None)[0].value()
for bdev in list_for_each_entry(all_bdevs, self.block_device_type,
'bd_list'):
if int(bdev['bd_part']) != 0:
return bdev['bd_part'].dereference()
return None
def get_filesystem_inode(self):
for sb in fs.for_each_super_block():
if fs.super_fstype(sb) != "bdev":
return sb['s_root']['d_inode'].dereference()
raise RuntimeError("No file system supers?")
def get_block_device_inode(self):
bdev_sb = self.get_blockdev_superblock()
for inode in list_for_each_entry(bdev_sb['s_inodes'], self.inode_type,
'i_sb_list'):
return inode
def get_blockdev_filesystem(self):
for sb in fs.for_each_super_block():
fstype = sb['s_type']['name'].string()
print(f"{int(sb['s_bdev']):#x} name={fstype}")
if int(sb['s_bdev']) != 0:
return sb
raise RuntimeError("No block device supers?")
@unittest.skip
def test_for_each_bio_in_stack(self):
"""This requires a dump that has a bio in flight to test"""
pass
def test_for_each_block_device_unfiltered(self):
disk_type = storage.symvals.disk_type
part_type = storage.symvals.part_type
for bdev in storage.for_each_block_device():
self.assertTrue(type(bdev) is gdb.Value)
self.assertTrue(bdev.type == storage.types.gendisk_type or
bdev.type == storage.types.hd_struct_type)
def test_for_each_block_device_filtered_for_disk(self):
disk_type = storage.symvals.disk_type
for bdev in storage.for_each_block_device(disk_type):
self.assertTrue(type(bdev) is gdb.Value)
self.assertTrue(bdev.type == storage.types.gendisk_type)
def test_for_each_block_device_filtered_nullptr(self):
null_type = util.get_typed_pointer(self.nullptr,
storage.types.device_type_type)
# The pointer is only used for comparison so we won't raise
# an exception but we won't get any results either.
for bdev in storage.for_each_block_device(null_type.dereference()):
self.assertTrue(False)
def test_for_each_block_device_filtered_poisonptr(self):
null_type = util.get_typed_pointer(self.poisonptr,
storage.types.device_type_type)
# The pointer is only used for comparison so we won't raise
# an exception but we won't get any results either.
for bdev in storage.for_each_block_device(null_type.dereference()):
self.assertTrue(False)
def test_for_each_disk(self):
for bdev in storage.for_each_disk():
self.assertTrue(type(bdev) is gdb.Value)
self.assertTrue(bdev.type == storage.types.gendisk_type)
def test_for_each_block_device_filtered_for_partitions(self):
part_type = storage.symvals.part_type
for bdev in storage.for_each_block_device(part_type):
self.assertTrue(type(bdev) is gdb.Value)
self.assertTrue(bdev.type == storage.types.hd_struct_type)
def test_block_device_name(self):
bdev = self.get_block_device()
self.assertTrue(type(bdev) is gdb.Value)
self.assertTrue(bdev.type == self.block_device_type)
name = storage.block_device_name(bdev)
self.assertTrue(type(name) is str)
def test_block_device_name_nullptr(self):
bdev = util.get_typed_pointer(self.nullptr, self.block_device_type).dereference()
self.assertTrue(type(bdev) is gdb.Value)
self.assertTrue(bdev.type == self.block_device_type)
with self.assertRaises(gdb.NotAvailableError):
name = storage.block_device_name(bdev)
def test_block_device_name_poisonptr(self):
bdev = util.get_typed_pointer(self.poisonptr, self.block_device_type).dereference()
self.assertTrue(type(bdev) is gdb.Value)
self.assertTrue(bdev.type == self.block_device_type)
with self.assertRaises(gdb.NotAvailableError):
name = storage.block_device_name(bdev)
def test_is_bdev_inode(self):
inode = self.get_block_device_inode()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
self.assertTrue(storage.is_bdev_inode(inode))
def test_is_bdev_inode_fs_inode(self):
inode = self.get_filesystem_inode()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
self.assertFalse(storage.is_bdev_inode(inode))
def test_is_bdev_inode_null_inode(self):
inode = util.get_typed_pointer(self.nullptr, self.inode_type)
inode = inode.dereference()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
with self.assertRaises(gdb.NotAvailableError):
x = storage.is_bdev_inode(inode)
def test_is_bdev_inode_poison_inode(self):
inode = util.get_typed_pointer(self.poisonptr, self.inode_type)
inode = inode.dereference()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
with self.assertRaises(gdb.NotAvailableError):
x = storage.is_bdev_inode(inode)
def test_inode_on_bdev_bdev_inode(self):
bdev_sb = self.get_blockdev_superblock()
inode = self.get_block_device_inode()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
bdev = storage.inode_on_bdev(inode)
self.assertTrue(type(bdev) is gdb.Value)
self.assertTrue(bdev.type == self.block_device_type)
self.assertTrue(inode['i_sb'] == bdev_sb)
self.assertTrue(fs.super_fstype(inode['i_sb']) == "bdev")
def test_inode_on_bdev_fs_inode(self):
bdev_sb = self.get_blockdev_superblock()
inode = self.get_filesystem_inode()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
bdev = storage.inode_on_bdev(inode)
self.assertTrue(type(bdev) is gdb.Value)
self.assertTrue(bdev.type == self.block_device_type)
self.assertFalse(inode['i_sb'] == bdev_sb)
self.assertFalse(fs.super_fstype(inode['i_sb']) == "bdev")
def test_inode_on_bdev_null_inode(self):
inode = util.get_typed_pointer(self.nullptr, self.inode_type)
inode = inode.dereference()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
with self.assertRaises(gdb.NotAvailableError):
bdev = storage.inode_on_bdev(inode)
def test_inode_on_bdev_poison_inode(self):
inode = util.get_typed_pointer(self.poisonptr, self.inode_type)
inode = inode.dereference()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
with self.assertRaises(gdb.NotAvailableError):
bdev = storage.inode_on_bdev(inode)
def test_inode_to_block_device_bdev_inode(self):
inode = self.get_block_device_inode()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
bdev = storage.inode_to_block_device(inode)
self.assertTrue(type(bdev) is gdb.Value)
self.assertTrue(bdev.type == self.block_device_type)
def test_inode_to_block_device_filesystem_inode(self):
inode = self.get_filesystem_inode()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
with self.assertRaises(TypeError):
bdev = storage.inode_to_block_device(inode)
def test_inode_to_block_device_null_inode(self):
inode = util.get_typed_pointer(self.nullptr, self.inode_type)
inode = inode.dereference()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
with self.assertRaises(gdb.NotAvailableError):
bdev = storage.inode_to_block_device(inode)
def test_inode_to_block_device_poison_inode(self):
inode = util.get_typed_pointer(self.poisonptr, self.inode_type)
inode = inode.dereference()
self.assertTrue(type(inode) is gdb.Value)
self.assertTrue(inode.type == self.inode_type)
with self.assertRaises(gdb.NotAvailableError):
bdev = storage.inode_to_block_device(inode)
def test_gendisk_name_disk(self):
bdev = self.get_block_device()
name = storage.gendisk_name(bdev['bd_disk'])
self.assertTrue(type(name) is str)
def test_gendisk_name_part(self):
bdev = self.get_block_device()
name = storage.gendisk_name(bdev['bd_part'])
self.assertTrue(type(name) is str)
def test_gendisk_name_disk_null_bdev(self):
bdev = util.get_typed_pointer(self.nullptr, self.block_device_type)
bdev = bdev.dereference()
with self.assertRaises(gdb.NotAvailableError):
name = storage.gendisk_name(bdev['bd_disk'])
def test_gendisk_name_disk_poison_bdev(self):
bdev = util.get_typed_pointer(self.poisonptr, self.block_device_type)
bdev = bdev.dereference()
with self.assertRaises(gdb.NotAvailableError):
name = storage.gendisk_name(bdev['bd_disk'])
def test_gendisk_to_dev(self):
gendisk = self.get_gendisk()
self.assertTrue(type(gendisk) is gdb.Value)
self.assertTrue(gendisk.type == self.gendisk_type)
dev = storage.gendisk_to_dev(gendisk)
self.assertTrue(type(dev) is gdb.Value)
self.assertTrue(dev.type == self.device_type)
def test_part_to_dev(self):
part = self.get_hd_struct()
self.assertTrue(type(part) is gdb.Value)
self.assertTrue(part.type == self.hd_struct_type)
dev = storage.part_to_dev(part)
self.assertTrue(type(dev) is gdb.Value)
self.assertTrue(dev.type == self.device_type)
def test_dev_to_gendisk(self):
gendisk = self.get_gendisk()
self.assertTrue(type(gendisk) is gdb.Value)
self.assertTrue(gendisk.type == self.gendisk_type)
dev = storage.gendisk_to_dev(gendisk)
self.assertTrue(type(dev) is gdb.Value)
self.assertTrue(dev.type == self.device_type)
ngendisk = storage.dev_to_gendisk(dev)
self.assertTrue(type(ngendisk) is gdb.Value)
self.assertTrue(ngendisk.type == self.gendisk_type)
self.assertTrue(gendisk == ngendisk)
def test_dev_to_part(self):
hd_struct = self.get_hd_struct()
self.assertTrue(type(hd_struct) is gdb.Value)
self.assertTrue(hd_struct.type == self.hd_struct_type)
dev = storage.part_to_dev(hd_struct)
self.assertTrue(type(dev) is gdb.Value)
self.assertTrue(dev.type == self.device_type)
nhd_struct = storage.dev_to_part(dev)
self.assertTrue(type(nhd_struct) is gdb.Value)
self.assertTrue(nhd_struct.type == self.hd_struct_type)
self.assertTrue(hd_struct == nhd_struct)