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