forked from gluster/glusterd2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate-graph.go
258 lines (212 loc) · 7.12 KB
/
generate-graph.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
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
/* Core file for volfile generation */
package volgen
import (
"fmt"
"github.com/gluster/glusterd2/errors"
"github.com/gluster/glusterd2/volume"
)
type trans struct {
Name string
Type string
}
func graphAddAsRoot(graph *Xlator, vinfo *volume.Volinfo, gtype string) error {
switch gtype {
case "CLIENT":
graph.Name = vinfo.Name
graph.Type = "debug/io-stats"
graph.Options = make(map[string]string)
// Add option to fuse graph
graph.Options["count-fop-hits"] = "off"
graph.Options["latency-measurement"] = "off"
case "SERVER":
gname := fmt.Sprintf("%s-server", vinfo.Name)
graph.Name = gname
graph.Type = "protocol/server"
graph.Options = make(map[string]string)
// Add option to server graph
graph.Options["auth.addr./brr1.allow"] = "*"
graph.Options["transport-type"] = "tcp"
default:
return errors.ErrWrongGraphType
}
return nil
}
func addGraphClientLink(cnode *Xlator, vtype string, name string, brick volume.Brickinfo) {
node := new(Xlator)
node.Options = make(map[string]string)
node.Name = name
node.Type = vtype
// Add options to client subgraph
node.Options["transport-type"] = "tcp"
node.Options["remote-subvolume"] = brick.Path
node.Options["remote-host"] = brick.Hostname
node.Options["ping-timeout"] = "42"
cnode.Children = append(cnode.Children, *node)
}
func graphBuildClient(vinfo *volume.Volinfo) *Xlator {
cnode := new(Xlator)
var i int
switch vinfo.Type {
case 1:
lbrick := len(vinfo.Bricks)
Dcount := lbrick / int(vinfo.ReplicaCount)
for d := 0; d < Dcount; d++ {
subnode := new(Xlator)
for j := 1; j <= int(vinfo.ReplicaCount); j++ {
name := fmt.Sprintf("%v-client-%v", vinfo.Name, i)
addGraphClientLink(subnode, "protocol/client", name, vinfo.Bricks[i])
i++
}
sname := fmt.Sprintf("%s-replicate-%d", vinfo.Name, d)
svtype := "cluster/replicate"
subnode.Name = sname
subnode.Type = svtype
cnode.Children = append(cnode.Children, *subnode)
}
sname := fmt.Sprintf("%s-dht", vinfo.Name)
svtype := "cluster/distribute"
cnode.Name = sname
cnode.Type = svtype
default:
// As of now if no volume type given then generate plane distribute volume graph
for i, brick := range vinfo.Bricks {
name := fmt.Sprintf("%v-client-%v", vinfo.Name, i)
addGraphClientLink(cnode, "protocol/client", name, brick)
i++
}
cnode.Name = fmt.Sprintf("%s-dht", vinfo.Name)
cnode.Type = "cluster/distribute"
}
return cnode
}
func mergeClientWithRoot(Graph *Xlator, Craph *Xlator) {
Graph.Children = append(Graph.Children, *Craph)
}
/* Adding options to translator*/
func addOption(tgraph *Xlator) {
tgraph.Options = make(map[string]string)
switch tgraph.Type {
case "storage/posix":
tgraph.Options["update-link-count-parent"] = "on"
case "features/trash":
tgraph.Options["trash-internal-op"] = "off"
tgraph.Options["trash-dir"] = ".trashcan"
case "features/changetimerecorder":
tgraph.Options["record-counters"] = "off"
tgraph.Options["ctr-enabled"] = "off"
tgraph.Options["record-entry"] = "on"
tgraph.Options["ctr_inode_heal_expire_period"] = "300"
tgraph.Options["ctr_link_consistency"] = "off"
tgraph.Options["record-exit"] = "off"
tgraph.Options["hot-brick"] = "off"
tgraph.Options["db-type"] = "sqlite3"
case "features/changelog":
tgraph.Options["changelog-barrier-timeout"] = "120"
case "features/upcall":
tgraph.Options["cache-invalidation"] = "off"
case "features/marker":
tgraph.Options["inode-quota"] = "on"
tgraph.Options["gsync-force-xtime"] = "off"
tgraph.Options["xtime"] = "off"
case "features/quota":
tgraph.Options["deem-statfs"] = "on"
tgraph.Options["timeout"] = "0"
tgraph.Options["server-quota"] = "on"
case "features/read-only":
tgraph.Options["read-only"] = "off"
default:
tgraph.Options = nil
}
}
func linkParentToChildren(vinfo *volume.Volinfo, mgraph *Xlator, xdict []trans) *Xlator {
var kgraph *Xlator
for v, k := range xdict {
tgraph := new(Xlator)
tgraph.Name = fmt.Sprintf("%v-%v", vinfo.Name, k.Name)
tgraph.Type = fmt.Sprintf("%v", k.Type)
addOption(tgraph)
if v == 0 {
mgraph.Children = append(mgraph.Children, *tgraph)
(kgraph) = (&mgraph.Children[0])
continue
}
kgraph.Children = append(kgraph.Children, *tgraph)
kgraph = (&kgraph.Children[0])
}
return kgraph
}
func fuseBuildXlator(vinfo *volume.Volinfo, cgraph *Xlator) *Xlator {
var mgraph Xlator
fdict := []trans{
trans{Name: "open-behind", Type: "performance/open-behind"},
trans{Name: "quick-read", Type: "performance/quick-read"},
trans{Name: "io-cache", Type: "performance/io-cache"},
trans{Name: "readdir-ahead", Type: "performance/readdir-ahead"},
trans{Name: "read-ahead", Type: "performance/read-ahead"},
trans{Name: "write-behind", Type: "performance/write-behind"},
}
mgraph.Name = fmt.Sprintf("%v-md-cache", vinfo.Name)
mgraph.Type = fmt.Sprintf("performance/md-cache")
/* Adding all above fdict[] translator to graph */
fgraph := linkParentToChildren(vinfo, &mgraph, fdict)
/* Appending all client graph as a child of write-behind translator*/
fgraph.Children = append(fgraph.Children, *cgraph)
return &mgraph
}
func serverBuildXlator(vinfo *volume.Volinfo) *Xlator {
var mgraph Xlator
sdict := []trans{
trans{Name: "read-only", Type: "features/read-only"},
trans{Name: "worm", Type: "features/worm"},
trans{Name: "quota", Type: "features/quota"},
trans{Name: "index", Type: "features/index"},
trans{Name: "barrier", Type: "features/barrier"},
trans{Name: "marker", Type: "features/marker"},
trans{Name: "io-thread", Type: "performance/io-threads"},
trans{Name: "upcall", Type: "features/upcall"},
trans{Name: "locks", Type: "features/locks"},
trans{Name: "access-control", Type: "features/access-control"},
trans{Name: "bitrot-stub", Type: "features/bitrot-stub"},
trans{Name: "changelog", Type: "features/changelog"},
trans{Name: "changelogtimerecord", Type: "features/changetimerecorder"},
trans{Name: "trash", Type: "features/trash"},
trans{Name: "posix", Type: "storage/posix"},
}
mgraph.Name = fmt.Sprintf("brick")
mgraph.Type = fmt.Sprintf("debug/io-stats")
mgraph.Options = make(map[string]string)
mgraph.Options["count-fop-hits"] = "off"
mgraph.Options["latency-measurement"] = "off"
/* Adding all above sdict[] translator to graph */
linkParentToChildren(vinfo, &mgraph, sdict)
return &mgraph
}
func buildXlator(vinfo *volume.Volinfo, Cgraph *Xlator, gtype string) *Xlator {
mgraph := new(Xlator)
switch gtype {
case "CLIENT":
mgraph = fuseBuildXlator(vinfo, Cgraph)
case "SERVER":
mgraph = serverBuildXlator(vinfo)
}
return mgraph
}
//GenerateGraph function will do all task for graph generation
func GenerateGraph(vinfo *volume.Volinfo, gtype string) *Xlator {
Graph := new(Xlator)
Cgraph := new(Xlator)
Mgraph := new(Xlator)
// Root of the graph
graphAddAsRoot(Graph, vinfo, gtype)
// Building client graph
// Do not build client graph for server volfile.
if gtype != "SERVER" {
Cgraph = graphBuildClient(vinfo)
}
// Build the translator graph which will be added bw client and root of
// the graph
Mgraph = buildXlator(vinfo, Cgraph, gtype)
// merge root of the graph with rest of the graph
mergeClientWithRoot(Graph, Mgraph)
return Graph
}