~ubuntu-branches/ubuntu/utopic/pacemaker/utopic-proposed

« back to all changes in this revision

Viewing changes to lib/cluster/legacy.c

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2013-08-15 11:27:07 UTC
  • mfrom: (1.1.12) (2.1.24 sid)
  • Revision ID: package-import@ubuntu.com-20130815112707-5r864ink7jme3zl5
Tags: 1.1.10+git20130802-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - debian/control: Build-Depends on libqb-dev; Depends on libheartbeat2.
* Corosync's pacemaker plugin is disabled, hence not built:
  - debian/licrmcluster4-dev.install: Do not install plugin.h.
  - debian/pacemaker.install: Do not install pacemaker.lcrso.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#  include <corosync/corodefs.h>
32
32
#  include <corosync/cpg.h>
33
33
#  include <corosync/cfg.h>
34
 
cpg_handle_t pcmk_cpg_handle = 0;
35
 
 
36
 
struct cpg_name pcmk_cpg_group = {
37
 
    .length = 0,
38
 
    .value[0] = 0,
39
 
};
40
34
#endif
41
35
 
42
36
#if HAVE_CMAP
48
42
cman_handle_t pcmk_cman_handle = NULL;
49
43
#endif
50
44
 
51
 
static char *pcmk_uname = NULL;
52
 
static int pcmk_uname_len = 0;
53
 
static uint32_t pcmk_nodeid = 0;
54
45
int ais_membership_timer = 0;
55
46
gboolean ais_membership_force = FALSE;
56
 
int ais_dispatch(gpointer user_data);
57
 
 
58
 
#define cs_repeat(counter, max, code) do {              \
59
 
        code;                                           \
60
 
        if(rc == CS_ERR_TRY_AGAIN || rc == CS_ERR_QUEUE_FULL) {  \
61
 
            counter++;                                  \
62
 
            crm_debug("Retrying operation after %ds", counter); \
63
 
            sleep(counter);                             \
64
 
        } else {                                        \
65
 
            break;                                      \
66
 
        }                                               \
67
 
    } while(counter < max)
68
 
 
69
 
enum crm_ais_msg_types
70
 
text2msg_type(const char *text)
71
 
{
72
 
    int type = crm_msg_none;
73
 
 
74
 
    CRM_CHECK(text != NULL, return type);
75
 
    if (safe_str_eq(text, "ais")) {
76
 
        type = crm_msg_ais;
77
 
    } else if (safe_str_eq(text, "crm_plugin")) {
78
 
        type = crm_msg_ais;
79
 
    } else if (safe_str_eq(text, CRM_SYSTEM_CIB)) {
80
 
        type = crm_msg_cib;
81
 
    } else if (safe_str_eq(text, CRM_SYSTEM_CRMD)) {
82
 
        type = crm_msg_crmd;
83
 
    } else if (safe_str_eq(text, CRM_SYSTEM_DC)) {
84
 
        type = crm_msg_crmd;
85
 
    } else if (safe_str_eq(text, CRM_SYSTEM_TENGINE)) {
86
 
        type = crm_msg_te;
87
 
    } else if (safe_str_eq(text, CRM_SYSTEM_PENGINE)) {
88
 
        type = crm_msg_pe;
89
 
    } else if (safe_str_eq(text, CRM_SYSTEM_LRMD)) {
90
 
        type = crm_msg_lrmd;
91
 
    } else if (safe_str_eq(text, CRM_SYSTEM_STONITHD)) {
92
 
        type = crm_msg_stonithd;
93
 
    } else if (safe_str_eq(text, "stonith-ng")) {
94
 
        type = crm_msg_stonith_ng;
95
 
    } else if (safe_str_eq(text, "attrd")) {
96
 
        type = crm_msg_attrd;
97
 
 
98
 
    } else {
99
 
        /* This will normally be a transient client rather than
100
 
         * a cluster daemon.  Set the type to the pid of the client
101
 
         */
102
 
        int scan_rc = sscanf(text, "%d", &type);
103
 
 
104
 
        if (scan_rc != 1 || type <= crm_msg_stonith_ng) {
105
 
            /* Ensure its sane */
106
 
            type = crm_msg_none;
107
 
        }
108
 
    }
109
 
    return type;
110
 
}
111
 
 
112
 
char *
113
 
get_ais_data(const AIS_Message * msg)
114
 
{
115
 
    int rc = BZ_OK;
116
 
    char *uncompressed = NULL;
117
 
    unsigned int new_size = msg->size + 1;
118
 
 
119
 
    if (msg->is_compressed == FALSE) {
120
 
        crm_trace("Returning uncompressed message data");
121
 
        uncompressed = strdup(msg->data);
122
 
 
123
 
    } else {
124
 
        crm_trace("Decompressing message data");
125
 
        uncompressed = calloc(1, new_size);
126
 
 
127
 
        rc = BZ2_bzBuffToBuffDecompress(uncompressed, &new_size, (char *)msg->data,
128
 
                                        msg->compressed_size, 1, 0);
129
 
 
130
 
        CRM_ASSERT(rc == BZ_OK);
131
 
        CRM_ASSERT(new_size == msg->size);
132
 
    }
133
 
 
134
 
    return uncompressed;
135
 
}
136
 
 
137
 
#if SUPPORT_COROSYNC
 
47
int plugin_dispatch(gpointer user_data);
 
48
 
138
49
int ais_fd_sync = -1;
139
50
int ais_fd_async = -1;          /* never send messages via this channel */
140
51
void *ais_ipc_ctx = NULL;
141
52
 
142
53
hdb_handle_t ais_ipc_handle = 0;
143
 
static char *ais_cluster_name = NULL;
144
54
 
145
 
gboolean
146
 
get_ais_nodeid(uint32_t * id, char **uname)
 
55
static gboolean
 
