corosync-fplay.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. #include <config.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <assert.h>
  10. #include <stdint.h>
  11. #include <errno.h>
  12. #include <sys/socket.h>
  13. #include <netinet/in.h>
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <arpa/inet.h>
  17. #include <corosync/engine/logsys.h>
  18. unsigned int flt_data_size = 1000000;
  19. unsigned int *flt_data;
  20. #define FDHEAD_INDEX (flt_data_size)
  21. #define FDTAIL_INDEX (flt_data_size + 1)
  22. #define TOTEMIP_ADDRLEN (sizeof(struct in6_addr))
  23. struct totem_ip_address {
  24. unsigned int nodeid;
  25. unsigned short family;
  26. unsigned char addr[TOTEMIP_ADDRLEN];
  27. } __attribute__((packed));
  28. struct memb_ring_id {
  29. struct totem_ip_address rep;
  30. unsigned long long seq;
  31. } __attribute__((packed));
  32. static const char *totemip_print(const struct totem_ip_address *addr)
  33. {
  34. static char buf[INET6_ADDRSTRLEN];
  35. return inet_ntop(addr->family, addr->addr, buf, sizeof(buf));
  36. }
  37. static char *print_string_len (const unsigned char *str, unsigned int len)
  38. {
  39. unsigned int i;
  40. static char buf[1024];
  41. memset (buf, 0, sizeof (buf));
  42. for (i = 0; i < len; i++) {
  43. buf[i] = str[i];
  44. }
  45. return (buf);
  46. }
  47. static void sync_printer_confchg_set_sync (const void **record)
  48. {
  49. const unsigned int *my_should_sync = record[0];
  50. printf ("Setting my_should_sync to %d\n", *my_should_sync);
  51. }
  52. static void sync_printer_set_sync_state (const void **record)
  53. {
  54. const unsigned int *my_sync_state = record[0];
  55. printf ("Setting my_sync_state to %d\n", *my_sync_state);
  56. }
  57. static void sync_printer_process_currentstate (const void **record)
  58. {
  59. const unsigned int *my_sync_state = record[0];
  60. printf ("Retrieving my_sync_state %d\n", *my_sync_state);
  61. }
  62. static void sync_printer_process_get_shouldsync (const void **record)
  63. {
  64. const unsigned int *my_should_sync = record[0];
  65. printf ("Getting my_should_sync %d\n", *my_should_sync);
  66. }
  67. static void sync_printer_checkpoint_release (const void **record)
  68. {
  69. const unsigned char *name = record[0];
  70. const uint16_t *name_len = record[1];
  71. const unsigned int *ckpt_id = record[2];
  72. const unsigned int *from = record[3];
  73. printf ("Checkpoint release name=[%s] id=[%d] from=[%d] len=[%d]\n",
  74. print_string_len (name, *name_len),
  75. *ckpt_id,
  76. *from,
  77. *name_len);
  78. }
  79. static void sync_printer_checkpoint_transmit (const void **record)
  80. {
  81. const unsigned char *name = record[0];
  82. const uint16_t *name_len = record[1];
  83. const unsigned int *ckpt_id = record[2];
  84. const unsigned int *xmit_id = record[3];
  85. printf ("xmit_id=[%d] Checkpoint transmit name=[%s] id=[%d]\n",
  86. *xmit_id, print_string_len (name, *name_len),
  87. *ckpt_id);
  88. }
  89. static void sync_printer_section_transmit (const void **record)
  90. {
  91. const unsigned char *ckpt_name = record[0];
  92. const uint16_t *name_len = record[1];
  93. const unsigned int *ckpt_id = record[2];
  94. const unsigned int *xmit_id = record[3];
  95. const unsigned char *section_name = record[4];
  96. const uint16_t *section_name_len = record[5];
  97. printf ("xmit_id=[%d] Section transmit checkpoint name=[%s] id=[%d] ",
  98. *xmit_id, print_string_len (ckpt_name, *name_len),
  99. *ckpt_id);
  100. printf ("section=[%s]\n",
  101. print_string_len (section_name, *section_name_len));
  102. }
  103. static void sync_printer_checkpoint_receive (const void **record)
  104. {
  105. const unsigned char *ckpt_name = record[0];
  106. const uint16_t *name_len = record[1];
  107. const unsigned int *ckpt_id = record[2];
  108. const unsigned int *xmit_id = record[3];
  109. printf ("xmit_id=[%d] Checkpoint receive checkpoint name=[%s] id=[%d]\n",
  110. *xmit_id, print_string_len (ckpt_name, *name_len), *ckpt_id);
  111. }
  112. static void sync_printer_section_receive (const void **record)
  113. {
  114. const unsigned char *ckpt_name = record[0];
  115. const uint16_t *name_len = record[1];
  116. const unsigned int *ckpt_id = record[2];
  117. const unsigned int *xmit_id = record[3];
  118. const unsigned char *section_name = record[4];
  119. const unsigned int *section_name_len = record[5];
  120. printf ("xmit_id=[%d] Section receive checkpoint name=[%s] id=[%d] ",
  121. *xmit_id, print_string_len (ckpt_name, *name_len),
  122. *ckpt_id);
  123. printf ("section=[%s]\n",
  124. print_string_len (section_name, *section_name_len));
  125. }
  126. static void sync_printer_confchg_fn (const void **record)
  127. {
  128. unsigned int i;
  129. const unsigned int *members = record[0];
  130. const unsigned int *member_count = record[1];
  131. const struct memb_ring_id *ring_id = record[2];
  132. struct in_addr addr;
  133. printf ("sync confchg fn ringid [ip=%s seq=%lld]\n",
  134. totemip_print (&ring_id->rep),
  135. ring_id->seq);
  136. printf ("members [%d]:\n", *member_count);
  137. for (i = 0; i < *member_count; i++) {
  138. addr.s_addr = members[i];
  139. printf ("\tmember [%s]\n", inet_ntoa (addr));
  140. }
  141. }
  142. static void printer_totemsrp_mcast (const void **record)
  143. {
  144. const unsigned int *msgid = record[0];
  145. printf ("totemsrp_mcast %d\n", *msgid);
  146. }
  147. static void printer_totemsrp_delv (const void **record)
  148. {
  149. const unsigned int *msgid = record[0];
  150. printf ("totemsrp_delv %d\n", *msgid);
  151. }
  152. static void printer_totempg_mcast_fits (const void **record)
  153. {
  154. const unsigned int *index = record[0];
  155. const unsigned int *iov_len = record[1];
  156. const unsigned int *copy_len = record[2];
  157. const unsigned int *fragment_size = record[3];
  158. const unsigned int *max_packet_size = record[4];
  159. const unsigned int *copy_base = record[5];
  160. const unsigned char *next_fragment = record[6];
  161. 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",
  162. *index, *iov_len, *copy_len, *fragment_size, *max_packet_size, *copy_base, *next_fragment);
  163. }
  164. static void sync_printer_service_process (const void **record)
  165. {
  166. const struct memb_ring_id *ring_id = record[0];
  167. const struct memb_ring_id *sync_ring_id = record[1];
  168. printf ("sync service process callback ringid [ip=%s seq=%lld] ",
  169. totemip_print (&ring_id->rep),
  170. ring_id->seq);
  171. printf ("sync ringid [ip=%s seq=%lld]\n",
  172. totemip_print (&sync_ring_id->rep),
  173. sync_ring_id->seq);
  174. }
  175. struct printer_subsys_record_print {
  176. int ident;
  177. void (*print_fn)(const void **record);
  178. int record_length;
  179. };
  180. struct printer_subsys {
  181. const char *subsys;
  182. struct printer_subsys_record_print *record_printers;
  183. int record_printers_count;
  184. };
  185. #define LOGREC_ID_SYNC_CONFCHG_FN 0
  186. #define LOGREC_ID_SYNC_SERVICE_PROCESS 1
  187. /*
  188. * CKPT subsystem
  189. */
  190. #define LOGREC_ID_CONFCHG_SETSYNC 0
  191. #define LOGREC_ID_SETSYNCSTATE 1
  192. #define LOGREC_ID_SYNC_PROCESS_CURRENTSTATE 2
  193. #define LOGREC_ID_SYNC_PROCESS_GETSHOULDSYNC 3
  194. #define LOGREC_ID_SYNC_CHECKPOINT_TRANSMIT 4
  195. #define LOGREC_ID_SYNC_SECTION_TRANSMIT 5
  196. #define LOGREC_ID_SYNC_CHECKPOINT_RECEIVE 6
  197. #define LOGREC_ID_SYNC_SECTION_RECEIVE 7
  198. #define LOGREC_ID_SYNC_CHECKPOINT_RELEASE 8
  199. #define LOGREC_ID_TOTEMSRP_MCAST 0
  200. #define LOGREC_ID_TOTEMSRP_DELV 1
  201. #define LOGREC_ID_TOTEMPG_MCAST_FITS 2
  202. static struct printer_subsys_record_print record_print_sync[] = {
  203. {
  204. .ident = LOGREC_ID_SYNC_CONFCHG_FN,
  205. .print_fn = sync_printer_confchg_fn,
  206. .record_length = 28
  207. },
  208. {
  209. .ident = LOGREC_ID_SYNC_SERVICE_PROCESS,
  210. .print_fn = sync_printer_service_process,
  211. .record_length = 28
  212. }
  213. };
  214. static struct printer_subsys_record_print record_print_ckpt[] = {
  215. {
  216. .ident = LOGREC_ID_CONFCHG_SETSYNC,
  217. .print_fn = sync_printer_confchg_set_sync,
  218. .record_length = 28
  219. },
  220. {
  221. .ident = LOGREC_ID_SETSYNCSTATE,
  222. .print_fn = sync_printer_set_sync_state,
  223. .record_length = 28
  224. },
  225. {
  226. .ident = LOGREC_ID_SYNC_PROCESS_CURRENTSTATE,
  227. .print_fn = sync_printer_process_currentstate,
  228. .record_length = 28
  229. },
  230. {
  231. .ident = LOGREC_ID_SYNC_PROCESS_GETSHOULDSYNC,
  232. .print_fn = sync_printer_process_get_shouldsync,
  233. .record_length = 28
  234. },
  235. {
  236. .ident = LOGREC_ID_SYNC_CHECKPOINT_TRANSMIT,
  237. .print_fn = sync_printer_checkpoint_transmit,
  238. .record_length = 28
  239. },
  240. {
  241. .ident = LOGREC_ID_SYNC_SECTION_TRANSMIT,
  242. .print_fn = sync_printer_section_transmit,
  243. .record_length = 28
  244. },
  245. {
  246. .ident = LOGREC_ID_SYNC_CHECKPOINT_RECEIVE,
  247. .print_fn = sync_printer_checkpoint_receive,
  248. .record_length = 28
  249. },
  250. {
  251. .ident = LOGREC_ID_SYNC_SECTION_RECEIVE,
  252. .print_fn = sync_printer_section_receive,
  253. .record_length = 28
  254. },
  255. {
  256. .ident = LOGREC_ID_SYNC_CHECKPOINT_RELEASE,
  257. .print_fn = sync_printer_checkpoint_release,
  258. .record_length = 28
  259. }
  260. };
  261. static struct printer_subsys_record_print record_print_totem[] = {
  262. {
  263. .ident = LOGREC_ID_TOTEMSRP_MCAST,
  264. .print_fn = printer_totemsrp_mcast,
  265. .record_length = 28
  266. },
  267. {
  268. .ident = LOGREC_ID_TOTEMSRP_DELV,
  269. .print_fn = printer_totemsrp_delv,
  270. .record_length = 28
  271. },
  272. {
  273. .ident = LOGREC_ID_TOTEMPG_MCAST_FITS,
  274. .print_fn = printer_totempg_mcast_fits,
  275. .record_length = 28
  276. }
  277. };
  278. static struct printer_subsys printer_subsystems[] = {
  279. {
  280. .subsys = "SYNC",
  281. .record_printers = record_print_sync,
  282. .record_printers_count = sizeof (record_print_sync) / sizeof (struct printer_subsys_record_print)
  283. },
  284. {
  285. .subsys = "CKPT",
  286. .record_printers = record_print_ckpt,
  287. .record_printers_count = sizeof (record_print_ckpt) / sizeof (struct printer_subsys_record_print)
  288. },
  289. {
  290. .subsys = "TOTEM",
  291. .record_printers = record_print_totem,
  292. .record_printers_count = sizeof (record_print_totem) / sizeof (struct printer_subsys_record_print)
  293. }
  294. };
  295. static unsigned int printer_subsys_count =
  296. sizeof (printer_subsystems) / sizeof (struct printer_subsys);
  297. static unsigned int record[10000];
  298. /*
  299. * Copy record, dealing with wrapping
  300. */
  301. static int logsys_rec_get (int rec_idx) {
  302. unsigned int rec_size;
  303. int firstcopy, secondcopy;
  304. rec_size = flt_data[rec_idx];
  305. firstcopy = rec_size;
  306. secondcopy = 0;
  307. if (firstcopy + rec_idx > flt_data_size) {
  308. firstcopy = flt_data_size - rec_idx;
  309. secondcopy -= firstcopy - rec_size;
  310. }
  311. memcpy (&record[0], &flt_data[rec_idx], firstcopy<<2);
  312. if (secondcopy) {
  313. memcpy (&record[firstcopy], &flt_data[0], secondcopy<<2);
  314. }
  315. return ((rec_idx + rec_size) % flt_data_size);
  316. }
  317. static void logsys_rec_print (const void *record)
  318. {
  319. const unsigned int *buf_uint32t = record;
  320. unsigned int rec_size;
  321. unsigned int rec_ident;
  322. unsigned int line;
  323. unsigned int arg_size_idx;
  324. unsigned int i;
  325. unsigned int j;
  326. unsigned int rec_idx = 0;
  327. unsigned int record_number;
  328. unsigned int words_processed;
  329. unsigned int found;
  330. const char *arguments[64];
  331. int arg_count = 0;
  332. rec_size = buf_uint32t[rec_idx];
  333. rec_ident = buf_uint32t[rec_idx+1];
  334. line = buf_uint32t[rec_idx+2];
  335. record_number = buf_uint32t[rec_idx+3];
  336. printf ("rec=[%d] ", record_number);
  337. arg_size_idx = rec_idx + 4;
  338. words_processed = 4;
  339. for (i = 0; words_processed < rec_size; i++) {
  340. arguments[arg_count++] =
  341. (const char *)&buf_uint32t[arg_size_idx + 1];
  342. words_processed += buf_uint32t[arg_size_idx] + 1;
  343. arg_size_idx += buf_uint32t[arg_size_idx] + 1;
  344. }
  345. found = 0;
  346. for (i = 0; i < printer_subsys_count; i++) {
  347. if (strcmp (arguments[0], printer_subsystems[i].subsys) == 0) {
  348. for (j = 0; j < printer_subsystems[i].record_printers_count; j++) {
  349. if (rec_ident == printer_subsystems[i].record_printers[j].ident) {
  350. printer_subsystems[i].record_printers[j].print_fn ((const void **)&arguments[3]);
  351. found = 1;
  352. }
  353. }
  354. }
  355. }
  356. if (rec_ident & LOGSYS_TAG_LOG) {
  357. printf ("Log Message=%s\n", arguments[3]);
  358. found = 1;
  359. }
  360. if (rec_ident & LOGSYS_TAG_ENTER) {
  361. printf ("ENTERING function [%s] line [%d]\n", arguments[2], line);
  362. found = 1;
  363. }
  364. if (rec_ident & LOGSYS_TAG_LEAVE) {
  365. printf ("LEAVING function [%s] line [%d]\n", arguments[2], line);
  366. found = 1;
  367. }
  368. if (found == 0) {
  369. printf ("Unknown record type found subsys=[%s] ident=[%d]\n",
  370. arguments[0], rec_ident);
  371. }
  372. if (rec_ident == 999) {
  373. printf ("ENTERING function [%s] line [%d]\n", arguments[2], line);
  374. found = 1;
  375. }
  376. if (rec_ident == 1000) {
  377. printf ("LEAVING function [%s] line [%d]\n", arguments[2], line);
  378. found = 1;
  379. }
  380. if (found == 0) {
  381. printf ("Unknown record type found subsys=[%s] ident=[%d]\n",
  382. arguments[0], rec_ident);
  383. }
  384. #ifdef COMPILE_OUT
  385. printf ("\n");
  386. #endif
  387. }
  388. int main (void)
  389. {
  390. unsigned int fd;
  391. int rec_idx;
  392. int end_rec;
  393. int record_count = 1;
  394. ssize_t n_read;
  395. const char *data_file = LOCALSTATEDIR "/lib/corosync/fdata";
  396. size_t n_required = (flt_data_size + 2) * sizeof (unsigned int);
  397. if ((fd = open (data_file, O_RDONLY)) < 0) {
  398. fprintf (stderr, "failed to open %s: %s\n",
  399. data_file, strerror (errno));
  400. return EXIT_FAILURE;
  401. }
  402. if ((flt_data = malloc (n_required)) == NULL) {
  403. fprintf (stderr, "exhausted virtual memory\n");
  404. return EXIT_FAILURE;
  405. }
  406. n_read = read (fd, flt_data, n_required);
  407. close (fd);
  408. if (n_read < 0) {
  409. fprintf (stderr, "reading %s failed: %s\n",
  410. data_file, strerror (errno));
  411. return EXIT_FAILURE;
  412. }
  413. if (n_read != n_required) {
  414. printf ("Warning: read %lu bytes, but expected %lu\n",
  415. (unsigned long) n_read, (unsigned long) n_required);
  416. }
  417. rec_idx = flt_data[FDTAIL_INDEX];
  418. end_rec = flt_data[FDHEAD_INDEX];
  419. printf ("Starting replay: head [%d] tail [%d]\n",
  420. flt_data[FDHEAD_INDEX],
  421. flt_data[FDTAIL_INDEX]);
  422. for (;;) {
  423. rec_idx = logsys_rec_get (rec_idx);
  424. logsys_rec_print (record);
  425. if (rec_idx == end_rec) {
  426. break;
  427. }
  428. record_count += 1;
  429. }
  430. printf ("Finishing replay: records found [%d]\n", record_count);
  431. return (0);
  432. }