#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include unsigned int flt_data_size; unsigned int *flt_data; #define FDHEAD_INDEX (flt_data_size) #define FDTAIL_INDEX (flt_data_size + 1) #define TOTEMIP_ADDRLEN (sizeof(struct in6_addr)) struct totem_ip_address { unsigned int nodeid; unsigned short family; unsigned char addr[TOTEMIP_ADDRLEN]; } __attribute__((packed)); struct memb_ring_id { struct totem_ip_address rep; unsigned long long seq; } __attribute__((packed)); static const char *totemip_print(const struct totem_ip_address *addr) { static char buf[INET6_ADDRSTRLEN]; return inet_ntop(addr->family, addr->addr, buf, sizeof(buf)); } static char *print_string_len (const unsigned char *str, unsigned int len) { unsigned int i; static char buf[1024]; memset (buf, 0, sizeof (buf)); for (i = 0; i < len; i++) { buf[i] = str[i]; } return (buf); } static void sync_printer_confchg_set_sync (const void **record) { const unsigned int *my_should_sync = record[0]; printf ("Setting my_should_sync to %d\n", *my_should_sync); } static void sync_printer_set_sync_state (const void **record) { const unsigned int *my_sync_state = record[0]; printf ("Setting my_sync_state to %d\n", *my_sync_state); } static void sync_printer_process_currentstate (const void **record) { const unsigned int *my_sync_state = record[0]; printf ("Retrieving my_sync_state %d\n", *my_sync_state); } static void sync_printer_process_get_shouldsync (const void **record) { const unsigned int *my_should_sync = record[0]; printf ("Getting my_should_sync %d\n", *my_should_sync); } static void sync_printer_checkpoint_release (const void **record) { const unsigned char *name = record[0]; const uint16_t *name_len = record[1]; const unsigned int *ckpt_id = record[2]; const unsigned int *from = record[3]; printf ("Checkpoint release name=[%s] id=[%d] from=[%d] len=[%d]\n", print_string_len (name, *name_len), *ckpt_id, *from, *name_len); } static void sync_printer_checkpoint_transmit (const void **record) { const unsigned char *name = record[0]; const uint16_t *name_len = record[1]; const unsigned int *ckpt_id = record[2]; const unsigned int *xmit_id = record[3]; printf ("xmit_id=[%d] Checkpoint transmit name=[%s] id=[%d]\n", *xmit_id, print_string_len (name, *name_len), *ckpt_id); } static void sync_printer_section_transmit (const void **record) { const unsigned char *ckpt_name = record[0]; const uint16_t *name_len = record[1]; const unsigned int *ckpt_id = record[2]; const unsigned int *xmit_id = record[3]; const unsigned char *section_name = record[4]; const uint16_t *section_name_len = record[5]; printf ("xmit_id=[%d] Section transmit checkpoint name=[%s] id=[%d] ", *xmit_id, print_string_len (ckpt_name, *name_len), *ckpt_id); printf ("section=[%s]\n", print_string_len (section_name, *section_name_len)); } static void sync_printer_checkpoint_receive (const void **record) { const unsigned char *ckpt_name = record[0]; const uint16_t *name_len = record[1]; const unsigned int *ckpt_id = record[2]; const unsigned int *xmit_id = record[3]; printf ("xmit_id=[%d] Checkpoint receive checkpoint name=[%s] id=[%d]\n", *xmit_id, print_string_len (ckpt_name, *name_len), *ckpt_id); } static void sync_printer_section_receive (const void **record) { const unsigned char *ckpt_name = record[0]; const uint16_t *name_len = record[1]; const unsigned int *ckpt_id = record[2]; const unsigned int *xmit_id = record[3]; const unsigned char *section_name = record[4]; const unsigned int *section_name_len = record[5]; printf ("xmit_id=[%d] Section receive checkpoint name=[%s] id=[%d] ", *xmit_id, print_string_len (ckpt_name, *name_len), *ckpt_id); printf ("section=[%s]\n", print_string_len (section_name, *section_name_len)); } static void sync_printer_confchg_fn (const void **record) { unsigned int i; const unsigned int *members = record[0]; const unsigned int *member_count = record[1]; const struct memb_ring_id *ring_id = record[2]; struct in_addr addr; printf ("sync confchg fn ringid [ip=%s seq=%lld]\n", totemip_print (&ring_id->rep), ring_id->seq); printf ("members [%d]:\n", *member_count); for (i = 0; i < *member_count; i++) { addr.s_addr = members[i]; printf ("\tmember [%s]\n", inet_ntoa (addr)); } } static void printer_totemsrp_mcast (const void **record) { const unsigned int *msgid = record[0]; printf ("totemsrp_mcast %d\n", *msgid); } static void printer_totemsrp_delv (const void **record) { const unsigned int *msgid = record[0]; printf ("totemsrp_delv %d\n", *msgid); } static void printer_totempg_mcast_fits (const void **record) { const unsigned int *idx = record[0]; const unsigned int *iov_len = record[1]; const unsigned int *copy_len = record[2]; const unsigned int *fragment_size = record[3]; const unsigned int *max_packet_size = record[4]; const unsigned int *copy_base = record[5]; const unsigned char *next_fragment = record[6]; printf ("totempg_mcast index=[%d] iov_len=[%d] copy_len=[%d] fragment_size=[%d] max_packet_size=[%d] copy_base=[%d] next_fragment[%d]\n", *idx, *iov_len, *copy_len, *fragment_size, *max_packet_size, *copy_base, *next_fragment); } static void sync_printer_service_process (const void **record) { const struct memb_ring_id *ring_id = record[0]; const struct memb_ring_id *sync_ring_id = record[1]; printf ("sync service process callback ringid [ip=%s seq=%lld] ", totemip_print (&ring_id->rep), ring_id->seq); printf ("sync ringid [ip=%s seq=%lld]\n", totemip_print (&sync_ring_id->rep), sync_ring_id->seq); } struct printer_subsys_record_print { int ident; void (*print_fn)(const void **record); int record_length; }; struct printer_subsys { const char *subsys; struct printer_subsys_record_print *record_printers; int record_printers_count; }; #define LOGREC_ID_SYNC_CONFCHG_FN 0 #define LOGREC_ID_SYNC_SERVICE_PROCESS 1 /* * CKPT subsystem */ #define LOGREC_ID_CONFCHG_SETSYNC 0 #define LOGREC_ID_SETSYNCSTATE 1 #define LOGREC_ID_SYNC_PROCESS_CURRENTSTATE 2 #define LOGREC_ID_SYNC_PROCESS_GETSHOULDSYNC 3 #define LOGREC_ID_SYNC_CHECKPOINT_TRANSMIT 4 #define LOGREC_ID_SYNC_SECTION_TRANSMIT 5 #define LOGREC_ID_SYNC_CHECKPOINT_RECEIVE 6 #define LOGREC_ID_SYNC_SECTION_RECEIVE 7 #define LOGREC_ID_SYNC_CHECKPOINT_RELEASE 8 #define LOGREC_ID_TOTEMSRP_MCAST 0 #define LOGREC_ID_TOTEMSRP_DELV 1 #define LOGREC_ID_TOTEMPG_MCAST_FITS 2 static struct printer_subsys_record_print record_print_sync[] = { { .ident = LOGREC_ID_SYNC_CONFCHG_FN, .print_fn = sync_printer_confchg_fn, .record_length = 28 }, { .ident = LOGREC_ID_SYNC_SERVICE_PROCESS, .print_fn = sync_printer_service_process, .record_length = 28 } }; static struct printer_subsys_record_print record_print_ckpt[] = { { .ident = LOGREC_ID_CONFCHG_SETSYNC, .print_fn = sync_printer_confchg_set_sync, .record_length = 28 }, { .ident = LOGREC_ID_SETSYNCSTATE, .print_fn = sync_printer_set_sync_state, .record_length = 28 }, { .ident = LOGREC_ID_SYNC_PROCESS_CURRENTSTATE, .print_fn = sync_printer_process_currentstate, .record_length = 28 }, { .ident = LOGREC_ID_SYNC_PROCESS_GETSHOULDSYNC, .print_fn = sync_printer_process_get_shouldsync, .record_length = 28 }, { .ident = LOGREC_ID_SYNC_CHECKPOINT_TRANSMIT, .print_fn = sync_printer_checkpoint_transmit, .record_length = 28 }, { .ident = LOGREC_ID_SYNC_SECTION_TRANSMIT, .print_fn = sync_printer_section_transmit, .record_length = 28 }, { .ident = LOGREC_ID_SYNC_CHECKPOINT_RECEIVE, .print_fn = sync_printer_checkpoint_receive, .record_length = 28 }, { .ident = LOGREC_ID_SYNC_SECTION_RECEIVE, .print_fn = sync_printer_section_receive, .record_length = 28 }, { .ident = LOGREC_ID_SYNC_CHECKPOINT_RELEASE, .print_fn = sync_printer_checkpoint_release, .record_length = 28 } }; static struct printer_subsys_record_print record_print_totem[] = { { .ident = LOGREC_ID_TOTEMSRP_MCAST, .print_fn = printer_totemsrp_mcast, .record_length = 28 }, { .ident = LOGREC_ID_TOTEMSRP_DELV, .print_fn = printer_totemsrp_delv, .record_length = 28 }, { .ident = LOGREC_ID_TOTEMPG_MCAST_FITS, .print_fn = printer_totempg_mcast_fits, .record_length = 28 } }; static struct printer_subsys printer_subsystems[] = { { .subsys = "SYNC", .record_printers = record_print_sync, .record_printers_count = sizeof (record_print_sync) / sizeof (struct printer_subsys_record_print) }, { .subsys = "CKPT", .record_printers = record_print_ckpt, .record_printers_count = sizeof (record_print_ckpt) / sizeof (struct printer_subsys_record_print) }, { .subsys = "TOTEM", .record_printers = record_print_totem, .record_printers_count = sizeof (record_print_totem) / sizeof (struct printer_subsys_record_print) } }; static unsigned int printer_subsys_count = sizeof (printer_subsystems) / sizeof (struct printer_subsys); static unsigned int g_record[10000]; /* * Copy record, dealing with wrapping */ static int logsys_rec_get (int rec_idx) { unsigned int rec_size; int firstcopy, secondcopy; rec_size = flt_data[rec_idx]; firstcopy = rec_size; secondcopy = 0; if (firstcopy + rec_idx > flt_data_size) { firstcopy = flt_data_size - rec_idx; secondcopy -= firstcopy - rec_size; } memcpy (&g_record[0], &flt_data[rec_idx], firstcopy<<2); if (secondcopy) { memcpy (&g_record[firstcopy], &flt_data[0], secondcopy<<2); } return ((rec_idx + rec_size) % flt_data_size); } static void logsys_rec_print (const void *record) { const unsigned int *buf_uint32t = record; unsigned int rec_size; unsigned int rec_ident; unsigned int level; unsigned int line; unsigned int arg_size_idx; unsigned int i; unsigned int j; unsigned int rec_idx = 0; unsigned int record_number; unsigned int words_processed; unsigned int found; const char *arguments[64]; int arg_count = 0; rec_size = buf_uint32t[rec_idx]; rec_ident = buf_uint32t[rec_idx+1]; line = buf_uint32t[rec_idx+2]; record_number = buf_uint32t[rec_idx+3]; level = LOGSYS_DECODE_LEVEL(rec_ident); printf ("rec=[%d] ", record_number); arg_size_idx = rec_idx + 4; words_processed = 4; for (i = 0; words_processed < rec_size; i++) { arguments[arg_count++] = (const char *)&buf_uint32t[arg_size_idx + 1]; words_processed += buf_uint32t[arg_size_idx] + 1; arg_size_idx += buf_uint32t[arg_size_idx] + 1; } found = 0; for (i = 0; i < printer_subsys_count; i++) { if (strcmp (arguments[0], printer_subsystems[i].subsys) == 0) { for (j = 0; j < printer_subsystems[i].record_printers_count; j++) { if (rec_ident == printer_subsystems[i].record_printers[j].ident) { printer_subsystems[i].record_printers[j].print_fn ((const void **)&arguments[3]); return; } } } } switch(LOGSYS_DECODE_RECID(rec_ident)) { case LOGSYS_RECID_LOG: printf ("Log Message=%s\n", arguments[3]); break; case LOGSYS_RECID_ENTER: printf ("ENTERING function [%s] line [%d]\n", arguments[2], line); break; case LOGSYS_RECID_LEAVE: printf ("LEAVING function [%s] line [%d]\n", arguments[2], line); break; case LOGSYS_RECID_TRACE1: printf ("Tracing(1) Messsage=%s\n", arguments[3]); break; case LOGSYS_RECID_TRACE2: printf ("Tracing(2) Messsage=%s\n", arguments[3]); break; case LOGSYS_RECID_TRACE3: printf ("Tracing(3) Messsage=%s\n", arguments[3]); break; case LOGSYS_RECID_TRACE4: printf ("Tracing(4) Messsage=%s\n", arguments[3]); break; case LOGSYS_RECID_TRACE5: printf ("Tracing(5) Messsage=%s\n", arguments[3]); break; case LOGSYS_RECID_TRACE6: printf ("Tracing(6) Messsage=%s\n", arguments[3]); break; case LOGSYS_RECID_TRACE7: printf ("Tracing(7) Messsage=%s\n", arguments[3]); break; case LOGSYS_RECID_TRACE8: printf ("Tracing(8) Messsage=%s\n", arguments[3]); break; default: printf ("Unknown record type found subsys=[%s] ident=[%d]\n", arguments[0], LOGSYS_DECODE_RECID(rec_ident)); break; } #ifdef COMPILE_OUT printf ("\n"); #endif } int main (void) { int fd; int rec_idx; int end_rec; int record_count = 1; ssize_t n_read; const char *data_file = LOCALSTATEDIR "/lib/corosync/fdata"; size_t n_required; if ((fd = open (data_file, O_RDONLY)) < 0) { fprintf (stderr, "failed to open %s: %s\n", data_file, strerror (errno)); return EXIT_FAILURE; } n_required = sizeof (unsigned int); n_read = read (fd, &flt_data_size, n_required); if (n_read != n_required) { fprintf (stderr, "Unable to read fdata header\n"); return EXIT_FAILURE; } n_required = ((flt_data_size + 2) * sizeof(unsigned int)); if ((flt_data = malloc (n_required)) == NULL) { fprintf (stderr, "exhausted virtual memory\n"); return EXIT_FAILURE; } n_read = read (fd, flt_data, n_required); close (fd); if (n_read < 0) { fprintf (stderr, "reading %s failed: %s\n", data_file, strerror (errno)); return EXIT_FAILURE; } if (n_read != n_required) { printf ("Warning: read %lu bytes, but expected %lu\n", (unsigned long) n_read, (unsigned long) n_required); } rec_idx = flt_data[FDTAIL_INDEX]; end_rec = flt_data[FDHEAD_INDEX]; printf ("Starting replay: head [%d] tail [%d]\n", flt_data[FDHEAD_INDEX], flt_data[FDTAIL_INDEX]); for (;;) { rec_idx = logsys_rec_get (rec_idx); logsys_rec_print (g_record); if (rec_idx == end_rec) { break; } record_count += 1; } printf ("Finishing replay: records found [%d]\n", record_count); return (0); }