56
plugin_get_details(uint32_t * id, char **uname)
147
57
{
148
58
    struct iovec iov;
149
59
    int retries = 0;
151
61
    cs_ipc_header_response_t header;
152
62
    struct crm_ais_nodeid_resp_s answer;
153
63
 
 
64
    static uint32_t local_id = 0;
 
65
    static char *local_uname = NULL;
 
66
 
 
67
    if(local_id) {
 
68
        if(id) *id = local_id;
 
69
        if(uname) *uname = strdup(local_uname);
 
70
        return TRUE;
 
71
    }
 
72
 
154
73
    header.error = CS_OK;
155
74
    header.id = crm_class_nodeid;
156
75
    header.size = sizeof(cs_ipc_header_response_t);
157
76
 
158
 
    CRM_CHECK(id != NULL, return FALSE);
159
 
    CRM_CHECK(uname != NULL, return FALSE);
160
 
 
161
77
    iov.iov_base = &header;
162
78
    iov.iov_len = header.size;
163
79
 
190
106
 
191
107
    crm_info("Server details: id=%u uname=%s cname=%s", answer.id, answer.uname, answer.cname);
192
108
 
193
 
    *id = answer.id;
194
 
    *uname = strdup(answer.uname);
195
 
    ais_cluster_name = strdup(answer.cname);
 
109
    local_id = answer.id;
 
110
    local_uname = strdup(answer.uname);
196
111
 
 
112
    if(id) *id = local_id;
 
113
    if(uname) *uname = strdup(local_uname);
197
114
    return TRUE;
198
115
}
199
116
 
200
 
gboolean
201
 
crm_get_cluster_name(char **cname)
202
 
{
203
 
    CRM_CHECK(cname != NULL, return FALSE);
204
 
    if (ais_cluster_name) {
205
 
        *cname = strdup(ais_cluster_name);
206
 
        return TRUE;
207
 
    }
208
 
    return FALSE;
209
 
}
210
 
 
211
 
gboolean
212
 
send_ais_text(int class, const char *data,
213
 
              gboolean local, crm_node_t * node, enum crm_ais_msg_types dest)
214
 
