This source file includes following definitions.
- fenced_scheduler_init
- fenced_set_local_node
- fenced_get_local_node
- fenced_scheduler_cleanup
- local_node_allowed_for
- register_if_fencing_device
- fenced_scheduler_run
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdio.h>
13 #include <errno.h>
14 #include <glib.h>
15
16 #include <crm/pengine/status.h>
17 #include <crm/pengine/internal.h>
18
19 #include <pacemaker-internal.h>
20 #include <pacemaker-fenced.h>
21
22
23 static pcmk_scheduler_t *scheduler = NULL;
24
25
26
27
28
29
30
31 int
32 fenced_scheduler_init(void)
33 {
34 pcmk__output_t *logger = NULL;
35 int rc = pcmk__log_output_new(&logger);
36
37 if (rc != pcmk_rc_ok) {
38 return rc;
39 }
40
41 scheduler = pcmk_new_scheduler();
42 if (scheduler == NULL) {
43 pcmk__output_free(logger);
44 return ENOMEM;
45 }
46
47 pe__register_messages(logger);
48 pcmk__register_lib_messages(logger);
49 pcmk__output_set_log_level(logger, LOG_TRACE);
50 scheduler->priv->out = logger;
51
52 return pcmk_rc_ok;
53 }
54
55
56
57
58
59
60
61 void
62 fenced_set_local_node(const char *node_name)
63 {
64 pcmk__assert(scheduler != NULL);
65
66 scheduler->priv->local_node_name = pcmk__str_copy(node_name);
67 }
68
69
70
71
72
73
74
75 const char *
76 fenced_get_local_node(void)
77 {
78 if (scheduler == NULL) {
79 return NULL;
80 }
81 return scheduler->priv->local_node_name;
82 }
83
84
85
86
87
88 void
89 fenced_scheduler_cleanup(void)
90 {
91 if (scheduler != NULL) {
92 pcmk__output_t *logger = scheduler->priv->out;
93
94 if (logger != NULL) {
95 logger->finish(logger, CRM_EX_OK, true, NULL);
96 pcmk__output_free(logger);
97 scheduler->priv->out = NULL;
98 }
99 pcmk_free_scheduler(scheduler);
100 scheduler = NULL;
101 }
102 }
103
104
105
106
107
108
109
110
111
112 static pcmk_node_t *
113 local_node_allowed_for(const pcmk_resource_t *rsc)
114 {
115 if ((rsc != NULL) && (scheduler->priv->local_node_name != NULL)) {
116 GHashTableIter iter;
117 pcmk_node_t *node = NULL;
118
119 g_hash_table_iter_init(&iter, rsc->priv->allowed_nodes);
120 while (g_hash_table_iter_next(&iter, NULL, (void **) &node)) {
121 if (pcmk__str_eq(node->priv->name, scheduler->priv->local_node_name,
122 pcmk__str_casei)) {
123 return node;
124 }
125 }
126 }
127 return NULL;
128 }
129
130
131
132
133
134
135
136
137
138 static void
139 register_if_fencing_device(gpointer data, gpointer user_data)
140 {
141 pcmk_resource_t *rsc = data;
142 const char *rsc_id = pcmk__s(rsc->priv->history_id, rsc->id);
143
144 xmlNode *xml = NULL;
145 GHashTableIter hash_iter;
146 pcmk_node_t *node = NULL;
147 const char *name = NULL;
148 const char *value = NULL;
149 const char *agent = NULL;
150 const char *rsc_provides = NULL;
151 stonith_key_value_t *params = NULL;
152
153
154 if (rsc->priv->children != NULL) {
155
156 for (GList *iter = rsc->priv->children;
157 iter != NULL; iter = iter->next) {
158
159 register_if_fencing_device(iter->data, NULL);
160 if (pcmk__is_clone(rsc)) {
161 return;
162 }
163 }
164 return;
165 }
166
167 if (!pcmk_is_set(rsc->flags, pcmk__rsc_fence_device)) {
168 return;
169 }
170
171 if (pe__resource_is_disabled(rsc)) {
172 crm_info("Ignoring fencing device %s because it is disabled", rsc->id);
173 return;
174 }
175
176 if ((stonith_watchdog_timeout_ms <= 0) &&
177 pcmk__str_eq(rsc->id, STONITH_WATCHDOG_ID, pcmk__str_none)) {
178 crm_info("Ignoring fencing device %s "
179 "because watchdog fencing is disabled", rsc->id);
180 return;
181 }
182
183
184 node = local_node_allowed_for(rsc);
185 if (node == NULL) {
186 crm_info("Ignoring fencing device %s "
187 "because local node is not allowed to run it", rsc->id);
188 return;
189 }
190 if (node->assign->score < 0) {
191 crm_info("Ignoring fencing device %s "
192 "because local node has preference %s for it",
193 rsc->id, pcmk_readable_score(node->assign->score));
194 return;
195 }
196
197
198 if (pcmk__is_group(rsc->priv->parent)) {
199 pcmk_node_t *group_node = local_node_allowed_for(rsc->priv->parent);
200
201 if ((group_node != NULL) && (group_node->assign->score < 0)) {
202 crm_info("Ignoring fencing device %s "
203 "because local node has preference %s for its group",
204 rsc->id, pcmk_readable_score(group_node->assign->score));
205 return;
206 }
207 }
208
209 crm_debug("Reloading configuration of fencing device %s", rsc->id);
210
211 agent = crm_element_value(rsc->priv->xml, PCMK_XA_TYPE);
212
213 get_meta_attributes(rsc->priv->meta, rsc, NULL, scheduler);
214 rsc_provides = g_hash_table_lookup(rsc->priv->meta,
215 PCMK_STONITH_PROVIDES);
216
217 g_hash_table_iter_init(&hash_iter, pe_rsc_params(rsc, node, scheduler));
218 while (g_hash_table_iter_next(&hash_iter, (gpointer *) &name,
219 (gpointer *) &value)) {
220 if ((name == NULL) || (value == NULL)) {
221 continue;
222 }
223 params = stonith__key_value_add(params, name, value);
224 }
225
226 xml = create_device_registration_xml(rsc_id, st_namespace_any, agent,
227 params, rsc_provides);
228 stonith__key_value_freeall(params, true, true);
229 pcmk__assert(fenced_device_register(xml, true) == pcmk_rc_ok);
230 pcmk__xml_free(xml);
231 }
232
233
234
235
236
237
238
239
240
241 void
242 fenced_scheduler_run(xmlNode *cib)
243 {
244 CRM_CHECK((cib != NULL) && (scheduler != NULL)
245 && (scheduler->input == NULL), return);
246
247 pcmk_reset_scheduler(scheduler);
248
249 scheduler->input = cib;
250 pcmk__set_scheduler_flags(scheduler,
251 pcmk__sched_location_only|pcmk__sched_no_counts);
252 pcmk__schedule_actions(scheduler);
253 g_list_foreach(scheduler->priv->resources, register_if_fencing_device,
254 NULL);
255
256 scheduler->input = NULL;
257 pcmk_reset_scheduler(scheduler);
258 }