-
Notifications
You must be signed in to change notification settings - Fork 0
/
lab3b.py
executable file
·242 lines (227 loc) · 10.4 KB
/
lab3b.py
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
#!/usr/bin/python
import csv, sys
Inodes = []
Bfrees = set([])
Ifrees = set([])
Dirents = []
Indirects = []
Groups = []
#occupiedBlocks = set([])
#tracks all the blocks that are referenced
referencedBlocks = dict([])
#counts how many directories an inode says its referenced by
linkCounts = dict([])
#counts how many directories are referenced by an inode
linksFound = dict([])
#for each child directory stores their parent
childParentDirs = dict([])
def main():
inconsistencyFound = False
if len(sys.argv) != 2:
sys.stderr.write("please use one and only one argument")
exit(1)
#to check if file is valid
try:
csvFile = open(sys.argv[1])
except:
sys.stderr.write("Error: couldn't open specified file")
exit(1)
#Go through the file and sort the different lines into lists
#Also should do anything with the Superblock here
#Also maybe the Group stuff since I think there might only be one group always, but it probably wouldn't be hard to assume multiple groups
with open(sys.argv[1]) as csvFile:
reader = csv.reader(csvFile)
for line in reader:
identifier = line[0]
if (identifier == 'SUPERBLOCK'):
numInodes = int(line[2])
firstNonReservedInode = int(line[7])
maxBlockNum = int(line[1])
blockSize = int(line[3])
inodeSize = int(line[4])
elif identifier == 'GROUP':
#Groups.append(line)
Bbitmap = int(line[6])
Ibitmap = int(line[7])
reserved = int(line[8]) + inodeSize*int(line[3])/blockSize
elif identifier == 'BFREE':
Bfrees.add(int(line[1]))
elif identifier == 'IFREE':
Ifrees.add(int(line[1]))
elif identifier == 'DIRENT':
Dirents.append(line)
elif identifier == 'INODE':
Inodes.append(line)
elif identifier == 'INDIRECT':
Indirects.append(line)
if line[5] in referencedBlocks:
referencedBlocks[int(line[5])] += 1
else:
referencedBlocks[int(line[5])] = 1
#indirects check
for line in Indirects:
blockNum = int(line[5])
#print(blockNum)
level = int(line[2])
#check for invalid
if blockNum < 0 or blockNum > maxBlockNum:
print("test")
if level == 1:
print("INVALID INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 12")
inconsistencyFound = True
elif level == 2:
print("INVALID DOUBLE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 268")
inconsistencyFound = True
elif level == 3:
print("INVALID TRIPLE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 65804")
inconsistencyFound = True
#Check for reserved
if blockNum != 0 and blockNum < reserved:
if level == 1:
print("RESERVED INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 12")
inconsistencyFound = True
elif level == 2:
print("RESERVED DOUBLE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 268")
inconsistencyFound = True
elif level == 3:
print("RESERVED TRIPLE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 65804")
inconsistencyFound = True
#Inode part
for line in Inodes:
#might have to check if the mode is 0 of the inodes
if int(line[1]) in Ifrees:
print("ALLOCATED INODE " + line[1] + " ON FREELIST")
inconsistencyFound = True
Ifrees.remove(int(line[1]))
#Ifrees.add(int(line[1]))
linkCounts.update({int(line[1]): int(line[6])})
if line[2] != "s" or int(line[10]) >= 60:
for i in range(0, 15):
blockNum = int(line[12+i])
#occupiedBlocks.add(blockNum)
#used to check for duplicates or unreferenced blocks
if blockNum in referencedBlocks:
referencedBlocks[blockNum] += 1
else:
referencedBlocks[blockNum] = 1
#check for invalid
if blockNum < 0 or blockNum > maxBlockNum:
if i < 12:
print("INVALID BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET " + str(i))
inconsistencyFound = True
elif i == 12:
print("INVALID INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 12")
inconsistencyFound = True
elif i == 13:
print("INVALID DOUBLE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 268")
inconsistencyFound = True
elif i == 14:
print("INVALID TRIPLE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 65804")
inconsistencyFound = True
#Check for reserved
if blockNum != 0 and blockNum < reserved:
if i < 12:
print("RESERVED BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET " + str(i))
inconsistencyFound = True
elif i == 12:
print("RESERVED INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 12")
inconsistencyFound = True
elif i == 13:
print("RESERVED DOUBLE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 268")
inconsistencyFound = True
elif i == 14:
print("RESERVED TRIPLE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 65804")
inconsistencyFound = True
#check for allocated blocks in freelist
for i in Bfrees:
if i in referencedBlocks:
print("ALLOCATED BLOCK " + str(i) + " ON FREELIST")
inconsistencyFound = True
else:
#print(i)
referencedBlocks[i] = 1
#print(i in referencedBlocks)
#check unreferenced blocks
for i in range(reserved +1, maxBlockNum):
if not int(i) in referencedBlocks:
r = 0
print("UNREFERENCED BLOCK " + str(i))
inconsistencyFound = True
#print(referencedBlocks[i])
#directory part
for line in Dirents:
inodeNum = int(line[3])
if inodeNum in linksFound:
linksFound[inodeNum] += 1
else:
linksFound.update({inodeNum : 1})
if inodeNum < 1 or inodeNum > numInodes:
print("DIRECTORY INODE " + line[1] + " NAME " + line[6] + " INVALID INODE " + str(inodeNum))
inconsistencyFound = True
#might have to check the inodes and if it has mode == 0
elif inodeNum in Ifrees:
print("DIRECTORY INODE " + line[1] + " NAME " + line[6] + " UNALLOCATED INODE " + str(inodeNum))
inconsistencyFound = True
elif line[6] == "'.'" and int(line[1]) != inodeNum:
print("DIRECTORY INODE " + line[1] + " NAME " + line[6] + " LINK TO INODE " + str(inodeNum) + " SHOULD BE " + line[1])
inconsistencyFound = True
elif line[6] != "'.'" and line[6] != "'..'" :
#print(str(inodeNum) + " " + line[1])
childParentDirs.update({int(inodeNum) : int(line[1])})
#need to have the checking for parent directory part
#elif line[6] == "'..'" and int(line[1]) != inodeNum:
#print("DIRECTORY INODE " + line[1] + " NAME " + line[6] + " LINK TO INODE " + str(inodeNum) + " SHOULD BE " + line[1])
#check for .. links correct
for line in Dirents:
if line[6] == "'..'":
#print(line)
#idk what to do if its not, i dont think that could happen - for some reason sometimes 2 is the parent even though idk why so I'm assuming if parent isn't given that it's 2
if int(line[1]) in childParentDirs:
#print(str(childParentDirs[int(line[1])]) + " " + line[3])
if childParentDirs[int(line[1])] != int(line[3]):
print("DIRECTORY INODE " + line[1] + " NAME " + line[6] + " LINK TO INODE " + line[3] + " SHOULD BE " + str(childParentDirs[int(line[1])]))
inconsistencyFound = True
elif int(line[3]) != 2:
print("DIRECTORY INODE " + line[1] + " NAME " + line[6] + " LINK TO INODE " + line[3] + " SHOULD BE 2")
inconsistencyFound = True
#check for numLinks
for node in linkCounts:
if not node in linksFound:
print("INODE " + str(node) + " HAS 0 LINKS BUT LINKCOUNT IS " + str(linkCounts[node]))
inconsistencyFound = True
elif linkCounts[node] != linksFound[node]:
print("INODE " + str(node) + " HAS " + str(linksFound[node]) + " LINKS BUT LINKCOUNT IS " + str(linkCounts[node]))
inconsistencyFound = True
#check duplicates
for line in Inodes:
#for checking unallocated node not in list
#print(line)
Ifrees.add(int(line[1]))
if line[2] != 's' or int(line[10]) >= 60:
for i in range(0, 15):
blockNum = int(line[12+i])
if blockNum != 0 and blockNum in referencedBlocks:
if referencedBlocks[blockNum] > 1:
if i < 12:
print("DUPLICATE BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET " + str(i))
inconsistencyFound = True
elif i == 12:
print("DUPLICATE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 12")
inconsistencyFound = True
elif i == 13:
print("DUPLICATE DOUBLE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 268")
inconsistencyFound = True
elif i == 14:
print("DUPLICATE TRIPLE INDIRECT BLOCK " + str(blockNum) + " IN INODE " + line[1] + " AT OFFSET 65804")
inconsistencyFound = True
#check for unallocated Inodes
for i in range(firstNonReservedInode, numInodes+1):
if not i in Ifrees:
print("UNALLOCATED INODE " + str(i) + " NOT ON FREELIST")
inconsistencyFound = True
#exit at the end of the function
if inconsistencyFound: #exit 2 if inconsistency was found
sys.exit(2)
sys.exit(0) #exit 0 if no inconsistencies were found
if __name__ == "__main__":
main()