{
215
 
    static int msg_id = 0;
216
 
    static int local_pid = 0;
217
 
    enum cluster_type_e cluster_type = get_cluster_type();
218
 
 
 
117
bool
 
118
send_plugin_text(int class, struct iovec *iov)
 
119
{
 
120
    int rc = CS_OK;
219
121
    int retries = 0;
220
 
    int rc = CS_OK;
221
122
    int buf_len = sizeof(cs_ipc_header_response_t);
222
 
 
223
 
    char *buf = NULL;
224
 
    struct iovec iov;
225
 
    const char *transport = "pcmk";
226
 
    cs_ipc_header_response_t *header = NULL;
227
 
    AIS_Message *ais_msg = NULL;
228
 
    enum crm_ais_msg_types sender = text2msg_type(crm_system_name);
229
 
 
 
123
    char *buf = malloc(buf_len);
 
124
    AIS_Message *ais_msg = (AIS_Message*)iov[0].iov_base;
 
125
    cs_ipc_header_response_t *header = (cs_ipc_header_response_t *) buf;
 
126
 
 
127
    CRM_ASSERT(buf != NULL);
230
128
    /* There are only 6 handlers registered to crm_lib_service in plugin.c */
231
129
    CRM_CHECK(class < 6, crm_err("Invalid message class: %d", class);
232
130
              return FALSE);
233
131
 
234
 
    if (data == NULL) {
235
 
        data = "";
236
 
    }
237
 
 
238
 
    if (local_pid == 0) {
239
 
        local_pid = getpid();
240
 
    }
241
 
 
242
 
    if (sender == crm_msg_none) {
243
 
        sender = local_pid;
244
 
    }
245
 
 
246
 
    ais_msg = calloc(1, sizeof(AIS_Message));
247
 
 
248
 
    ais_msg->id = msg_id++;
249
 
    ais_msg->header.id = class;
250
 
    ais_msg->header.error = CS_OK;
251
 
 
252
 
    ais_msg->host.type = dest;
253
 
    ais_msg->host.local = local;
254
 
 
255
 
    if (node) {
256
 
        if (node->uname) {
257
 
            ais_msg->host.size = strlen(node->uname);
258
 
            memset(ais_msg->host.uname, 0, MAX_NAME);
259
 
            memcpy(ais_msg->host.uname, node->uname, ais_msg->host.size);
260
 
        }
261
 
        ais_msg->host.id = node->id;
262
 
    }
263
 
 
264
 
    ais_msg->sender.id = 0;
265
 
    ais_msg->sender.type = sender;
266
 
    ais_msg->sender.pid = local_pid;
267
 
    ais_msg->sender.size = pcmk_uname_len;
268
 
    memset(ais_msg->sender.uname, 0, MAX_NAME);
269
 
    memcpy(ais_msg->sender.uname, pcmk_uname, ais_msg->sender.size);
270
 
 
271
 
    ais_msg->size = 1 + strlen(data);
272
 
 
273
 
    if (ais_msg->size < CRM_BZ2_THRESHOLD) {
274
 
  failback:
275
 
        ais_msg = realloc(ais_msg, sizeof(AIS_Message) + ais_msg->size);
276
 
        memcpy(ais_msg->data, data, ais_msg->size);
277
 
 
278
 
    } else {
279
 
        char *compressed = NULL;
280
 
        char *uncompressed = strdup(data);
281
 
        unsigned int len = (ais_msg->size * 1.1) + 600; /* recomended size */
282
 
 
283
 
        crm_trace("Compressing message payload");
284
 
        compressed = malloc(len);
285
 
 
286
 
        rc = BZ2_bzBuffToBuffCompress(compressed, &len, uncompressed, ais_msg->size, CRM_BZ2_BLOCKS,
287
 
                                      0, CRM_BZ2_WORK);
288
 
 
289
 
        free(uncompressed);
290
 
 
291
 
        if (rc != BZ_OK) {
292
 
            crm_err("Compression failed: %d", rc);
293
 
            free(compressed);
294
 
            goto failback;
295
 
        }
296
 
 
297
 
        ais_msg = realloc(ais_msg, sizeof(AIS_Message) + len + 1);
298
 
        memcpy(ais_msg->data, compressed, len);
299
 
        ais_msg->data[len] = 0;
300
 
        free(compressed);
301
 
 
302
 
        ais_msg->is_compressed = TRUE;
303
 
        ais_msg->compressed_size = len;
304
 
 
305
 
        crm_trace("Compression details: %d -> %d", ais_msg->size, ais_data_len(ais_msg));
306
 
    }
307
 
 
308
 
    ais_msg->header.size = sizeof(AIS_Message) + ais_data_len(ais_msg);
309
 
 
310
 
    crm_trace("Sending%s message %d to %s.%s (data=%d, total=%d)",
311
 
              ais_msg->is_compressed ? " compressed" : "",
312
 
              ais_msg->id, ais_dest(&(ais_msg->host)), msg_type2text(dest),
313
 
              ais_data_len(ais_msg), ais_msg->header.size);
314
 
 
315
 
    iov.iov_base = ais_msg;
316
 
    iov.iov_len = ais_msg->header.size;
317
 
    buf = realloc(buf, buf_len);
318
 
 
319
132
    do {
320
133
        if (rc == CS_ERR_TRY_AGAIN || rc == CS_ERR_QUEUE_FULL) {
321
134
            retries++;
325
138
        }
326
139
 
327
140
        errno = 0;
328
 
        switch (cluster_type) {
329
 
            case pcmk_cluster_corosync:
330
 
                CRM_ASSERT(FALSE /*Not supported here */ );
331
 
                break;
332
 
 
333
 
            case pcmk_cluster_classic_ais:
334
 
                rc = coroipcc_msg_send_reply_receive(ais_ipc_handle, &iov, 1, buf, buf_len);
335
 
                header = (cs_ipc_header_response_t *) buf;
336
 
                if (rc == CS_OK) {
337
 
                    CRM_CHECK(header->size == sizeof(cs_ipc_header_response_t),
338
 
                              crm_err("Odd message: id=%d, size=%d, class=%d, error=%d",
339
 
                                      header->id, header->size, class, header->error));
340
 
 
341
 
                    CRM_ASSERT(buf_len >= header->size);
342
 
                    CRM_CHECK(header->id == CRM_MESSAGE_IPC_ACK,
343
 
                              crm_err("Bad response id (%d) for request (%d)", header->id,
344
 
                                      ais_msg->header.id));
345
 
                    CRM_CHECK(header->error == CS_OK, rc = header->error);
346
 
                }
347
 
                break;
348
 
 
349
 
            case pcmk_cluster_cman:
350
 
                transport = "cpg";
351
 
                CRM_CHECK(dest != crm_msg_ais, rc = CS_ERR_MESSAGE_ERROR;
352
 
                          goto bail);
353
 
                rc = cpg_mcast_joined(pcmk_cpg_handle, CPG_TYPE_AGREED, &iov, 1);
354
 
                if (rc == CS_ERR_TRY_AGAIN || rc == CS_ERR_QUEUE_FULL) {
355
 
                    cpg_flow_control_state_t fc_state = CPG_FLOW_CONTROL_DISABLED;
356
 
                    int rc2 = cpg_flow_control_state_get(pcmk_cpg_handle, &fc_state);
357
 
 
358
 
                    if (rc2 == CS_OK && fc_state == CPG_FLOW_CONTROL_ENABLED) {
359
 
                        crm_warn("Connection overloaded, cannot send messages");
360
 
                        goto bail;
361
 
 
362
 
                    } else if (rc2 != CS_OK) {
363
 
                        crm_warn("Could not determin the connection state: %s (%d)",
364
 
                                 ais_error2text(rc2), rc2);
365
 
                        goto bail;
366
 
                    }
367
 
                }
368
 
                break;
369
 
 
370
 
            case pcmk_cluster_unknown:
371
 
            case pcmk_cluster_invalid:
372
 
            case pcmk_cluster_heartbeat:
373
 
                CRM_ASSERT(is_openais_cluster());
374
 
                break;
375
 
        }
 
141
        rc = coroipcc_msg_send_reply_receive(ais_ipc_handle, iov, 1, buf, buf_len);
376
142
 
377
143
    } while ((rc == CS_ERR_TRY_AGAIN || rc == CS_ERR_QUEUE_FULL) && retries < 20);
378
144
 
379
 
  bail:
380
 
    if (rc != CS_OK) {
381
 
        crm_perror(LOG_ERR, "Sending message %d via %s: FAILED (rc=%d): %s",
382
 
                   ais_msg->id, transport, rc, ais_error2text(rc));
 
145
    if (rc == CS_OK) {
 
146
        CRM_CHECK(header->size == sizeof(cs_ipc_header_response_t),
 
147
                  crm_err("Odd message: id=%d, size=%d, class=%d, error=%d",
 
148
                          header->id, header->size, class, header->error));
 
149
 
 
150
        CRM_ASSERT(buf_len >= header->size);
 
151
        CRM_CHECK(header->id == CRM_MESSAGE_IPC_ACK,
 
152
                  crm_err("Bad response id (%d) for request (%d)", header->id,
 
153
                          ais_msg->header.id));
 
154
        CRM_CHECK(header->error == CS_OK, rc = header->error);
383
155
 
384
156
    } else {
385
 
        crm_trace("Message %d: sent", ais_msg->id);
 
157
        crm_perror(LOG_ERR, "Sending plugin message %d FAILED: %s (%d)",
 
158
                   ais_msg->id, ais_error2text(rc), rc);
386
159
    }
387
160
 
 
161
    free(iov[0].iov_base);
 
162
    free(iov);
388
163
    free(buf);
389
 
    free(ais_msg);
 
164
 
390
165
    return (rc == CS_OK);
391
166
}
392
167
 
393
 
gboolean
394
 
send_ais_message(xmlNode * msg, gboolean local, crm_node_t * node, enum crm_ais_msg_types dest)
395
 
{
396
 
    gboolean rc = TRUE;
397
 
    char *data = NULL;
398
 
 
399
 
    if (is_classic_ais_cluster()) {
400
 
        if (ais_fd_async < 0) {
401
 
            crm_err("Not connected to AIS: %d", ais_fd_async);
402
 
            return FALSE;
403
 
        }
404
 
    }
405
 
 
406
 
    data = dump_xml_unformatted(msg);
407
 
    rc = send_ais_text(crm_class_cluster, data, local, node, dest);
408
 
    free(data);
409
 
    return rc;
410
 
}
411
 
 
412
168
void
413
 
terminate_cs_connection(void)
 
169
terminate_cs_connection(crm_cluster_t *cluster)
414
170
{
415
171
    crm_notice("Disconnecting from Corosync");
416
172
 
422
178
        } else {
423
179
            crm_info("No plugin connection");
424
180
        }
425
 
 
426
 
    } else {
427
 
        if (pcmk_cpg_handle) {
428
 
            crm_info("Disconnecting CPG");
429
 
            if (cpg_leave(pcmk_cpg_handle, &pcmk_cpg_group) == CS_OK) {
430
 
                cpg_finalize(pcmk_cpg_handle);
431
 
            }
432
 
            pcmk_cpg_handle = 0;
433
 
 
434
 
        } else {
435
 
            crm_info("No CPG connection");
436
 
        }
437
181
    }
 
182
    cluster_disconnect_cpg(cluster);
438
183
 
439
184
#  if SUPPORT_CMAN
440
185
    if (is_cman_cluster()) {
441
186
        if (pcmk_cman_handle) {
442
187
            crm_info("Disconnecting cman");
443
188
            if (cman_stop_notification(pcmk_cman_handle) >= 0) {
 
189
                crm_info("Destroying cman");
444
190
                cman_finish(pcmk_cman_handle);
445
191
            }
446
192
 
453
199
    ais_fd_sync = -1;
454
200
}
455
201
 
456
 
static crm_node_t *
457
 
crm_update_ais_node(xmlNode * member, long long seq)
 
202
void
 
203
plugin_handle_membership(AIS_Message *msg)
458
204
{
459
 
    const char *id_s = crm_element_value(member, "id");
460
 
    const char *addr = crm_element_value(member, "addr");
461
 
    const char *uname = crm_element_value(member, "uname");
462
 
    const char *state = crm_element_value(member, "state");
463
 
    const char *born_s = crm_element_value(member, "born");
464
 
    const char *seen_s = crm_element_value(member, "seen");
465
 
    const char *votes_s = crm_element_value(member, "votes");
466
 
    const char *procs_s = crm_element_value(member, "processes");
467
 
 
468
 
    int votes = crm_int_helper(votes_s, NULL);
469
 
    unsigned int id = crm_int_helper(id_s, NULL);
470
 
    unsigned int procs = crm_int_helper(procs_s, NULL);
471
 
 
472
 
    /* TODO: These values will contain garbage if version < 0.7.1 */
473
 
    uint64_t born = crm_int_helper(born_s, NULL);
474
 
    uint64_t seen = crm_int_helper(seen_s, NULL);
475
 
 
476
 
    return crm_update_peer(__FUNCTION__, id, born, seen, votes, procs, uname, uname, addr, state);
 
205
    if (msg->header.id == crm_class_members || msg->header.id == crm_class_quorum) {
 
206
        xmlNode *member = NULL;
 
207
        const char *value = NULL;
 
208
        gboolean quorate = FALSE;
 
209
        xmlNode *xml = string2xml(msg->data);
 
210
 
 
211
        if (xml == NULL) {
 
212
            crm_err("Invalid membership update: %s", msg->data);
 
213
            return;
 
214
        }
 
215
 
 
216
        value = crm_element_value(xml, "quorate");
 
217
        CRM_CHECK(value != NULL, crm_log_xml_err(xml, "No quorum value:"); return);
 
218
        if (crm_is_true(value)) {
 
219
            quorate = TRUE;
 
220
        }
 
221
 
 
222
        value = crm_element_value(xml, "id");
 
223
        CRM_CHECK(value != NULL, crm_log_xml_err(xml, "No membership id"); return);
 
224
        crm_peer_seq = crm_int_helper(value, NULL);
 
225
 
 
226
        if (quorate != crm_have_quorum) {
 
227
            crm_notice("Membership %s: quorum %s", value, quorate ? "acquired" : "lost");
 
228
            crm_have_quorum = quorate;
 
229
 
 
230
        } else {
 
231
            crm_info("Membership %s: quorum %s", value, quorate ? "retained" : "still lost");
 
232
        }
 
233
 
 
234
        for (member = __xml_first_child(xml); member != NULL; member = __xml_next(member)) {
 
235
            const char *id_s = crm_element_value(member, "id");
 
236
            const char *addr = crm_element_value(member, "addr");
 
237
            const char *uname = crm_element_value(member, "uname");
 
238
            const char *state = crm_element_value(member, "state");
 
239
            const char *born_s = crm_element_value(member, "born");
 
240
            const char *seen_s = crm_element_value(member, "seen");
 
241
            const char *votes_s = crm_element_value(member, "votes");
 
242
            const char *procs_s = crm_element_value(member, "processes");
 
243
 
 
244
            int votes = crm_int_helper(votes_s, NULL);
 
245
            unsigned int id = crm_int_helper(id_s, NULL);
 
246
            unsigned int procs = crm_int_helper(procs_s, NULL);
 
247
 
 
248
            /* TODO: These values will contain garbage if version < 0.7.1 */
 
249
            uint64_t born = crm_int_helper(born_s, NULL);
 
250
            uint64_t seen = crm_int_helper(seen_s, NULL);
 
251
 
 
252
            crm_update_peer(__FUNCTION__, id, born, seen, votes, procs, uname, uname, addr, state);
 
253
        }
 
254
        free_xml(xml);
 
255
    }
477
256
}
478
257
 
479
 
static gboolean
480
 
ais_dispatch_message(AIS_Message * msg,
481
 
                     gboolean(*dispatch) (int kind, const char *from, const char *data))
 
258
static void
 
259
plugin_default_deliver_message(cpg_handle_t handle,
 
260
                               const struct cpg_name *groupName,
 
261
                               uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len)
482
262
{
483
 
    char *data = NULL;
484
 
    char *uncompressed = NULL;
485
 
 
486
 
    xmlNode *xml = NULL;
487
 
 
488
 
    CRM_ASSERT(msg != NULL);
489
 
 
490
 
    crm_trace("Got new%s message (size=%d, %d, %d)",
491
 
              msg->is_compressed ? " compressed" : "",
492
 
              ais_data_len(msg), msg->size, msg->compressed_size);
493
 
 
494
 
    data = msg->data;
495
 
    if (msg->is_compressed && msg->size > 0) {
496
 
        int rc = BZ_OK;
497
 
        unsigned int new_size = msg->size + 1;
498
 
 
499
 
        if (check_message_sanity(msg, NULL) == FALSE) {
500
 
            goto badmsg;
501
 
        }
502
 
 
503
 
        crm_trace("Decompressing message data");
504
 
        uncompressed = calloc(1, new_size);
505
 
        rc = BZ2_bzBuffToBuffDecompress(uncompressed, &new_size, data, msg->compressed_size, 1, 0);
506
 
 
507
 
        if (rc != BZ_OK) {
508
 
            crm_err("Decompression failed: %d", rc);
509
 
            goto badmsg;
510
 
        }
511
 
 
512
 
        CRM_ASSERT(rc == BZ_OK);
513
 
        CRM_ASSERT(new_size == msg->size);
514
 
 
515
 
        data = uncompressed;
516
 
 
517
 
    } else if (check_message_sanity(msg, data) == FALSE) {
518
 
        goto badmsg;
519
 
 
520
 
    } else if (safe_str_eq("identify", data)) {
521
 
        int pid = getpid();
522
 
        char *pid_s = crm_itoa(pid);
523
 
 
524
 
        send_ais_text(crm_class_cluster, pid_s, TRUE, NULL, crm_msg_ais);
525
 
        free(pid_s);
526
 
        goto done;
527
 
    }
528
 
 
529
 
    if (msg->header.id != crm_class_members) {
530
 
        crm_get_peer(msg->sender.id, msg->sender.uname);
531
 
    }
532
 
 
533
 
    if (msg->header.id == crm_class_rmpeer) {
534
 
        uint32_t id = crm_int_helper(data, NULL);
535
 
 
536
 
        crm_info("Removing peer %s/%u", data, id);
537
 
        reap_crm_member(id, NULL);
538
 
        goto done;
539
 
 
540
 
    } else if (is_classic_ais_cluster()) {
541
 
        if (msg->header.id == crm_class_members || msg->header.id == crm_class_quorum) {
542
 
            xmlNode *node = NULL;
543
 
            const char *value = NULL;
544
 
            gboolean quorate = FALSE;
545
 
 
546
 
            xml = string2xml(data);
547
 
            if (xml == NULL) {
548
 
                crm_err("Invalid membership update: %s", data);
549
 
                goto badmsg;
550
 
            }
551
 
 
552
 
            value = crm_element_value(xml, "quorate");
553
 
            CRM_CHECK(value != NULL, crm_log_xml_err(xml, "No quorum value:");
554
 
                      goto badmsg);
555
 
            if (crm_is_true(value)) {
556
 
                quorate = TRUE;
557
 
            }
558
 
 
559
 
            value = crm_element_value(xml, "id");
560
 
            CRM_CHECK(value != NULL, crm_log_xml_err(xml, "No membership id");
561
 
                      goto badmsg);
562
 
            crm_peer_seq = crm_int_helper(value, NULL);
563
 
 
564
 
            if (quorate != crm_have_quorum) {
565
 
                crm_notice("Membership %s: quorum %s", value, quorate ? "acquired" : "lost");
566
 
                crm_have_quorum = quorate;
567
 
 
568
 
            } else {
569
 
                crm_info("Membership %s: quorum %s", value, quorate ? "retained" : "still lost");
570
 
            }
571
 
 
572
 
            for (node = __xml_first_child(xml); node != NULL; node = __xml_next(node)) {
573
 
                crm_update_ais_node(node, crm_peer_seq);
574
 
            }
575
 
        }
576
 
    }
577
 
 
578
 
    crm_trace("Payload: %s", data);
579
 
    if (dispatch != NULL) {
580
 
        dispatch(msg->header.id, msg->sender.uname, data);
581
 
    }
582
 
 
583
 
  done:
584
 
    free(uncompressed);
585
 
    free_xml(xml);
586
 
    return TRUE;
587
 
 
588
 
  badmsg:
589
 
    crm_err("Invalid message (id=%d, dest=%s:%s, from=%s:%s.%d):"
590
 
            " min=%d, total=%d, size=%d, bz2_size=%d",
591
 
            msg->id, ais_dest(&(msg->host)), msg_type2text(msg->host.type),
592
 
            ais_dest(&(msg->sender)), msg_type2text(msg->sender.type),
593
 
            msg->sender.pid, (int)sizeof(AIS_Message),
594
 
            msg->header.size, msg->size, msg->compressed_size);
595
 
    goto done;
 
263
    uint32_t kind = 0;
 
264
    const char *from = NULL;
 
265
    char *data = pcmk_message_common_cs(handle, nodeid, pid, msg, &kind, &from);
 
266
 
 
267
    free(data);
596
268
}
597
269
 
598
270
int
599
 
ais_dispatch(gpointer user_data)
 
271
plugin_dispatch(gpointer user_data)
600
272
{
601
273
    int rc = CS_OK;
602
 
    gboolean good = TRUE;
603
 
 
604
 
    gboolean(*dispatch) (int kind, const char *from, const char *data) = user_data;
 
274
    crm_cluster_t *cluster = (crm_cluster_t *) user_data;
605
275
 
606
276
    do {
607
277
        char *buffer = NULL;
618
288
            /* NULL is a legal "no message afterall" value */
619
289
            return 0;
620
290
        }
621
 
        good = ais_dispatch_message((AIS_Message *) buffer, dispatch);
 
291
        /*
 
292
        cpg_deliver_fn_t(cpg_handle_t handle, const struct cpg_name *group_name,
 
293
                         uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len);
 
294
        */
 
295
        if (cluster && cluster->cpg.cpg_deliver_fn) {
 
296
            cluster->cpg.cpg_deliver_fn(0, NULL, 0, 0, buffer, 0);
 
297
 
 
298
        } else {
 
299
            plugin_default_deliver_message(0, NULL, 0, 0, buffer, 0);
 
300
        }
 
301
 
622
302
        coroipcc_dispatch_put(ais_ipc_handle);
623
303
 
624
 
    } while (good && ais_ipc_handle);
625
 
 
626
 
    if (good) {
627
 
        return 0;
628
 
    }
629
 
 
630
 
    return -1;
 
304
    } while (ais_ipc_handle);
 
305
 
 
306
    return 0;
631
307
}
632
308
 
