-
Notifications
You must be signed in to change notification settings - Fork 0
/
dir_manager_diag.go
126 lines (117 loc) · 3.56 KB
/
dir_manager_diag.go
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
package bakemono
import (
"bytes"
"fmt"
"log"
)
func (dm *DirManager) DiagHangUsedDirs() (int, error) {
// mark dirs used and linked from head node
var counter int
var mpDirsUsed []map[int]bool
for seg := 0; seg < int(dm.SegmentsNum); seg++ {
mp := make(map[int]bool)
for buck := 0; buck < int(dm.BucketsNumPerSegment); buck++ {
index := buck * DirDepth
for dm.Dirs[segId(seg)][index].offset() != 0 {
counter++
mp[index] = true
next := int(dm.Dirs[segId(seg)][index].next())
if next == 0 {
break
}
index = next
if counter > 100000000 {
panic("DiagHangUsedDirs: counter > 100000000")
}
}
}
mpDirsUsed = append(mpDirsUsed, mp)
}
// check if dir hang-up
for seg := 0; seg < int(dm.SegmentsNum); seg++ {
for buck := 0; buck < int(dm.BucketsNumPerSegment); buck++ {
index := buck * DirDepth
for i := 0; i < DirDepth; i++ {
if dm.Dirs[segId(seg)][index+i].offset() != 0 {
if !mpDirsUsed[seg][index+i] {
return 0, fmt.Errorf("find a hang-up dir. seg: %d, buck: %d, index: %d", seg, buck, index+i)
}
}
}
}
}
return counter, nil
}
func (dm *DirManager) DiagHangFreeDirs() (int, error) {
// mark dirs registered in free list
var counter int
var mpDirsInFreeList []map[uint16]bool
for seg := 0; seg < int(dm.SegmentsNum); seg++ {
mp := make(map[uint16]bool)
index := dm.DirFreeStart[segId(seg)]
for index != 0 {
counter++
mp[index] = true
index = dm.Dirs[segId(seg)][index].next()
if counter > 100000000 {
panic("DiagHangFreeDirs: counter > 100000000")
}
}
mpDirsInFreeList = append(mpDirsInFreeList, mp)
}
// check if dir hang-up
for seg := 0; seg < int(dm.SegmentsNum); seg++ {
for buck := 0; buck < int(dm.BucketsNumPerSegment); buck++ {
index := buck * DirDepth
for i := 1; i < DirDepth; i++ {
if dm.Dirs[segId(seg)][index+i].offset() == 0 {
if !mpDirsInFreeList[seg][uint16(index+i)] {
return 0, fmt.Errorf("find a hang-up dir. seg: %d, buck: %d, index: %d", seg, buck, index+i)
}
}
}
}
}
return counter, nil
}
func (dm *DirManager) DiagDumpAllDirs() {
log.Printf("Dump all dirs, segments: %d, buckets: %d", dm.SegmentsNum, dm.BucketsNumPerSegment)
for seg := 0; seg < int(dm.SegmentsNum); seg++ {
log.Printf("Segment %d", seg)
for buck := 0; buck < int(dm.BucketsNumPerSegment); buck++ {
log.Printf("Bucket %d", buck)
index := buck * DirDepth
for i := 0; i < DirDepth; i++ {
log.Printf("Segment %d, \tBucket %d, \tDir %d, \toffset: %d, \tprev: %d, next: %d",
seg, buck, index, dm.Dirs[segId(seg)][index].offset(), dm.Dirs[segId(seg)][index].prev(), dm.Dirs[segId(seg)][index].next())
index++
}
}
}
}
func (dm *DirManager) DiagDumpAllDirsToString() string {
bf := bytes.NewBufferString("")
bf.WriteString(fmt.Sprintf("Dump all dirs, segments: %d, buckets: %d\n", dm.SegmentsNum, dm.BucketsNumPerSegment))
for seg := 0; seg < int(dm.SegmentsNum); seg++ {
//log.Printf("Segment %d", seg)
for buck := 0; buck < int(dm.BucketsNumPerSegment); buck++ {
//log.Printf("Bucket %d", buck)
index := buck * DirDepth
for i := 0; i < DirDepth; i++ {
bf.WriteString(fmt.Sprintf(
"Segment %d, \tBucket %d, \tDir %d, \toffset: %d, \tprev: %d, next: %d\n",
seg, buck, index, dm.Dirs[segId(seg)][index].offset(), dm.Dirs[segId(seg)][index].prev(), dm.Dirs[segId(seg)][index].next()))
index++
}
}
}
return bf.String()
}
func (dm *DirManager) DiagPanicHangUpDirs() error {
_, err := dm.DiagHangUsedDirs()
if err != nil {
log.Printf("dirInsert: DiagHangUsedDirs: %v", err)
return err
}
return nil
}