This source file includes following definitions.
- free_rsc_info
- free_deletion_op
- free_recurring_op
- fail_pending_op
- lrm_state_is_local
- lrm_state_create
- lrm_state_destroy
- remote_proxy_remove_by_node
- internal_lrm_state_destroy
- lrm_state_reset_tables
- lrm_state_init_local
- lrm_state_destroy_all
- lrm_state_find
- lrm_state_find_or_create
- lrm_state_get_list
- find_connected_proxy_by_node
- remote_proxy_disconnect_by_node
- lrm_state_disconnect_only
- lrm_state_disconnect
- lrm_state_is_connected
- lrm_state_poke_connection
- lrm_state_ipc_connect
- crmd_remote_proxy_new
- crmd_is_proxy_session
- crmd_proxy_send
- crmd_proxy_dispatch
- remote_config_check
- crmd_remote_proxy_cb
- lrm_state_remote_connect_async
- lrm_state_get_metadata
- lrm_state_cancel
- lrm_state_get_rsc_info
- lrm_state_exec
- lrm_state_register_rsc
- lrm_state_unregister_rsc
- crmd_unpack_alerts
- crmd_alert_node_event
- crmd_alert_fencing_op
- crmd_alert_resource_op
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <crm_internal.h>
20 #include <crm/crm.h>
21 #include <crm/msg_xml.h>
22 #include <crm/common/iso8601.h>
23
24 #include <crmd.h>
25 #include <crmd_fsa.h>
26 #include <crmd_messages.h>
27 #include <crmd_callbacks.h>
28 #include <crmd_lrm.h>
29 #include <crmd_alerts.h>
30 #include <crm/pengine/rules.h>
31 #include <crm/pengine/rules_internal.h>
32 #include <crm/transition.h>
33 #include <crm/lrmd_alerts_internal.h>
34
35 GHashTable *lrm_state_table = NULL;
36 extern GHashTable *proxy_table;
37 int lrmd_internal_proxy_send(lrmd_t * lrmd, xmlNode *msg);
38 void lrmd_internal_set_proxy_callback(lrmd_t * lrmd, void *userdata, void (*callback)(lrmd_t *lrmd, void *userdata, xmlNode *msg));
39
40 static void
41 free_rsc_info(gpointer value)
42 {
43 lrmd_rsc_info_t *rsc_info = value;
44
45 lrmd_free_rsc_info(rsc_info);
46 }
47
48 static void
49 free_deletion_op(gpointer value)
50 {
51 struct pending_deletion_op_s *op = value;
52
53 free(op->rsc);
54 delete_ha_msg_input(op->input);
55 free(op);
56 }
57
58 static void
59 free_recurring_op(gpointer value)
60 {
61 struct recurring_op_s *op = (struct recurring_op_s *)value;
62
63 free(op->user_data);
64 free(op->rsc_id);
65 free(op->op_type);
66 free(op->op_key);
67 if (op->params) {
68 g_hash_table_destroy(op->params);
69 }
70 free(op);
71 }
72
73 static gboolean
74 fail_pending_op(gpointer key, gpointer value, gpointer user_data)
75 {
76 lrmd_event_data_t event = { 0, };
77 lrm_state_t *lrm_state = user_data;
78 struct recurring_op_s *op = (struct recurring_op_s *)value;
79
80 crm_trace("Pre-emptively failing %s_%s_%d on %s (call=%s, %s)",
81 op->rsc_id, op->op_type, op->interval,
82 lrm_state->node_name, (char*)key, op->user_data);
83
84 event.type = lrmd_event_exec_complete;
85 event.rsc_id = op->rsc_id;
86 event.op_type = op->op_type;
87 event.user_data = op->user_data;
88 event.timeout = 0;
89 event.interval = op->interval;
90 event.rc = PCMK_OCF_CONNECTION_DIED;
91 event.op_status = PCMK_LRM_OP_ERROR;
92 event.t_run = op->start_time;
93 event.t_rcchange = op->start_time;
94
95 event.call_id = op->call_id;
96 event.remote_nodename = lrm_state->node_name;
97 event.params = op->params;
98
99 process_lrm_event(lrm_state, &event, op);
100 return TRUE;
101 }
102
103 gboolean
104 lrm_state_is_local(lrm_state_t *lrm_state)
105 {
106 if (lrm_state == NULL || fsa_our_uname == NULL) {
107 return FALSE;
108 }
109
110 if (strcmp(lrm_state->node_name, fsa_our_uname) != 0) {
111 return FALSE;
112 }
113
114 return TRUE;
115
116 }
117
118 lrm_state_t *
119 lrm_state_create(const char *node_name)
120 {
121 lrm_state_t *state = NULL;
122
123 if (!node_name) {
124 crm_err("No node name given for lrm state object");
125 return NULL;
126 }
127
128 state = calloc(1, sizeof(lrm_state_t));
129 if (!state) {
130 return NULL;
131 }
132
133 state->node_name = strdup(node_name);
134
135 state->rsc_info_cache = g_hash_table_new_full(crm_str_hash,
136 g_str_equal, NULL, free_rsc_info);
137
138 state->deletion_ops = g_hash_table_new_full(crm_str_hash,
139 g_str_equal, g_hash_destroy_str, free_deletion_op);
140
141 state->pending_ops = g_hash_table_new_full(crm_str_hash,
142 g_str_equal, g_hash_destroy_str, free_recurring_op);
143
144 state->resource_history = g_hash_table_new_full(crm_str_hash,
145 g_str_equal, NULL, history_free);
146
147 state->metadata_cache = metadata_cache_new();
148
149 g_hash_table_insert(lrm_state_table, (char *)state->node_name, state);
150 return state;
151
152 }
153
154 void
155 lrm_state_destroy(const char *node_name)
156 {
157 g_hash_table_remove(lrm_state_table, node_name);
158 }
159
160 static gboolean
161 remote_proxy_remove_by_node(gpointer key, gpointer value, gpointer user_data)
162 {
163 remote_proxy_t *proxy = value;
164 const char *node_name = user_data;
165
166 if (safe_str_eq(node_name, proxy->node_name)) {
167 return TRUE;
168 }
169
170 return FALSE;
171 }
172
173 static void
174 internal_lrm_state_destroy(gpointer data)
175 {
176 lrm_state_t *lrm_state = data;
177
178 if (!lrm_state) {
179 return;
180 }
181
182 crm_trace("Destroying proxy table %s with %d members", lrm_state->node_name, g_hash_table_size(proxy_table));
183 g_hash_table_foreach_remove(proxy_table, remote_proxy_remove_by_node, (char *) lrm_state->node_name);
184 remote_ra_cleanup(lrm_state);
185 lrmd_api_delete(lrm_state->conn);
186
187 if (lrm_state->rsc_info_cache) {
188 crm_trace("Destroying rsc info cache with %d members", g_hash_table_size(lrm_state->rsc_info_cache));
189 g_hash_table_destroy(lrm_state->rsc_info_cache);
190 }
191 if (lrm_state->resource_history) {
192 crm_trace("Destroying history op cache with %d members", g_hash_table_size(lrm_state->resource_history));
193 g_hash_table_destroy(lrm_state->resource_history);
194 }
195 if (lrm_state->deletion_ops) {
196 crm_trace("Destroying deletion op cache with %d members", g_hash_table_size(lrm_state->deletion_ops));
197 g_hash_table_destroy(lrm_state->deletion_ops);
198 }
199 if (lrm_state->pending_ops) {
200 crm_trace("Destroying pending op cache with %d members", g_hash_table_size(lrm_state->pending_ops));
201 g_hash_table_destroy(lrm_state->pending_ops);
202 }
203 metadata_cache_free(lrm_state->metadata_cache);
204
205 free((char *)lrm_state->node_name);
206 free(lrm_state);
207 }
208
209 void
210 lrm_state_reset_tables(lrm_state_t * lrm_state, gboolean reset_metadata)
211 {
212 if (lrm_state->resource_history) {
213 crm_trace("Re-setting history op cache with %d members",
214 g_hash_table_size(lrm_state->resource_history));
215 g_hash_table_remove_all(lrm_state->resource_history);
216 }
217 if (lrm_state->deletion_ops) {
218 crm_trace("Re-setting deletion op cache with %d members",
219 g_hash_table_size(lrm_state->deletion_ops));
220 g_hash_table_remove_all(lrm_state->deletion_ops);
221 }
222 if (lrm_state->pending_ops) {
223 crm_trace("Re-setting pending op cache with %d members",
224 g_hash_table_size(lrm_state->pending_ops));
225 g_hash_table_remove_all(lrm_state->pending_ops);
226 }
227 if (lrm_state->rsc_info_cache) {
228 crm_trace("Re-setting rsc info cache with %d members",
229 g_hash_table_size(lrm_state->rsc_info_cache));
230 g_hash_table_remove_all(lrm_state->rsc_info_cache);
231 }
232 if (reset_metadata) {
233 metadata_cache_reset(lrm_state->metadata_cache);
234 }
235 }
236
237 gboolean
238 lrm_state_init_local(void)
239 {
240 if (lrm_state_table) {
241 return TRUE;
242 }
243
244 lrm_state_table =
245 g_hash_table_new_full(crm_strcase_hash, crm_strcase_equal, NULL, internal_lrm_state_destroy);
246 if (!lrm_state_table) {
247 return FALSE;
248 }
249
250 proxy_table =
251 g_hash_table_new_full(crm_strcase_hash, crm_strcase_equal, NULL, remote_proxy_free);
252 if (!proxy_table) {
253 g_hash_table_destroy(lrm_state_table);
254 lrm_state_table = NULL;
255 return FALSE;
256 }
257
258 return TRUE;
259 }
260
261 void
262 lrm_state_destroy_all(void)
263 {
264 if (lrm_state_table) {
265 crm_trace("Destroying state table with %d members", g_hash_table_size(lrm_state_table));
266 g_hash_table_destroy(lrm_state_table); lrm_state_table = NULL;
267 }
268 if(proxy_table) {
269 crm_trace("Destroying proxy table with %d members", g_hash_table_size(proxy_table));
270 g_hash_table_destroy(proxy_table); proxy_table = NULL;
271 }
272 }
273
274 lrm_state_t *
275 lrm_state_find(const char *node_name)
276 {
277 if (!node_name) {
278 return NULL;
279 }
280 return g_hash_table_lookup(lrm_state_table, node_name);
281 }
282
283 lrm_state_t *
284 lrm_state_find_or_create(const char *node_name)
285 {
286 lrm_state_t *lrm_state;
287
288 lrm_state = g_hash_table_lookup(lrm_state_table, node_name);
289 if (!lrm_state) {
290 lrm_state = lrm_state_create(node_name);
291 }
292
293 return lrm_state;
294 }
295
296 GList *
297 lrm_state_get_list(void)
298 {
299 return g_hash_table_get_values(lrm_state_table);
300 }
301
302 static remote_proxy_t *
303 find_connected_proxy_by_node(const char * node_name)
304 {
305 GHashTableIter gIter;
306 remote_proxy_t *proxy = NULL;
307
308 CRM_CHECK(proxy_table != NULL, return NULL);
309
310 g_hash_table_iter_init(&gIter, proxy_table);
311
312 while (g_hash_table_iter_next(&gIter, NULL, (gpointer *) &proxy)) {
313 if (proxy->source
314 && safe_str_eq(node_name, proxy->node_name)) {
315 return proxy;
316 }
317 }
318
319 return NULL;
320 }
321
322 static void
323 remote_proxy_disconnect_by_node(const char * node_name)
324 {
325 remote_proxy_t *proxy = NULL;
326
327 CRM_CHECK(proxy_table != NULL, return);
328
329 while ((proxy = find_connected_proxy_by_node(node_name)) != NULL) {
330
331
332
333 if (proxy->source) {
334 mainloop_del_ipc_client(proxy->source);
335 }
336 }
337
338 return;
339 }
340
341 void
342 lrm_state_disconnect_only(lrm_state_t * lrm_state)
343 {
344 int removed = 0;
345
346 if (!lrm_state->conn) {
347 return;
348 }
349 crm_trace("Disconnecting %s", lrm_state->node_name);
350
351 remote_proxy_disconnect_by_node(lrm_state->node_name);
352
353 ((lrmd_t *) lrm_state->conn)->cmds->disconnect(lrm_state->conn);
354
355 if (is_not_set(fsa_input_register, R_SHUTDOWN)) {
356 removed = g_hash_table_foreach_remove(lrm_state->pending_ops, fail_pending_op, lrm_state);
357 crm_trace("Synthesized %d operation failures for %s", removed, lrm_state->node_name);
358 }
359 }
360
361 void
362 lrm_state_disconnect(lrm_state_t * lrm_state)
363 {
364 if (!lrm_state->conn) {
365 return;
366 }
367
368 lrm_state_disconnect_only(lrm_state);
369
370 lrmd_api_delete(lrm_state->conn);
371 lrm_state->conn = NULL;
372 }
373
374 int
375 lrm_state_is_connected(lrm_state_t * lrm_state)
376 {
377 if (!lrm_state->conn) {
378 return FALSE;
379 }
380 return ((lrmd_t *) lrm_state->conn)->cmds->is_connected(lrm_state->conn);
381 }
382
383 int
384 lrm_state_poke_connection(lrm_state_t * lrm_state)
385 {
386
387 if (!lrm_state->conn) {
388 return -1;
389 }
390 return ((lrmd_t *) lrm_state->conn)->cmds->poke_connection(lrm_state->conn);
391 }
392
393 int
394 lrm_state_ipc_connect(lrm_state_t * lrm_state)
395 {
396 int ret;
397
398 if (!lrm_state->conn) {
399 lrm_state->conn = lrmd_api_new();
400 ((lrmd_t *) lrm_state->conn)->cmds->set_callback(lrm_state->conn, lrm_op_callback);
401 }
402
403 ret = ((lrmd_t *) lrm_state->conn)->cmds->connect(lrm_state->conn, CRM_SYSTEM_CRMD, NULL);
404
405 if (ret != pcmk_ok) {
406 lrm_state->num_lrm_register_fails++;
407 } else {
408 lrm_state->num_lrm_register_fails = 0;
409 }
410
411 return ret;
412 }
413
414 static remote_proxy_t *
415 crmd_remote_proxy_new(lrmd_t *lrmd, const char *node_name, const char *session_id, const char *channel)
416 {
417 static struct ipc_client_callbacks proxy_callbacks = {
418 .dispatch = remote_proxy_dispatch,
419 .destroy = remote_proxy_disconnected
420 };
421 remote_proxy_t *proxy = remote_proxy_new(lrmd, &proxy_callbacks, node_name,
422 session_id, channel);
423 return proxy;
424 }
425
426 gboolean
427 crmd_is_proxy_session(const char *session)
428 {
429 return g_hash_table_lookup(proxy_table, session) ? TRUE : FALSE;
430 }
431
432 void
433 crmd_proxy_send(const char *session, xmlNode *msg)
434 {
435 remote_proxy_t *proxy = g_hash_table_lookup(proxy_table, session);
436 lrm_state_t *lrm_state = NULL;
437
438 if (!proxy) {
439 return;
440 }
441 crm_log_xml_trace(msg, "to-proxy");
442 lrm_state = lrm_state_find(proxy->node_name);
443 if (lrm_state) {
444 crm_trace("Sending event to %.8s on %s", proxy->session_id, proxy->node_name);
445 remote_proxy_relay_event(proxy, msg);
446 }
447 }
448
449 static void
450 crmd_proxy_dispatch(const char *session, xmlNode *msg)
451 {
452
453 crm_log_xml_trace(msg, "CRMd-PROXY[inbound]");
454
455 crm_xml_add(msg, F_CRM_SYS_FROM, session);
456 if (crmd_authorize_message(msg, NULL, session)) {
457 route_message(C_IPC_MESSAGE, msg);
458 }
459
460 trigger_fsa(fsa_source);
461 }
462
463 static void
464 remote_config_check(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
465 {
466 if (rc != pcmk_ok) {
467 crm_err("Query resulted in an error: %s", pcmk_strerror(rc));
468
469 if (rc == -EACCES || rc == -pcmk_err_schema_validation) {
470 crm_err("The cluster is mis-configured - shutting down and staying down");
471 }
472
473 } else {
474 lrmd_t * lrmd = (lrmd_t *)user_data;
475 crm_time_t *now = crm_time_new(NULL);
476 GHashTable *config_hash = crm_str_table_new();
477
478 crm_debug("Call %d : Parsing CIB options", call_id);
479
480 unpack_instance_attributes(
481 output, output, XML_CIB_TAG_PROPSET, NULL, config_hash, CIB_OPTIONS_FIRST, FALSE, now);
482
483
484 remote_proxy_check(lrmd, config_hash);
485
486 g_hash_table_destroy(config_hash);
487 crm_time_free(now);
488 }
489 }
490
491 static void
492 crmd_remote_proxy_cb(lrmd_t *lrmd, void *userdata, xmlNode *msg)
493 {
494 lrm_state_t *lrm_state = userdata;
495 const char *session = crm_element_value(msg, F_LRMD_IPC_SESSION);
496 remote_proxy_t *proxy = g_hash_table_lookup(proxy_table, session);
497
498 const char *op = crm_element_value(msg, F_LRMD_IPC_OP);
499 if (safe_str_eq(op, LRMD_IPC_OP_NEW)) {
500 const char *channel = crm_element_value(msg, F_LRMD_IPC_IPC_SERVER);
501
502 proxy = crmd_remote_proxy_new(lrmd, lrm_state->node_name, session, channel);
503 if (proxy != NULL) {
504
505 int rc = fsa_cib_conn->cmds->query(fsa_cib_conn, XML_CIB_TAG_CRMCONFIG, NULL, cib_scope_local);
506 fsa_cib_conn->cmds->register_callback_full(fsa_cib_conn, rc, 10, FALSE, lrmd,
507 "remote_config_check", remote_config_check, NULL);
508 }
509
510 } else if (safe_str_eq(op, LRMD_IPC_OP_SHUTDOWN_REQ)) {
511 char *now_s = NULL;
512 time_t now = time(NULL);
513
514 crm_notice("%s requested shutdown of its remote connection",
515 lrm_state->node_name);
516
517 if (!remote_ra_is_in_maintenance(lrm_state)) {
518 now_s = crm_itoa(now);
519 update_attrd(lrm_state->node_name, XML_CIB_ATTR_SHUTDOWN, now_s, NULL, TRUE);
520 free(now_s);
521
522 remote_proxy_ack_shutdown(lrmd);
523
524 crm_warn("Reconnection attempts to %s may result in failures that must be cleared",
525 lrm_state->node_name);
526 } else {
527 remote_proxy_nack_shutdown(lrmd);
528
529 crm_notice("Remote resource for %s is not managed so no ordered shutdown happening",
530 lrm_state->node_name);
531 }
532 return;
533
534 } else if (safe_str_eq(op, LRMD_IPC_OP_REQUEST) && proxy && proxy->is_local) {
535
536
537
538
539 int flags = 0;
540 xmlNode *request = get_message_xml(msg, F_LRMD_IPC_MSG);
541
542 CRM_CHECK(request != NULL, return);
543 #if ENABLE_ACL
544 CRM_CHECK(lrm_state->node_name, return);
545 crm_xml_add(request, XML_ACL_TAG_ROLE, "pacemaker-remote");
546 crm_acl_get_set_user(request, F_LRMD_IPC_USER, lrm_state->node_name);
547 #endif
548 crmd_proxy_dispatch(session, request);
549
550 crm_element_value_int(msg, F_LRMD_IPC_MSG_FLAGS, &flags);
551 if (flags & crm_ipc_client_response) {
552 int msg_id = 0;
553 xmlNode *op_reply = create_xml_node(NULL, "ack");
554
555 crm_xml_add(op_reply, "function", __FUNCTION__);
556 crm_xml_add_int(op_reply, "line", __LINE__);
557
558 crm_element_value_int(msg, F_LRMD_IPC_MSG_ID, &msg_id);
559 remote_proxy_relay_response(proxy, op_reply, msg_id);
560
561 free_xml(op_reply);
562 }
563
564 } else {
565 remote_proxy_cb(lrmd, lrm_state->node_name, msg);
566 }
567 }
568
569
570 int
571 lrm_state_remote_connect_async(lrm_state_t * lrm_state, const char *server, int port,
572 int timeout_ms)
573 {
574 int ret;
575
576 if (!lrm_state->conn) {
577 lrm_state->conn = lrmd_remote_api_new(lrm_state->node_name, server, port);
578 if (!lrm_state->conn) {
579 return -1;
580 }
581 ((lrmd_t *) lrm_state->conn)->cmds->set_callback(lrm_state->conn, remote_lrm_op_callback);
582 lrmd_internal_set_proxy_callback(lrm_state->conn, lrm_state, crmd_remote_proxy_cb);
583 }
584
585 crm_trace("initiating remote connection to %s at %d with timeout %d", server, port, timeout_ms);
586 ret =
587 ((lrmd_t *) lrm_state->conn)->cmds->connect_async(lrm_state->conn, lrm_state->node_name,
588 timeout_ms);
589
590 if (ret != pcmk_ok) {
591 lrm_state->num_lrm_register_fails++;
592 } else {
593 lrm_state->num_lrm_register_fails = 0;
594 }
595
596 return ret;
597 }
598
599 int
600 lrm_state_get_metadata(lrm_state_t * lrm_state,
601 const char *class,
602 const char *provider,
603 const char *agent, char **output, enum lrmd_call_options options)
604 {
605 if (!lrm_state->conn) {
606 return -ENOTCONN;
607 }
608 return ((lrmd_t *) lrm_state->conn)->cmds->get_metadata(lrm_state->conn, class, provider, agent,
609 output, options);
610 }
611
612 int
613 lrm_state_cancel(lrm_state_t * lrm_state, const char *rsc_id, const char *action, int interval)
614 {
615 if (!lrm_state->conn) {
616 return -ENOTCONN;
617 }
618
619
620
621 if (is_remote_lrmd_ra(NULL, NULL, rsc_id)) {
622 return remote_ra_cancel(lrm_state, rsc_id, action, interval);
623 }
624 return ((lrmd_t *) lrm_state->conn)->cmds->cancel(lrm_state->conn, rsc_id, action, interval);
625 }
626
627 lrmd_rsc_info_t *
628 lrm_state_get_rsc_info(lrm_state_t * lrm_state, const char *rsc_id, enum lrmd_call_options options)
629 {
630 lrmd_rsc_info_t *rsc = NULL;
631
632 if (!lrm_state->conn) {
633 return NULL;
634 }
635 if (is_remote_lrmd_ra(NULL, NULL, rsc_id)) {
636 return remote_ra_get_rsc_info(lrm_state, rsc_id);
637 }
638
639 rsc = g_hash_table_lookup(lrm_state->rsc_info_cache, rsc_id);
640 if (rsc == NULL) {
641
642 rsc = ((lrmd_t *) lrm_state->conn)->cmds->get_rsc_info(lrm_state->conn, rsc_id, options);
643 if (rsc == NULL) {
644 return NULL;
645 }
646
647 g_hash_table_insert(lrm_state->rsc_info_cache, rsc->id, rsc);
648 }
649
650 return lrmd_copy_rsc_info(rsc);
651
652 }
653
654 int
655 lrm_state_exec(lrm_state_t * lrm_state, const char *rsc_id, const char *action, const char *userdata, int interval,
656 int timeout,
657 int start_delay,
658 lrmd_key_value_t * params)
659 {
660
661 if (!lrm_state->conn) {
662 lrmd_key_value_freeall(params);
663 return -ENOTCONN;
664 }
665
666 if (is_remote_lrmd_ra(NULL, NULL, rsc_id)) {
667 return remote_ra_exec(lrm_state,
668 rsc_id, action, userdata, interval, timeout, start_delay, params);
669 }
670
671 return ((lrmd_t *) lrm_state->conn)->cmds->exec(lrm_state->conn,
672 rsc_id,
673 action,
674 userdata,
675 interval,
676 timeout,
677 start_delay,
678 lrmd_opt_notify_changes_only, params);
679 }
680
681 int
682 lrm_state_register_rsc(lrm_state_t * lrm_state,
683 const char *rsc_id,
684 const char *class,
685 const char *provider, const char *agent, enum lrmd_call_options options)
686 {
687 if (!lrm_state->conn) {
688 return -ENOTCONN;
689 }
690
691
692
693
694
695 if (is_remote_lrmd_ra(agent, provider, NULL)) {
696 return lrm_state_find_or_create(rsc_id) ? pcmk_ok : -1;
697 }
698
699 return ((lrmd_t *) lrm_state->conn)->cmds->register_rsc(lrm_state->conn, rsc_id, class,
700 provider, agent, options);
701 }
702
703 int
704 lrm_state_unregister_rsc(lrm_state_t * lrm_state,
705 const char *rsc_id, enum lrmd_call_options options)
706 {
707 if (!lrm_state->conn) {
708 return -ENOTCONN;
709 }
710
711
712
713
714 if (is_remote_lrmd_ra(NULL, NULL, rsc_id)) {
715 lrm_state_destroy(rsc_id);
716 return pcmk_ok;
717 }
718
719 g_hash_table_remove(lrm_state->rsc_info_cache, rsc_id);
720
721 return ((lrmd_t *) lrm_state->conn)->cmds->unregister_rsc(lrm_state->conn, rsc_id, options);
722 }
723
724
725
726
727
728 static GListPtr crmd_alert_list = NULL;
729
730 void
731 crmd_unpack_alerts(xmlNode *alerts)
732 {
733 pe_free_alert_list(crmd_alert_list);
734 crmd_alert_list = pe_unpack_alerts(alerts);
735 }
736
737 void
738 crmd_alert_node_event(crm_node_t *node)
739 {
740 lrm_state_t *lrm_state;
741
742 if (crmd_alert_list == NULL) {
743 return;
744 }
745
746 lrm_state = lrm_state_find(fsa_our_uname);
747 if (lrm_state == NULL) {
748 return;
749 }
750
751 lrmd_send_node_alert((lrmd_t *) lrm_state->conn, crmd_alert_list,
752 node->uname, node->id, node->state);
753 }
754
755 void
756 crmd_alert_fencing_op(stonith_event_t * e)
757 {
758 char *desc;
759 lrm_state_t *lrm_state;
760
761 if (crmd_alert_list == NULL) {
762 return;
763 }
764
765 lrm_state = lrm_state_find(fsa_our_uname);
766 if (lrm_state == NULL) {
767 return;
768 }
769
770 desc = crm_strdup_printf("Operation %s of %s by %s for %s@%s: %s (ref=%s)",
771 e->action, e->target,
772 (e->executioner? e->executioner : "<no-one>"),
773 e->client_origin, e->origin,
774 pcmk_strerror(e->result), e->id);
775
776 lrmd_send_fencing_alert((lrmd_t *) lrm_state->conn, crmd_alert_list,
777 e->target, e->operation, desc, e->result);
778 free(desc);
779 }
780
781 void
782 crmd_alert_resource_op(const char *node, lrmd_event_data_t * op)
783 {
784 lrm_state_t *lrm_state;
785
786 if (crmd_alert_list == NULL) {
787 return;
788 }
789
790 lrm_state = lrm_state_find(fsa_our_uname);
791 if (lrm_state == NULL) {
792 return;
793 }
794
795 lrmd_send_resource_alert((lrmd_t *) lrm_state->conn, crmd_alert_list, node,
796 op);
797 }