633
309
static void
634
 
ais_destroy(gpointer user_data)
 
310
plugin_destroy(gpointer user_data)
635
311
{
636
312
    crm_err("AIS connection terminated");
637
313
    ais_fd_sync = -1;
638
 
    crm_exit(1);
 
314
    crm_exit(ENOTCONN);
639
315
}
640
316
 
641
317
#  if SUPPORT_CMAN
692
368
            }
693
369
 
694
370
            for (lpc = 0; lpc < node_count; lpc++) {
 
371
                crm_node_t *peer = NULL;
 
372
 
695
373
                if (cman_nodes[lpc].cn_nodeid == 0) {
696
374
                    /* Never allow node ID 0 to be considered a member #315711 */
697
375
                    /* Skip entirely, its a qdisk */
698
376
                    continue;
699
377
                }
700
 
                crm_update_peer(__FUNCTION__, cman_nodes[lpc].cn_nodeid,
701
 
                                cman_nodes[lpc].cn_incarnation,
702
 
                                cman_nodes[lpc].cn_member ? crm_peer_seq : 0, 0, 0,
703
 
                                cman_nodes[lpc].cn_name, cman_nodes[lpc].cn_name, NULL,
704
 
                                cman_nodes[lpc].cn_member ? CRM_NODE_MEMBER : CRM_NODE_LOST);
 
378
 
 
379
                peer = crm_get_peer(cman_nodes[lpc].cn_nodeid, cman_nodes[lpc].cn_name);
 
380
                if(cman_nodes[lpc].cn_member) {
 
381
                    crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_MEMBER, crm_peer_seq);
 
382
 
 
383
                } else if(peer->state) {
 
384
                    crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_LOST, 0);
 
