69
71
} attr_hash_entry_t;
72
free_hash_entry(gpointer data)
74
attr_hash_entry_t *entry = data;
81
crm_free(entry->dampen);
82
crm_free(entry->section);
83
crm_free(entry->uuid);
84
crm_free(entry->value);
85
crm_free(entry->stored_value);
86
crm_free(entry->user);
90
73
void attrd_local_callback(xmlNode * msg);
91
74
gboolean attrd_timer_callback(void *user_data);
92
75
gboolean attrd_trigger_update(attr_hash_entry_t * hash_entry);
93
76
void attrd_perform_update(attr_hash_entry_t * hash_entry);
79
free_hash_entry(gpointer data)
81
attr_hash_entry_t *entry = data;
92
free(entry->stored_value);
98
attrd_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
100
crm_trace("Connection %p", c);
102
crm_info("Ignoring new client [%d] during shutdown", crm_ipcs_client_pid(c));
106
if (crm_client_new(c, uid, gid) == NULL) {
113
attrd_ipc_created(qb_ipcs_connection_t * c)
115
crm_trace("Connection %p", c);
118
/* Exit code means? */
120
attrd_ipc_dispatch(qb_ipcs_connection_t * c, void *data, size_t size)
124
crm_client_t *client = crm_client_get(c);
125
xmlNode *msg = crm_ipcs_recv(client, data, size, &id, &flags);
127
if (flags & crm_ipc_client_response) {
128
crm_trace("Ack'ing msg from %d (%p)", crm_ipcs_client_pid(c), c);
129
crm_ipcs_send_ack(client, id, "ack", __FUNCTION__, __LINE__);
133
crm_debug("No msg from %d (%p)", crm_ipcs_client_pid(c), c);
137
determine_request_user(client->user, msg, F_ATTRD_USER);
140
crm_trace("Processing msg from %d (%p)", crm_ipcs_client_pid(c), c);
141
crm_log_xml_trace(msg, __PRETTY_FUNCTION__);
143
attrd_local_callback(msg);
149
/* Error code means? */
151
attrd_ipc_closed(qb_ipcs_connection_t * c)
153
crm_client_t *client = crm_client_get(c);
155
crm_trace("Connection %p", c);
156
crm_client_destroy(client);
161
attrd_ipc_destroy(qb_ipcs_connection_t * c)
163
crm_trace("Connection %p", c);
166
struct qb_ipcs_service_handlers ipc_callbacks = {
167
.connection_accept = attrd_ipc_accept,
168
.connection_created = attrd_ipc_created,
169
.msg_process = attrd_ipc_dispatch,
170
.connection_closed = attrd_ipc_closed,
171
.connection_destroyed = attrd_ipc_destroy
96
175
attrd_shutdown(int nsig)
98
177
need_shutdown = TRUE;
145
attrd_ipc_callback(IPC_Channel * client, gpointer user_data)
149
attrd_client_t *curr_client = (attrd_client_t *) user_data;
150
gboolean stay_connected = TRUE;
152
crm_trace("Invoked: %s", curr_client->id);
154
while (IPC_ISRCONN(client)) {
155
if (client->ops->is_message_pending(client) == 0) {
159
msg = xmlfromIPC(client, MAX_IPC_DELAY);
167
determine_request_user(&curr_client->user, client, msg, F_ATTRD_USER);
170
crm_trace("Processing msg from %s", curr_client->id);
171
crm_log_xml_trace(msg, __PRETTY_FUNCTION__);
173
attrd_local_callback(msg);
178
if (client->ch_status != IPC_CONNECT) {
183
crm_trace("Processed %d messages", lpc);
184
if (client->ch_status != IPC_CONNECT) {
185
stay_connected = FALSE;
188
return stay_connected;
192
attrd_connection_destroy(gpointer user_data)
194
attrd_client_t *client = user_data;
196
/* cib_process_disconnect */
198
if (client == NULL) {
202
if (client->source != NULL) {
203
crm_trace("Deleting %s (%p) from mainloop", client->name, client->source);
204
G_main_del_IPC_Channel(client->source);
205
client->source = NULL;
208
crm_trace("Destroying %s (%p)", client->name, client);
209
crm_free(client->name);
210
crm_free(client->id);
211
crm_free(client->user);
213
crm_trace("Freed the cib client");
219
attrd_connect(IPC_Channel * channel, gpointer user_data)
221
attrd_client_t *new_client = NULL;
223
crm_trace("Connecting channel");
225
if (channel == NULL) {
226
crm_err("Channel was NULL");
229
} else if (channel->ch_status != IPC_CONNECT) {
230
crm_err("Channel was disconnected");
232
} else if (need_shutdown) {
233
crm_info("Ignoring connection request during shutdown");
237
crm_malloc0(new_client, sizeof(attrd_client_t));
238
new_client->channel = channel;
240
crm_trace("Created channel %p for channel %s", new_client, new_client->id);
242
/* channel->ops->set_recv_qlen(channel, 100); */
243
/* channel->ops->set_send_qlen(channel, 400); */
246
G_main_add_IPC_Channel(G_PRIORITY_DEFAULT, channel, FALSE, attrd_ipc_callback, new_client,
247
attrd_connection_destroy);
249
crm_trace("Client %s connected", new_client->id);
255
215
log_hash_entry(int level, attr_hash_entry_t * entry, const char *text)
257
do_crm_log(level, "%s", text);
258
do_crm_log(level, "Set: %s", entry->section);
259
do_crm_log(level, "Name: %s", entry->id);
260
do_crm_log(level, "Value: %s", entry->value);
261
do_crm_log(level, "Timeout: %s", entry->dampen);
217
do_crm_log(level, "%s: Set: %s, Name: %s, Value: %s, Timeout: %s",
218
text, entry->section, entry->id, entry->value, entry->dampen);
264
221
static attr_hash_entry_t *
278
235
if (hash_entry == NULL) {
279
236
/* create one and add it */
280
237
crm_info("Creating hash entry for %s", attr);
281
crm_malloc0(hash_entry, sizeof(attr_hash_entry_t));
282
hash_entry->id = crm_strdup(attr);
238
hash_entry = calloc(1, sizeof(attr_hash_entry_t));
239
hash_entry->id = strdup(attr);
284
241
g_hash_table_insert(attr_hash, hash_entry->id, hash_entry);
285
242
hash_entry = g_hash_table_lookup(attr_hash, attr);
297
254
if (value == NULL) {
298
255
value = XML_CIB_TAG_STATUS;
300
crm_free(hash_entry->section);
301
hash_entry->section = crm_strdup(value);
257
free(hash_entry->section);
258
hash_entry->section = strdup(value);
302
259
crm_trace("\t%s->section: %s", attr, value);
304
261
value = crm_element_value(msg, F_ATTRD_DAMPEN);
305
262
if (value != NULL) {
306
crm_free(hash_entry->dampen);
307
hash_entry->dampen = crm_strdup(value);
263
free(hash_entry->dampen);
264
hash_entry->dampen = strdup(value);
309
266
hash_entry->timeout = crm_get_msec(value);
310
267
crm_trace("\t%s->timeout: %s", attr, value);
313
crm_free(hash_entry->user);
270
free(hash_entry->user);
315
272
value = crm_element_value(msg, F_ATTRD_USER);
316
273
if (value != NULL) {
317
hash_entry->user = crm_strdup(value);
274
hash_entry->user = strdup(value);
318
275
crm_trace("\t%s->user: %s", attr, value);
386
343
const char *host = crm_element_value(xml, F_ATTRD_HOST);
387
344
const char *ignore = crm_element_value(xml, F_ATTRD_IGNORE_LOCALLY);
389
crm_xml_add_int(xml, F_SEQ, wrapper->id);
390
crm_xml_add(xml, F_ORIG, wrapper->sender.uname);
346
/* crm_xml_add_int(xml, F_SEQ, wrapper->id); */
347
crm_xml_add(xml, F_ORIG, from);
392
349
if (host != NULL && safe_str_eq(host, attrd_uname)) {
393
crm_notice("Update relayed from %s", wrapper->sender.uname);
350
crm_notice("Update relayed from %s", from);
394
351
attrd_local_callback(xml);
396
} else if (ignore == NULL || safe_str_neq(wrapper->sender.uname, attrd_uname)) {
397
crm_trace("%s message from %s", op, wrapper->sender.uname);
353
} else if (ignore == NULL || safe_str_neq(from, attrd_uname)) {
354
crm_trace("%s message from %s", op, from);
398
355
hash_entry = find_hash_entry(xml);
399
356
stop_attrd_timer(hash_entry);
400
357
attrd_perform_update(hash_entry);
410
367
attrd_ais_destroy(gpointer unused)
413
369
if (need_shutdown) {
414
370
/* we signed out, so this is expected */
415
crm_info("OpenAIS disconnection complete");
371
crm_info("Corosync disconnection complete");
419
crm_crit("Lost connection to OpenAIS service!");
375
crm_crit("Lost connection to Corosync service!");
420
376
if (mainloop != NULL && g_main_is_running(mainloop)) {
421
377
g_main_quit(mainloop);
424
exit(LSB_EXIT_GENERIC);
429
385
attrd_cib_connection_destroy(gpointer user_data)
387
cib_t *conn = user_data;
389
conn->cmds->signoff(conn); /* Ensure IPC is cleaned up */
431
391
if (need_shutdown) {
432
392
crm_info("Connection to the CIB terminated...");
435
395
/* eventually this will trigger a reconnect, not a shutdown */
436
396
crm_err("Connection to the CIB terminated...");
414
local_update_for_hash_entry(gpointer key, gpointer value, gpointer user_data)
416
attr_hash_entry_t *entry = value;
418
if (entry->timer_id == 0) {
419
crm_trace("Performing local-only update after replace for %s", entry->id);
420
attrd_perform_update(entry);
422
* just let the timer expire and attrd_timer_callback() will do the right thing
454
428
do_cib_replaced(const char *event, xmlNode * msg)
456
crm_info("Sending full refresh");
457
g_hash_table_foreach(attr_hash, update_for_hash_entry, NULL);
430
crm_info("Updating all attributes after %s event", event);
431
g_hash_table_foreach(attr_hash, local_update_for_hash_entry, NULL);
472
446
if (was_err == FALSE) {
473
enum cib_errors rc = cib_not_connected;
475
449
if (attempts < max_retry) {
476
450
crm_debug("CIB signon attempt %d", attempts);
477
451
rc = local_conn->cmds->signon(local_conn, T_ATTRD, cib_command);
480
if (rc != cib_ok && attempts > max_retry) {
481
crm_err("Signon to CIB failed: %s", cib_error2string(rc));
454
if (rc != pcmk_ok && attempts > max_retry) {
455
crm_err("Signon to CIB failed: %s", pcmk_strerror(rc));
484
} else if (rc != cib_ok) {
458
} else if (rc != pcmk_ok) {
502
crm_cluster_t cluster;
528
503
gboolean was_err = FALSE;
529
char *channel_name = crm_strdup(T_ATTRD);
504
qb_ipcs_connection_t *c = NULL;
505
qb_ipcs_service_t *ipcs = NULL;
531
crm_log_init(T_ATTRD, LOG_NOTICE, TRUE, FALSE, argc, argv);
507
crm_log_init(T_ATTRD, LOG_NOTICE, TRUE, FALSE, argc, argv, FALSE);
532
508
mainloop_add_signal(SIGTERM, attrd_shutdown);
534
510
while ((flag = getopt(argc, argv, OPTARGS)) != EOF) {
537
crm_bump_log_level();
513
crm_bump_log_level(argc, argv);
539
515
case 'h': /* Help message */
540
usage(T_ATTRD, LSB_EXIT_OK);
516
usage(T_ATTRD, EX_OK);
558
534
crm_info("Starting up");
560
536
if (was_err == FALSE) {
561
void *destroy = NULL;
562
void *dispatch = NULL;
565
538
#if SUPPORT_COROSYNC
566
539
if (is_openais_cluster()) {
567
destroy = attrd_ais_destroy;
568
dispatch = attrd_ais_dispatch;
540
cluster.destroy = attrd_ais_destroy;
541
cluster.cs_dispatch = attrd_ais_dispatch;
572
545
#if SUPPORT_HEARTBEAT
573
546
if (is_heartbeat_cluster()) {
574
data = &attrd_cluster_conn;
575
dispatch = attrd_ha_callback;
576
destroy = attrd_ha_connection_destroy;
547
cluster.hb_conn = NULL;
548
cluster.hb_dispatch = attrd_ha_callback;
549
cluster.destroy = attrd_ha_connection_destroy;
580
if (FALSE == crm_cluster_connect(&attrd_uname, &attrd_uuid, dispatch, destroy, data)) {
553
if (FALSE == crm_cluster_connect(&cluster)) {
581
554
crm_err("HA Signon failed");
558
attrd_uname = cluster.uname;
559
attrd_uuid = cluster.uuid;
560
#if SUPPORT_HEARTBEAT
561
attrd_cluster_conn = cluster.hb_conn;
586
565
crm_info("Cluster connection active");
588
567
if (was_err == FALSE) {
589
int rc = init_server_ipc_comms(channel_name, attrd_connect,
590
default_ipc_connection_destroy);
593
crm_err("Could not start IPC server");
568
attrd_ipc_server_init(&ipcs, &ipc_callbacks);
598
571
crm_info("Accepting attribute updates");
596
c = qb_ipcs_connection_first_get(ipcs);
598
qb_ipcs_connection_t *last = c;
600
c = qb_ipcs_connection_next_get(ipcs, last);
602
/* There really shouldn't be anyone connected at this point */
603
crm_notice("Disconnecting client %p, pid=%d...", last, crm_ipcs_client_pid(last));
604
qb_ipcs_disconnect(last);
605
qb_ipcs_connection_unref(last);
608
qb_ipcs_destroy(ipcs);
624
611
cib_conn->cmds->signoff(cib_conn);
625
612
cib_delete(cib_conn);
628
615
g_hash_table_destroy(attr_hash);
629
crm_free(channel_name);
630
crm_free(attrd_uuid);
631
617
empty_uuid_cache();
636
622
struct attrd_callback_s {
644
630
attr_hash_entry_t *hash_entry = NULL;
645
631
struct attrd_callback_s *data = user_data;
647
if (data->value == NULL && rc == cib_NOTEXISTS) {
633
if (data->value == NULL && rc == -ENXIO) {
636
} else if (call_id < 0) {
637
crm_warn("Update %s=%s failed: %s", data->attr, data->value, pcmk_strerror(call_id));
653
643
crm_debug("Update %d for %s=%s passed", call_id, data->attr, data->value);
654
644
hash_entry = g_hash_table_lookup(attr_hash, data->attr);
656
646
if (hash_entry) {
657
crm_free(hash_entry->stored_value);
647
free(hash_entry->stored_value);
658
648
hash_entry->stored_value = NULL;
659
649
if (data->value != NULL) {
660
hash_entry->stored_value = crm_strdup(data->value);
650
hash_entry->stored_value = strdup(data->value);
664
case cib_diff_failed: /* When an attr changes while the CIB is syncing */
665
case cib_remote_timeout: /* When an attr changes while there is a DC election */
666
case cib_NOTEXISTS: /* When an attr changes while the CIB is syncing a
654
case -pcmk_err_diff_failed: /* When an attr changes while the CIB is syncing */
655
case -ETIME: /* When an attr changes while there is a DC election */
656
case -ENXIO: /* When an attr changes while the CIB is syncing a
667
657
* newer config from a node that just came up
669
659
crm_warn("Update %d for %s=%s failed: %s",
670
call_id, data->attr, data->value, cib_error2string(rc));
660
call_id, data->attr, data->value, pcmk_strerror(rc));
673
663
crm_err("Update %d for %s=%s failed: %s",
674
call_id, data->attr, data->value, cib_error2string(rc));
664
call_id, data->attr, data->value, pcmk_strerror(rc));
677
crm_free(data->value);
678
crm_free(data->attr);
683
673
attrd_perform_update(attr_hash_entry_t * hash_entry)
686
676
struct attrd_callback_s *data = NULL;
687
677
const char *user_name = NULL;
708
698
hash_entry->set, hash_entry->uuid, hash_entry->id, NULL, FALSE,
711
if (hash_entry->stored_value) {
701
if (rc >= 0 && hash_entry->stored_value) {
712
702
crm_notice("Sent delete %d: node=%s, attr=%s, id=%s, set=%s, section=%s",
713
703
rc, attrd_uuid, hash_entry->id,
714
704
hash_entry->uuid ? hash_entry->uuid : "<n/a>", hash_entry->set,
715
705
hash_entry->section);
717
} else if (rc < 0 && rc != cib_NOTEXISTS) {
707
} else if (rc < 0 && rc != -ENXIO) {
719
709
("Delete operation failed: node=%s, attr=%s, id=%s, set=%s, section=%s: %s (%d)",
720
710
attrd_uuid, hash_entry->id, hash_entry->uuid ? hash_entry->uuid : "<n/a>",
721
hash_entry->set, hash_entry->section, cib_error2string(rc), rc);
711
hash_entry->set, hash_entry->section, pcmk_strerror(rc), rc);
724
714
crm_trace("Sent delete %d: node=%s, attr=%s, id=%s, set=%s, section=%s",
725
rc, attrd_uuid, hash_entry->id,
726
hash_entry->uuid ? hash_entry->uuid : "<n/a>", hash_entry->set,
727
hash_entry->section);
715
rc, attrd_uuid, hash_entry->id,
716
hash_entry->uuid ? hash_entry->uuid : "<n/a>", hash_entry->set,
717
hash_entry->section);
732
722
rc = update_attr_delegate(cib_conn, cib_none, hash_entry->section,
733
723
attrd_uuid, NULL, hash_entry->set, hash_entry->uuid,
734
724
hash_entry->id, hash_entry->value, FALSE, user_name);
726
crm_notice("Sent update %s=%s failed: %s", hash_entry->id, hash_entry->value,
735
729
if (safe_str_neq(hash_entry->value, hash_entry->stored_value) || rc < 0) {
736
730
crm_notice("Sent update %d: %s=%s", rc, hash_entry->id, hash_entry->value);
742
crm_malloc0(data, sizeof(struct attrd_callback_s));
743
data->attr = crm_strdup(hash_entry->id);
736
data = calloc(1, sizeof(struct attrd_callback_s));
737
data->attr = strdup(hash_entry->id);
744
738
if (hash_entry->value != NULL) {
745
data->value = crm_strdup(hash_entry->value);
739
data->value = strdup(hash_entry->value);
747
add_cib_op_callback(cib_conn, rc, FALSE, data, attrd_cib_callback);
741
cib_conn->cmds->register_callback(cib_conn, rc, 120, FALSE, data, "attrd_cib_callback",