/
erasure-simulator.go
129 lines (126 loc) · 3.99 KB
/
erasure-simulator.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
127
128
129
package grasure
//SimOptions defines the parameters for simulation
type SimOptions struct {
//switch between "diskFail" and "bitRot"
Mode string
// specify which disks to fail
FailDisk string
// specify number of disks to fail
FailNum int
//specify the fileName, used only for "bitRot" mode
FileName string
}
//the proportion of stripe where bitrot occurs of all stripes
const stripeFailProportion = 0.3
//Destroy simulates disk failure or bitrot:
//
//for `diskFail mode`, `failNum` random disks are marked as unavailable, `failName` is ignored.
//
// for `bitRot`, `failNum` random blocks in a stripe of the file corrupts, that only works in Read Mode;
//
// Since it's a simulation, no real data will be lost.
// Note that failNum = min(failNum, DiskNum).
//func (e *Erasure) Destroy(simOption *SimOptions) {
// //if disk is currently unhealthy then give up
// if !e.isDiskHealthy() {
// return
// }
// //if failDisk is specialized, then use that
// if simOption.FailDisk != "" {
// disks := strings.Split(simOption.FailDisk, ",")
// for _, d := range disks {
// dd, _ := strconv.Atoi(d)
// e.diskInfos[dd].available = false
// }
// return
// }
// if simOption.Mode == "diskFail" || simOption.Mode == "DiskFail" {
// if simOption.FailNum <= 0 {
// return
// }
// if simOption.FailNum > e.DiskNum {
// simOption.FailNum = e.DiskNum
// }
//
// //we randomly picked up failNum disks and mark as unavailable
// if !e.Quiet {
// log.Println("simulate failure on:")
// }
//
// shuff := genRandomArr(e.DiskNum, 0)
// for i := 0; i < simOption.FailNum; i++ {
//
// if !e.Quiet {
// log.Println(e.diskInfos[shuff[i]].diskPath)
// }
// e.diskInfos[shuff[i]].available = false
// }
// } else if simOption.Mode == "bitRot" || simOption.Mode == "BitRot" {
// //in thi smode, we don't really corrupt a bit. Instead, we mark the block containing rots as failed
// // which is omnipresent is today's storage facilities.
// //if fileName is "", we corrupt all the files, else corrupt specific file
// if simOption.FailNum > e.K+e.M {
// simOption.FailNum = e.K + e.M
// }
// if simOption.FileName == "" {
// e.fileMap.Range(func(filename, fi interface{}) bool {
// fd := fi.(*fileInfo)
// //of course the bitrot must be random, and pesudo-random
// //algorithms have flaws. For every stripe, we corrupt failNum blocks
// stripeNum := len(fd.blockInfos)
// stripeFail := int(stripeFailProportion * float32(stripeNum))
// for i := range genRandomArr(stripeNum, 0)[:stripeFail] {
//
// for j := range genRandomArr(e.K+e.M, 0)[:simOption.FailNum] {
// fd.blockInfos[i][j].bstat = blkFail
// }
// }
// return true
// })
// } else {
// baseFileName := filepath.Base(simOption.FileName)
// intFi, ok := e.fileMap.Load(baseFileName)
// if !ok {
// log.Fatal(errFileNotFound)
// }
// fi := intFi.(*fileInfo)
//
// //of course the bitrot must be random, and pesudo-random
// //algorithms have flaws. For every stripe, we corrupt simOption.FailNum blocks
// stripeNum := len(fi.blockInfos)
// stripeFail := int(stripeFailProportion * float32(stripeNum))
// strps := genRandomArr(stripeNum, 0)[:stripeFail]
// for _, i := range strps {
//
// blks := genRandomArr(e.K+e.M, 0)[:simOption.FailNum]
// for _, j := range blks {
// // fmt.Printf("i:%d, j :%d fails.\n", i, j)
// fi.blockInfos[i][j].bstat = blkFail
// }
// }
//
// }
// } else {
// log.Fatal("please specialize failMode in diskFail and bitRot")
// }
//}
//
////print disk status
//func (e *Erasure) printDiskStatus() {
// for i, disk := range e.diskInfos {
//
// fmt.Printf("DiskId:%d, available:%tn,numBlocks:%d, storage:%d/%d (bytes)\n",
// i, disk.available, disk.numBlocks, int64(disk.numBlocks)*e.BlockSize, disk.capacity)
// }
//}
//
////check system health
//// 1. if currently working disks' number is less than DiskNum, inform the user
//func (e *Erasure) isDiskHealthy() bool {
// for _, v := range e.diskInfos[:e.DiskNum] {
// if !v.available {
// return false
// }
// }
// return true
//}