385
 
 
386
                } else {
 
387
                    crm_info("State of node %s[%u] is still unknown", peer->uname, peer->id);
 
388
                }
705
389
            }
706
390
 
707
391
            if (dispatch) {
744
428
        goto cman_bail;
745
429
    }
746
430
 
747
 
    rc = cman_get_cluster(pcmk_cman_handle, &cluster);
748
 
    if (rc < 0) {
749
 
        crm_err("Couldn't query cman cluster details: %d %d", rc, errno);
750
 
        goto cman_bail;
751
 
    }
752
 
    ais_cluster_name = strdup(cluster.ci_name);
753
 
 
754
431
    rc = cman_start_notification(pcmk_cman_handle, cman_event_callback);
755
432
    if (rc < 0) {
756
433
        crm_err("Couldn't register for cman notifications: %d %d", rc, errno);
772
449
    }
773
450
#  else
774
451
    crm_err("cman qorum is not supported in this build");
775
 
    crm_exit(100);
776
 
#  endif
777
 
    return TRUE;
778
 
}
779
 
 
780
 
#  ifdef SUPPORT_COROSYNC
781
 
gboolean(*pcmk_cpg_dispatch_fn) (int kind, const char *from, const char *data) = NULL;
782
 
static bool cpg_evicted = FALSE;
783
 
 
784
 
