This source file includes following definitions.
- find_device
- find_topology
- add_device
- add_topology
- standalone_cfg_add_device
- standalone_cfg_add_device_options
- standalone_cfg_add_node
- standalone_cfg_add_node_priority
- destroy_topology
- destroy_devices
- cfg_register_topology
- cfg_register_device
- standalone_cfg_commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <crm_internal.h>
21 #include <crm/common/xml.h>
22 #include <crm/msg_xml.h>
23 #include <crm/stonith-ng.h>
24 #include <crm/fencing/internal.h>
25 #include <internal.h>
26 #include <standalone_config.h>
27
28 struct device {
29 char *name;
30 char *agent;
31 char *hostlist;
32 char *hostmap;
33
34 struct {
35 char *key;
36 char *val;
37 } key_vals[STANDALONE_CFG_MAX_KEYVALS];
38 int key_vals_count;
39
40 struct device *next;
41 };
42
43 struct topology {
44 char *node_name;
45 struct {
46 char *device_name;
47 unsigned int level;
48 } priority_levels[STANDALONE_CFG_MAX_KEYVALS];
49 int priority_levels_count;
50
51 struct topology *next;
52 };
53
54 static struct device *dev_list;
55 static struct topology *topo_list;
56
57 static struct device *
58 find_device(const char *name)
59 {
60 struct device *dev = NULL;
61
62 for (dev = dev_list; dev != NULL; dev = dev->next) {
63 if (!strcasecmp(dev->name, name)) {
64 break;
65 }
66 }
67
68 return dev;
69 }
70
71 static struct topology *
72 find_topology(const char *name)
73 {
74 struct topology *topo = NULL;
75
76 for (topo = topo_list; topo != NULL; topo = topo->next) {
77 if (!strcasecmp(topo->node_name, name)) {
78 break;
79 }
80 }
81
82 return topo;
83 }
84
85 static void
86 add_device(struct device *dev)
87 {
88 dev->next = dev_list;
89 dev_list = dev;
90 }
91
92 static void
93 add_topology(struct topology *topo)
94 {
95 topo->next = topo_list;
96 topo_list = topo;
97 }
98
99 int
100 standalone_cfg_add_device(const char *device, const char *agent)
101 {
102 struct device *dev = NULL;
103
104 if (!device || !agent) {
105 return -1;
106 }
107
108
109 if (find_device(device)) {
110 return 0;
111 }
112 dev = calloc(1, sizeof(struct device));
113
114 dev->name = strdup(device);
115 dev->agent = strdup(agent);
116 add_device(dev);
117
118 return 0;
119 }
120
121 int
122 standalone_cfg_add_device_options(const char *device, const char *key, const char *value)
123 {
124 struct device *dev;
125
126 if (!device || !key || !value) {
127 return -1;
128 } else if (!(dev = find_device(device))) {
129 crm_err("Standalone config error, could not find device %s to add key value %s=%s to",
130 device, key, value);
131 return -1;
132 } else if (dev->key_vals_count >= STANDALONE_CFG_MAX_KEYVALS) {
133 return -1;
134 }
135
136 dev->key_vals[dev->key_vals_count].key = strdup(key);
137 dev->key_vals[dev->key_vals_count].val = strdup(value);
138 dev->key_vals_count++;
139
140 return 0;
141 }
142
143 int
144 standalone_cfg_add_node(const char *node, const char *device, const char *ports)
145 {
146 struct device *dev;
147 char **ptr;
148 char *tmp;
149 size_t len = strlen(":;") + 1;
150 size_t offset = 0;
151
152
153 if (!node || !device) {
154 return -1;
155 } else if (!(dev = find_device(device))) {
156 crm_err("Standalone config error, could not find device %s to add mode %s to",
157 device, node);
158 return -1;
159 }
160
161 ptr = &dev->hostlist;
162
163 len += strlen(node);
164 if (ports) {
165 ptr = &dev->hostmap;
166 len += strlen(ports);
167 }
168
169 tmp = *ptr;
170
171 if (tmp) {
172 offset = strlen(tmp);
173 tmp = realloc_safe(tmp, len + offset + 1);
174 } else {
175 tmp = malloc(len);
176 }
177
178 *ptr = tmp;
179 tmp += offset;
180
181 if (ports) {
182 sprintf(tmp, "%s:%s;", node, ports);
183 } else {
184 sprintf(tmp, "%s ", node);
185 }
186
187 return 0;
188 }
189
190 int
191 standalone_cfg_add_node_priority(const char *node, const char *device, unsigned int level)
192 {
193 struct topology *topo = NULL;
194 int new = 0;
195
196 if (!node || !device) {
197 return -1;
198 }
199
200 if (!(topo = find_topology(node))) {
201 new = 1;
202 topo = calloc(1, sizeof(struct topology));
203 topo->node_name = strdup(node);
204 } else if (topo->priority_levels_count >= STANDALONE_CFG_MAX_KEYVALS) {
205 return -1;
206 }
207
208 topo->priority_levels[topo->priority_levels_count].device_name = strdup(device);
209 topo->priority_levels[topo->priority_levels_count].level = level;
210 topo->priority_levels_count++;
211
212 if (new) {
213 add_topology(topo);
214 }
215
216 return 0;
217 }
218
219 static int
220 destroy_topology(void)
221 {
222 struct topology *topo = NULL;
223 int i;
224
225 while (topo_list) {
226 topo = topo_list;
227
228 free(topo->node_name);
229 for (i = 0; i < topo->priority_levels_count; i++) {
230 free(topo->priority_levels[i].device_name);
231 }
232
233 topo_list = topo->next;
234 free(topo);
235 }
236 return 0;
237 }
238
239 static int
240 destroy_devices(void)
241 {
242 struct device *dev = NULL;
243 int i;
244
245 while (dev_list) {
246 dev = dev_list;
247
248 free(dev->name);
249 free(dev->agent);
250 free(dev->hostlist);
251 free(dev->hostmap);
252 for (i = 0; i < dev->key_vals_count; i++) {
253 free(dev->key_vals[i].key);
254 free(dev->key_vals[i].val);
255 }
256 dev_list = dev->next;
257 free(dev);
258 }
259
260 return 0;
261 }
262
263 static int
264 cfg_register_topology(struct topology *topo)
265 {
266 stonith_key_value_t *devices = NULL;
267 xmlNode *data;
268 char *dump;
269 int i;
270 int res = 0;
271
272 for (i = 0; i < topo->priority_levels_count; i++) {
273 devices = stonith_key_value_add(devices, NULL, topo->priority_levels[i].device_name);
274
275 data = create_level_registration_xml(topo->node_name, NULL, NULL, NULL,
276 topo->priority_levels[i].level, devices);
277
278 dump = dump_xml_formatted(data);
279 crm_info("Standalone config level being added:\n%s", dump);
280
281 res |= stonith_level_register(data, NULL);
282 free(dump);
283 free_xml(data);
284 stonith_key_value_freeall(devices, 1, 1);
285 }
286
287 return res;
288 }
289
290 static int
291 cfg_register_device(struct device *dev)
292 {
293 stonith_key_value_t *params = NULL;
294 xmlNode *data;
295 char *dump;
296 int i;
297 int res;
298
299
300 if (dev->hostlist) {
301 params = stonith_key_value_add(params, STONITH_ATTR_HOSTLIST, dev->hostlist);
302 }
303 if (dev->hostmap) {
304 params = stonith_key_value_add(params, STONITH_ATTR_HOSTMAP, dev->hostmap);
305 }
306 for (i = 0; i < dev->key_vals_count; i++) {
307 params stonith_key_value_add(params, dev->key_vals[i].key, dev->key_vals[i].val);
308 }
309
310
311 data = create_device_registration_xml(dev->name, __FUNCTION__, dev->agent, params);
312
313 dump = dump_xml_formatted(data);
314 crm_info("Standalone device being added:\n%s", dump);
315
316 res = stonith_device_register(data, NULL, FALSE);
317
318 free(dump);
319 free_xml(data);
320 stonith_key_value_freeall(params, 1, 1);
321 return res;
322 }
323
324 int
325 standalone_cfg_commit(void)
326 {
327 struct device *dev = NULL;
328 struct topology *topo = NULL;
329
330 for (dev = dev_list; dev != NULL; dev = dev->next) {
331 cfg_register_device(dev);
332 }
333
334 for (topo = topo_list; topo != NULL; topo = topo->next) {
335 cfg_register_topology(topo);
336 }
337
338 destroy_devices();
339 destroy_topology();
340 return 0;
341 }