static int
785
 
pcmk_cpg_dispatch(gpointer user_data)
786
 
{
787
 
    int rc = 0;
788
 
 
789
 
    pcmk_cpg_dispatch_fn = user_data;
790
 
    rc = cpg_dispatch(pcmk_cpg_handle, CS_DISPATCH_ALL);
791
 
    if (rc != CS_OK) {
792
 
        crm_err("Connection to the CPG API failed: %d", rc);
793
 
        pcmk_cpg_handle = 0;
794
 
        return -1;
795
 
 
796
 
    } else if(cpg_evicted) {
797
 
        crm_err("Evicted from CPG membership");
798
 
        return -1;
799
 
    }
800
 
    return 0;
801
 
}
802
 
 
803
 
static void
804
 
pcmk_cpg_deliver(cpg_handle_t handle,
805
 
                 const struct cpg_name *groupName,
806
 
                 uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len)
807
 
{
808
 
    AIS_Message *ais_msg = (AIS_Message *) msg;
809
 
 
810
 
    if (ais_msg->sender.id > 0 && ais_msg->sender.id != nodeid) {
811
 
        crm_err("Nodeid mismatch from %d.%d: claimed nodeid=%u", nodeid, pid, ais_msg->sender.id);
812
 
        return;
813
 
 
814
 
    } else if (ais_msg->host.size != 0 && safe_str_neq(ais_msg->host.uname, pcmk_uname)) {
815
 
        /* Not for us */
816
 
        return;
817
 
    } else if (ais_msg->host.id != 0 && (pcmk_nodeid != ais_msg->host.id)) {
818
 
        /* Not for us */
819
 
        return;
820
 
    }
821
 
 
822
 
    ais_msg->sender.id = nodeid;
823
 
    if (ais_msg->sender.size == 0) {
824
 
        crm_node_t *peer = crm_get_peer(nodeid, NULL);
825
 
 
826
 
        if (peer == NULL) {
827
 
            crm_err("Peer with nodeid=%u is unknown", nodeid);
828
 
 
829
 
        } else if (peer->uname == NULL) {
830
 
            crm_err("No uname for peer with nodeid=%u", nodeid);
831
 
 
832
 
        } else {
833
 
            crm_notice("Fixing uname for peer with nodeid=%u", nodeid);
834
 
            ais_msg->sender.size = strlen(peer->uname);
835
 
            memset(ais_msg->sender.uname, 0, MAX_NAME);
836
 
            memcpy(ais_msg->sender.uname, peer->uname, ais_msg->sender.size);
837
 
        }
838
 
    }
839
 
 
840
 
    ais_dispatch_message(ais_msg, pcmk_cpg_dispatch_fn);
841
 
}
842
 
 
843
 
static void
844
 
pcmk_cpg_membership(cpg_handle_t handle,
845
 
                    const struct cpg_name *groupName,
846
 
                    const struct cpg_address *member_list, size_t member_list_entries,
847
 
                    const struct cpg_address *left_list, size_t left_list_entries,
848
 
                    const struct cpg_address *joined_list, size_t joined_list_entries)
849
 
{
850
 
    int i;
851
 
    gboolean found = FALSE;
852
 
    static int counter = 0;
853
 
 
854
 
    for (i = 0; i < left_list_entries; i++) {
855
 
        crm_node_t *peer = crm_get_peer(left_list[i].nodeid, NULL);
856
 
 
857
 
        crm_info("Left[%d.%d] %s.%u ", counter, i, groupName->value, left_list[i].nodeid);
858
 
        crm_update_peer_proc(__FUNCTION__, peer, crm_proc_cpg, OFFLINESTATUS);
859
 
    }
860
 
 
861
 
    for (i = 0; i < joined_list_entries; i++) {
862
 
        crm_info("Joined[%d.%d] %s.%u ", counter, i, groupName->value, joined_list[i].nodeid);
863
 
    }
864
 
 
865
 
    for (i = 0; i < member_list_entries; i++) {
866
 
        crm_node_t *peer = crm_get_peer(member_list[i].nodeid, NULL);
867
 
 
868
 
        crm_info("Member[%d.%d] %s.%u ", counter, i, groupName->value, member_list[i].nodeid);
869
 
        crm_update_peer_proc(__FUNCTION__, peer, crm_proc_cpg, ONLINESTATUS);
870
 
        if (pcmk_nodeid == member_list[i].nodeid) {
871
 
            found = TRUE;
872
 
        }
873
 
    }
874
 
 
875
 
    if (!found) {
876
 
        crm_err("We're not part of CPG group %s anymore!", groupName->value);
877
 
        cpg_evicted = TRUE;
878
 
    }
879
 
 
880
 
    counter++;
881
 
}
882
 
 
883
 
cpg_callbacks_t cpg_callbacks = {
884
 
    .cpg_deliver_fn = pcmk_cpg_deliver,
885
 
    .cpg_confchg_fn = pcmk_cpg_membership,
886
 
};
887
 
#  endif
888
 
 
889
 
static gboolean
890
 
init_cpg_connection(crm_cluster_t * cluster)
891
 
{
892
 
#  ifdef SUPPORT_COROSYNC
893
 
    int rc = -1;
894
 
    int fd = 0;
895
 
    int retries = 0;
896
 
    crm_node_t *peer = NULL;
897
 
 
898
 
    struct mainloop_fd_callbacks cpg_fd_callbacks = {
899
 
        .dispatch = pcmk_cpg_dispatch,
900
 
        .destroy = cluster->destroy,
901
 
    };
902
 
 
903
 
    cpg_evicted = FALSE;
904
 
    strcpy(pcmk_cpg_group.value, crm_system_name);
905
 
    pcmk_cpg_group.length = strlen(crm_system_name) + 1;
906
 
 
907
 
    cs_repeat(retries, 30, rc = cpg_initialize(&pcmk_cpg_handle, &cpg_callbacks));
908
 
    if (rc != CS_OK) {
909
 
        crm_err("Could not connect to the Cluster Process Group API: %d\n", rc);
910
 
        goto bail;
911
 
    }
912
 
 
913
 
    retries = 0;
914
 
    cs_repeat(retries, 30, rc = cpg_local_get(pcmk_cpg_handle, (unsigned int *)&cluster->nodeid));
915
 
    if (rc != CS_OK) {
916
 
        crm_err("Could not get local node id from the CPG API");
917
 
        goto bail;
918
 
    }
919
 
 
920
 
    retries = 0;
921
 
    cs_repeat(retries, 30, rc = cpg_join(pcmk_cpg_handle, &pcmk_cpg_group));
922
 
    if (rc != CS_OK) {
923
 
        crm_err("Could not join the CPG group '%s': %d", crm_system_name, rc);
924
 
        goto bail;
925
 
    }
926
 
 
927
 
    rc = cpg_fd_get(pcmk_cpg_handle, &fd);
928
 
    if (rc != CS_OK) {
929
 
        crm_err("Could not obtain the CPG API connection: %d\n", rc);
930
 
        goto bail;
931
 
    }
932
 
 
933
 
    mainloop_add_fd("corosync-cpg", G_PRIORITY_MEDIUM, fd, cluster->cs_dispatch, &cpg_fd_callbacks);
934
 
 
935
 
  bail:
936
 
    if (rc != CS_OK) {
937
 
        cpg_finalize(pcmk_cpg_handle);
938
 
        return FALSE;
939
 
    }
940
 
 
941
 
    peer = crm_get_peer(cluster->nodeid, pcmk_uname);
942
 
    crm_update_peer_proc(__FUNCTION__, peer, crm_proc_cpg, ONLINESTATUS);
943
 
 
944
 
#  else
945
 
    crm_err("The Corosync CPG API is not supported in this build");
946
 
    crm_exit(100);
947
 
#  endif
948
 
    return TRUE;
949
 
}
 
452
    crm_exit(DAEMON_RESPAWN_STOP);
 
453
#  endif
 
454
    return TRUE;
 
455
}
 
456
 
 
457
#  ifdef SUPPORT_COROSYNC
950
458
 
951
459
gboolean
952
 
init_quorum_connection(gboolean(*dispatch) (unsigned long long, gboolean),
 
460
cluster_connect_quorum(gboolean(*dispatch) (unsigned long long, gboolean),
953
461
                       void (*destroy) (gpointer))
954
462
{
955
463
    crm_err("The Corosync quorum API is not supported in this build");
956
 
    crm_exit(100);
 
464
    crm_exit(DAEMON_RESPAWN_STOP);
957
465
    return TRUE;
958
466
}
959
467
 
963
471
    int rc;
964
472
    int pid = 0;
965
473
    char *pid_s = NULL;
966
 
    struct utsname name;
 
474
    const char *name = NULL;
 
475
    crm_node_t *peer = NULL;
 
476
    enum crm_proc_flag proc = 0;
967
477
 
968
478
    struct mainloop_fd_callbacks ais_fd_callbacks = {
969
 
        .dispatch = ais_dispatch,
 
479
        .dispatch = plugin_dispatch,
970
480
        .destroy = cluster->destroy,
971
481
    };
972
482
 
977
487
    if (ais_ipc_handle) {
978
488
        coroipcc_fd_get(ais_ipc_handle, &ais_fd_async);
979
489
    } else {
980
 
        crm_info("Connection to our AIS plugin (%d) failed: %s (%d)",
 
490
        crm_info("Connection to our Corosync plugin (%d) failed: %s (%d)",
981
491
                 PCMK_SERVICE_ID, strerror(errno), errno);
982
492
        return FALSE;
983
493
    }
986
496
        rc = CS_ERR_LIBRARY;
987
497
    }
988
498
    if (rc != CS_OK) {
989
 
        crm_info("Connection to our AIS plugin (%d) failed: %s (%d)", PCMK_SERVICE_ID,
 
499
        crm_info("Connection to our Corosync plugin (%d) failed: %s (%d)", PCMK_SERVICE_ID,
990
500
                 ais_error2text(rc), rc);
991
501
    }
992
502
 
995
505
    }
996
506
 
997
507
    if (ais_fd_callbacks.destroy == NULL) {
998
 
        ais_fd_callbacks.destroy = ais_destroy;
 
508
        ais_fd_callbacks.destroy = plugin_destroy;
999
509
    }
1000
510
 
1001
 
    mainloop_add_fd("corosync-plugin", G_PRIORITY_MEDIUM, ais_fd_async, cluster->cs_dispatch,
1002
 
                    &ais_fd_callbacks);
 
511
    mainloop_add_fd("corosync-plugin", G_PRIORITY_MEDIUM, ais_fd_async, cluster, &ais_fd_callbacks);
1003
512
    crm_info("AIS connection established");
1004
513
 
1005
514
    pid = getpid();
1006
515
    pid_s = crm_itoa(pid);
1007
 
    send_ais_text(crm_class_cluster, pid_s, TRUE, NULL, crm_msg_ais);
 
516
    send_cluster_text(crm_class_cluster, pid_s, TRUE, NULL, crm_msg_ais);
1008
517
    free(pid_s);
1009
518
 
1010
 
    if (uname(&name) < 0) {
1011
 
        crm_perror(LOG_ERR, "Could not determin the current host");
1012
 
        crm_exit(100);
1013
 
    }
 
519
    cluster->nodeid = get_local_nodeid(0);
1014
520
 
1015
 
    get_ais_nodeid(&pcmk_nodeid, &pcmk_uname);
1016
 
    if (safe_str_neq(name.nodename, pcmk_uname)) {
1017
 
        crm_crit("Node name mismatch!  Corosync supplied %s, our lookup returned %s",
1018
 
                 pcmk_uname, name.nodename);
 
521
    name = get_local_node_name();
 
522
    plugin_get_details(NULL, &(cluster->uname));
 
523
    if (safe_str_neq(name, cluster->uname)) {
 
524
        crm_crit("Node name mismatch!  Corosync supplied %s but our lookup returned %s",
 
525
                 cluster->uname, name);
1019
526
        crm_notice
1020
527
            ("Node name mismatches usually occur when assigned automatically by DHCP servers");
1021
 
        crm_notice("If this node was part of the cluster with a different name,"
1022
 
                   " you will need to remove the old entry with crm_node --remove");
 
528
        crm_exit(ENOTUNIQ);
1023
529
    }
1024
 
    
1025
 
    cluster->nodeid = pcmk_nodeid;
 
530
 
 
531
    proc = text2proc(crm_system_name);
 
532
    peer = crm_get_peer(cluster->nodeid, cluster->uname);
 
533
    crm_update_peer_proc(__FUNCTION__, peer, proc|crm_proc_plugin, ONLINESTATUS);
1026
534
 
1027
535
    return TRUE;
1028
536
}
1080
588
        int rc = init_cs_connection_once(cluster);
1081
589
 
1082
590
        retries++;
1083
 
 
1084
591
        switch (rc) {
1085
592
            case CS_OK:
1086
 
                if (getenv("HA_mcp")) {
 
593
                if (getenv("HA_mcp") && get_cluster_type() != pcmk_cluster_cman) {
1087
594
                    xmlNode *poke = create_xml_node(NULL, "poke");
1088
595
                    mainloop_io_t *ipc =
1089
596
                        mainloop_add_ipc_client(CRM_SYSTEM_MCP, G_PRIORITY_MEDIUM, 0,
1144
651
gboolean
1145
652
init_cs_connection_once(crm_cluster_t * cluster)
1146
653
{
 
654
    crm_node_t *peer = NULL;
1147
655
    enum cluster_type_e stack = get_cluster_type();
1148
656
 
1149
657
    crm_peer_init();
1156
664
            }
1157
665
            break;
1158
666
        case pcmk_cluster_cman:
1159
 
            if (init_cpg_connection(cluster) == FALSE) {
 
667
            if (cluster_connect_cpg(cluster) == FALSE) {
1160
668
                return FALSE;
1161
669
            }
1162
 
            pcmk_uname = cman_node_name(0 /* CMAN_NODEID_US */ );
 
670
            cluster->uname = cman_node_name(0 /* CMAN_NODEID_US */ );
1163
671
            break;
1164
672
        case pcmk_cluster_heartbeat:
1165
673
            crm_info("Could not find an active corosync based cluster");
1173
681
 
1174
682
    crm_info("Connection to '%s': established", name_for_cluster_type(stack));
1175
683
 
1176
 
    CRM_ASSERT(pcmk_uname != NULL);
1177
 
    pcmk_uname_len = strlen(pcmk_uname);
1178
 
 
1179
 
    pcmk_nodeid = cluster->nodeid;
1180
 
    if (pcmk_nodeid != 0) {
1181
 
        /* Ensure the local node always exists */
1182
 
        crm_get_peer(pcmk_nodeid, pcmk_uname);
1183
 
    }
1184
 
 
1185
 
    cluster->uuid = get_corosync_uuid(pcmk_nodeid, pcmk_uname);
1186
 
    cluster->uname = strdup(pcmk_uname);
 
684
    cluster->nodeid = get_local_nodeid(0);
 
685
    if(cluster->nodeid == 0) {
 
686
        crm_err("Could not establish local nodeid");
 
687
        return FALSE;
 
688
    }
 
689
 
 
690
    cluster->uname = get_node_name(0);
 
691
    if(cluster->uname == NULL) {
 
692
        crm_err("Could not establish local node name");
 
693
        return FALSE;
 
694
    }
 
695
 
 
696
    /* Ensure the local node always exists */
 
697
    peer = crm_get_peer(cluster->nodeid, cluster->uname);
 
698
    cluster->uuid = get_corosync_uuid(peer);
1187
699
 
1188
700
    return TRUE;
1189
701
}
1192
704
check_message_sanity(const AIS_Message * msg, const char *data)
1193
705
{
1194
706
    gboolean sane = TRUE;
1195
 
    gboolean repaired = FALSE;
1196
707
    int dest = msg->host.type;
1197
708
    int tmp_size = msg->header.size - sizeof(AIS_Message);
1198
709
 
1241
752
                ais_dest(&(msg->sender)), msg_type2text(msg->sender.type),
1242
753
                msg->sender.pid, msg->is_compressed, ais_data_len(msg), msg->header.size);
1243
754
 
1244
 
    } else if (repaired) {
1245
 
        crm_err
1246
 
            ("Repaired message %d: (dest=%s:%s, from=%s:%s.%d, compressed=%d, size=%d, total=%d)",
1247
 
             msg->id, ais_dest(&(msg->host)), msg_type2text(dest), ais_dest(&(msg->sender)),
1248
 
             msg_type2text(msg->sender.type), msg->sender.pid, msg->is_compressed,
1249
 
             ais_data_len(msg), msg->header.size);
1250
755
    } else {
1251
756
        crm_trace
1252
757
            ("Verfied message %d: (dest=%s:%s, from=%s:%s.%d, compressed=%d, size=%d, total=%d)",