totemrrp.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759
  1. /*
  2. * Copyright (c) 2005 MontaVista Software, Inc.
  3. * Copyright (c) 2006-2009 Red Hat, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. * Author: Steven Dake (sdake@redhat.com)
  8. *
  9. * This software licensed under BSD license, the text of which follows:
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above copyright notice,
  15. * this list of conditions and the following disclaimer.
  16. * - Redistributions in binary form must reproduce the above copyright notice,
  17. * this list of conditions and the following disclaimer in the documentation
  18. * and/or other materials provided with the distribution.
  19. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  20. * contributors may be used to endorse or promote products derived from this
  21. * software without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  33. * THE POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. #include <config.h>
  36. #include <assert.h>
  37. #include <pthread.h>
  38. #include <sys/mman.h>
  39. #include <sys/types.h>
  40. #include <sys/stat.h>
  41. #include <sys/socket.h>
  42. #include <netdb.h>
  43. #include <sys/un.h>
  44. #include <sys/ioctl.h>
  45. #include <sys/param.h>
  46. #include <netinet/in.h>
  47. #include <arpa/inet.h>
  48. #include <unistd.h>
  49. #include <fcntl.h>
  50. #include <stdlib.h>
  51. #include <stdio.h>
  52. #include <errno.h>
  53. #include <sched.h>
  54. #include <time.h>
  55. #include <sys/time.h>
  56. #include <sys/poll.h>
  57. #include <limits.h>
  58. #include <corosync/sq.h>
  59. #include <corosync/list.h>
  60. #include <corosync/hdb.h>
  61. #include <corosync/swab.h>
  62. #include <corosync/totem/coropoll.h>
  63. #define LOGSYS_UTILS_ONLY 1
  64. #include <corosync/engine/logsys.h>
  65. #include "totemnet.h"
  66. #include "totemrrp.h"
  67. void rrp_deliver_fn (
  68. void *context,
  69. const void *msg,
  70. unsigned int msg_len);
  71. void rrp_iface_change_fn (
  72. void *context,
  73. const struct totem_ip_address *iface_addr);
  74. struct totemrrp_instance;
  75. struct passive_instance {
  76. struct totemrrp_instance *rrp_instance;
  77. unsigned int *faulty;
  78. unsigned int *token_recv_count;
  79. unsigned int *mcast_recv_count;
  80. unsigned char token[15000];
  81. unsigned int token_len;
  82. poll_timer_handle timer_expired_token;
  83. poll_timer_handle timer_problem_decrementer;
  84. void *totemrrp_context;
  85. unsigned int token_xmit_iface;
  86. unsigned int msg_xmit_iface;
  87. };
  88. struct active_instance {
  89. struct totemrrp_instance *rrp_instance;
  90. unsigned int *faulty;
  91. unsigned int *last_token_recv;
  92. unsigned int *counter_problems;
  93. unsigned char token[15000];
  94. unsigned int token_len;
  95. unsigned int last_token_seq;
  96. poll_timer_handle timer_expired_token;
  97. poll_timer_handle timer_problem_decrementer;
  98. void *totemrrp_context;
  99. };
  100. struct rrp_algo {
  101. const char *name;
  102. void * (*initialize) (
  103. struct totemrrp_instance *rrp_instance,
  104. int interface_count);
  105. void (*mcast_recv) (
  106. struct totemrrp_instance *instance,
  107. unsigned int iface_no,
  108. void *context,
  109. const void *msg,
  110. unsigned int msg_len);
  111. void (*mcast_noflush_send) (
  112. struct totemrrp_instance *instance,
  113. const void *msg,
  114. unsigned int msg_len);
  115. void (*mcast_flush_send) (
  116. struct totemrrp_instance *instance,
  117. const void *msg,
  118. unsigned int msg_len);
  119. void (*token_recv) (
  120. struct totemrrp_instance *instance,
  121. unsigned int iface_no,
  122. void *context,
  123. const void *msg,
  124. unsigned int msg_len,
  125. unsigned int token_seqid);
  126. void (*token_send) (
  127. struct totemrrp_instance *instance,
  128. const void *msg,
  129. unsigned int msg_len);
  130. void (*recv_flush) (
  131. struct totemrrp_instance *instance);
  132. void (*send_flush) (
  133. struct totemrrp_instance *instance);
  134. void (*iface_check) (
  135. struct totemrrp_instance *instance);
  136. void (*processor_count_set) (
  137. struct totemrrp_instance *instance,
  138. unsigned int processor_count);
  139. void (*token_target_set) (
  140. struct totemrrp_instance *instance,
  141. struct totem_ip_address *token_target,
  142. unsigned int iface_no);
  143. void (*ring_reenable) (
  144. struct totemrrp_instance *instance);
  145. };
  146. struct totemrrp_instance {
  147. hdb_handle_t totemrrp_poll_handle;
  148. struct totem_interface *interfaces;
  149. struct rrp_algo *rrp_algo;
  150. void *context;
  151. char *status[INTERFACE_MAX];
  152. void (*totemrrp_deliver_fn) (
  153. void *context,
  154. const void *msg,
  155. unsigned int msg_len);
  156. void (*totemrrp_iface_change_fn) (
  157. void *context,
  158. const struct totem_ip_address *iface_addr,
  159. unsigned int iface_no);
  160. void (*totemrrp_token_seqid_get) (
  161. const void *msg,
  162. unsigned int *seqid,
  163. unsigned int *token_is);
  164. unsigned int (*totemrrp_msgs_missing) (void);
  165. /*
  166. * Function and data used to log messages
  167. */
  168. int totemrrp_log_level_security;
  169. int totemrrp_log_level_error;
  170. int totemrrp_log_level_warning;
  171. int totemrrp_log_level_notice;
  172. int totemrrp_log_level_debug;
  173. int totemrrp_subsys_id;
  174. void (*totemrrp_log_printf) (int subsys, const char *function,
  175. const char *file, int line, unsigned int level, unsigned int rec_ident,
  176. const char *format, ...)__attribute__((format(printf, 7, 8)));
  177. hdb_handle_t handle;
  178. hdb_handle_t *net_handles;
  179. void *rrp_algo_instance;
  180. int interface_count;
  181. hdb_handle_t poll_handle;
  182. int processor_count;
  183. struct totem_config *totem_config;
  184. };
  185. /*
  186. * None Replication Forward Declerations
  187. */
  188. static void none_mcast_recv (
  189. struct totemrrp_instance *instance,
  190. unsigned int iface_no,
  191. void *context,
  192. const void *msg,
  193. unsigned int msg_len);
  194. static void none_mcast_noflush_send (
  195. struct totemrrp_instance *instance,
  196. const void *msg,
  197. unsigned int msg_len);
  198. static void none_mcast_flush_send (
  199. struct totemrrp_instance *instance,
  200. const void *msg,
  201. unsigned int msg_len);
  202. static void none_token_recv (
  203. struct totemrrp_instance *instance,
  204. unsigned int iface_no,
  205. void *context,
  206. const void *msg,
  207. unsigned int msg_len,
  208. unsigned int token_seqid);
  209. static void none_token_send (
  210. struct totemrrp_instance *instance,
  211. const void *msg,
  212. unsigned int msg_len);
  213. static void none_recv_flush (
  214. struct totemrrp_instance *instance);
  215. static void none_send_flush (
  216. struct totemrrp_instance *instance);
  217. static void none_iface_check (
  218. struct totemrrp_instance *instance);
  219. static void none_processor_count_set (
  220. struct totemrrp_instance *instance,
  221. unsigned int processor_count_set);
  222. static void none_token_target_set (
  223. struct totemrrp_instance *instance,
  224. struct totem_ip_address *token_target,
  225. unsigned int iface_no);
  226. static void none_ring_reenable (
  227. struct totemrrp_instance *instance);
  228. /*
  229. * Passive Replication Forward Declerations
  230. */
  231. static void *passive_instance_initialize (
  232. struct totemrrp_instance *rrp_instance,
  233. int interface_count);
  234. static void passive_mcast_recv (
  235. struct totemrrp_instance *instance,
  236. unsigned int iface_no,
  237. void *context,
  238. const void *msg,
  239. unsigned int msg_len);
  240. static void passive_mcast_noflush_send (
  241. struct totemrrp_instance *instance,
  242. const void *msg,
  243. unsigned int msg_len);
  244. static void passive_mcast_flush_send (
  245. struct totemrrp_instance *instance,
  246. const void *msg,
  247. unsigned int msg_len);
  248. static void passive_token_recv (
  249. struct totemrrp_instance *instance,
  250. unsigned int iface_no,
  251. void *context,
  252. const void *msg,
  253. unsigned int msg_len,
  254. unsigned int token_seqid);
  255. static void passive_token_send (
  256. struct totemrrp_instance *instance,
  257. const void *msg,
  258. unsigned int msg_len);
  259. static void passive_recv_flush (
  260. struct totemrrp_instance *instance);
  261. static void passive_send_flush (
  262. struct totemrrp_instance *instance);
  263. static void passive_iface_check (
  264. struct totemrrp_instance *instance);
  265. static void passive_processor_count_set (
  266. struct totemrrp_instance *instance,
  267. unsigned int processor_count_set);
  268. static void passive_token_target_set (
  269. struct totemrrp_instance *instance,
  270. struct totem_ip_address *token_target,
  271. unsigned int iface_no);
  272. static void passive_ring_reenable (
  273. struct totemrrp_instance *instance);
  274. /*
  275. * Active Replication Forward Definitions
  276. */
  277. static void *active_instance_initialize (
  278. struct totemrrp_instance *rrp_instance,
  279. int interface_count);
  280. static void active_mcast_recv (
  281. struct totemrrp_instance *instance,
  282. unsigned int iface_no,
  283. void *context,
  284. const void *msg,
  285. unsigned int msg_len);
  286. static void active_mcast_noflush_send (
  287. struct totemrrp_instance *instance,
  288. const void *msg,
  289. unsigned int msg_len);
  290. static void active_mcast_flush_send (
  291. struct totemrrp_instance *instance,
  292. const void *msg,
  293. unsigned int msg_len);
  294. static void active_token_recv (
  295. struct totemrrp_instance *instance,
  296. unsigned int iface_no,
  297. void *context,
  298. const void *msg,
  299. unsigned int msg_len,
  300. unsigned int token_seqid);
  301. static void active_token_send (
  302. struct totemrrp_instance *instance,
  303. const void *msg,
  304. unsigned int msg_len);
  305. static void active_recv_flush (
  306. struct totemrrp_instance *instance);
  307. static void active_send_flush (
  308. struct totemrrp_instance *instance);
  309. static void active_iface_check (
  310. struct totemrrp_instance *instance);
  311. static void active_processor_count_set (
  312. struct totemrrp_instance *instance,
  313. unsigned int processor_count_set);
  314. static void active_token_target_set (
  315. struct totemrrp_instance *instance,
  316. struct totem_ip_address *token_target,
  317. unsigned int iface_no);
  318. static void active_ring_reenable (
  319. struct totemrrp_instance *instance);
  320. static void active_timer_expired_token_start (
  321. struct active_instance *active_instance);
  322. static void active_timer_expired_token_cancel (
  323. struct active_instance *active_instance);
  324. static void active_timer_problem_decrementer_start (
  325. struct active_instance *active_instance);
  326. static void active_timer_problem_decrementer_cancel (
  327. struct active_instance *active_instance);
  328. struct rrp_algo none_algo = {
  329. .name = "none",
  330. .initialize = NULL,
  331. .mcast_recv = none_mcast_recv,
  332. .mcast_noflush_send = none_mcast_noflush_send,
  333. .mcast_flush_send = none_mcast_flush_send,
  334. .token_recv = none_token_recv,
  335. .token_send = none_token_send,
  336. .recv_flush = none_recv_flush,
  337. .send_flush = none_send_flush,
  338. .iface_check = none_iface_check,
  339. .processor_count_set = none_processor_count_set,
  340. .token_target_set = none_token_target_set,
  341. .ring_reenable = none_ring_reenable
  342. };
  343. struct rrp_algo passive_algo = {
  344. .name = "passive",
  345. .initialize = passive_instance_initialize,
  346. .mcast_recv = passive_mcast_recv,
  347. .mcast_noflush_send = passive_mcast_noflush_send,
  348. .mcast_flush_send = passive_mcast_flush_send,
  349. .token_recv = passive_token_recv,
  350. .token_send = passive_token_send,
  351. .recv_flush = passive_recv_flush,
  352. .send_flush = passive_send_flush,
  353. .iface_check = passive_iface_check,
  354. .processor_count_set = passive_processor_count_set,
  355. .token_target_set = passive_token_target_set,
  356. .ring_reenable = passive_ring_reenable
  357. };
  358. struct rrp_algo active_algo = {
  359. .name = "active",
  360. .initialize = active_instance_initialize,
  361. .mcast_recv = active_mcast_recv,
  362. .mcast_noflush_send = active_mcast_noflush_send,
  363. .mcast_flush_send = active_mcast_flush_send,
  364. .token_recv = active_token_recv,
  365. .token_send = active_token_send,
  366. .recv_flush = active_recv_flush,
  367. .send_flush = active_send_flush,
  368. .iface_check = active_iface_check,
  369. .processor_count_set = active_processor_count_set,
  370. .token_target_set = active_token_target_set,
  371. .ring_reenable = active_ring_reenable
  372. };
  373. struct rrp_algo *rrp_algos[] = {
  374. &none_algo,
  375. &passive_algo,
  376. &active_algo
  377. };
  378. #define RRP_ALGOS_COUNT 3
  379. /*
  380. * All instances in one database
  381. */
  382. DECLARE_HDB_DATABASE (totemrrp_instance_database,NULL);
  383. #define log_printf(level, format, args...) \
  384. do { \
  385. rrp_instance->totemrrp_log_printf ( \
  386. rrp_instance->totemrrp_subsys_id, \
  387. __FUNCTION__, __FILE__, __LINE__, level, \
  388. LOGSYS_RECID_LOG, format, ##args); \
  389. } while (0);
  390. /*
  391. * None Replication Implementation
  392. */
  393. static void none_mcast_recv (
  394. struct totemrrp_instance *rrp_instance,
  395. unsigned int iface_no,
  396. void *context,
  397. const void *msg,
  398. unsigned int msg_len)
  399. {
  400. rrp_instance->totemrrp_deliver_fn (
  401. context,
  402. msg,
  403. msg_len);
  404. }
  405. static void none_mcast_flush_send (
  406. struct totemrrp_instance *instance,
  407. const void *msg,
  408. unsigned int msg_len)
  409. {
  410. totemnet_mcast_flush_send (instance->net_handles[0], msg, msg_len);
  411. }
  412. static void none_mcast_noflush_send (
  413. struct totemrrp_instance *instance,
  414. const void *msg,
  415. unsigned int msg_len)
  416. {
  417. totemnet_mcast_noflush_send (instance->net_handles[0], msg, msg_len);
  418. }
  419. static void none_token_recv (
  420. struct totemrrp_instance *rrp_instance,
  421. unsigned int iface_no,
  422. void *context,
  423. const void *msg,
  424. unsigned int msg_len,
  425. unsigned int token_seq)
  426. {
  427. rrp_instance->totemrrp_deliver_fn (
  428. context,
  429. msg,
  430. msg_len);
  431. }
  432. static void none_token_send (
  433. struct totemrrp_instance *instance,
  434. const void *msg,
  435. unsigned int msg_len)
  436. {
  437. totemnet_token_send (
  438. instance->net_handles[0],
  439. msg, msg_len);
  440. }
  441. static void none_recv_flush (struct totemrrp_instance *instance)
  442. {
  443. totemnet_recv_flush (instance->net_handles[0]);
  444. }
  445. static void none_send_flush (struct totemrrp_instance *instance)
  446. {
  447. totemnet_send_flush (instance->net_handles[0]);
  448. }
  449. static void none_iface_check (struct totemrrp_instance *instance)
  450. {
  451. totemnet_iface_check (instance->net_handles[0]);
  452. }
  453. static void none_processor_count_set (
  454. struct totemrrp_instance *instance,
  455. unsigned int processor_count)
  456. {
  457. totemnet_processor_count_set (instance->net_handles[0],
  458. processor_count);
  459. }
  460. static void none_token_target_set (
  461. struct totemrrp_instance *instance,
  462. struct totem_ip_address *token_target,
  463. unsigned int iface_no)
  464. {
  465. totemnet_token_target_set (instance->net_handles[0], token_target);
  466. }
  467. static void none_ring_reenable (
  468. struct totemrrp_instance *instance)
  469. {
  470. /*
  471. * No operation
  472. */
  473. }
  474. /*
  475. * Passive Replication Implementation
  476. */
  477. void *passive_instance_initialize (
  478. struct totemrrp_instance *rrp_instance,
  479. int interface_count)
  480. {
  481. struct passive_instance *instance;
  482. instance = malloc (sizeof (struct passive_instance));
  483. if (instance == 0) {
  484. goto error_exit;
  485. }
  486. memset (instance, 0, sizeof (struct passive_instance));
  487. instance->faulty = malloc (sizeof (int) * interface_count);
  488. if (instance->faulty == 0) {
  489. free (instance);
  490. instance = 0;
  491. goto error_exit;
  492. }
  493. memset (instance->faulty, 0, sizeof (int) * interface_count);
  494. instance->token_recv_count = malloc (sizeof (int) * interface_count);
  495. if (instance->token_recv_count == 0) {
  496. free (instance->faulty);
  497. free (instance);
  498. instance = 0;
  499. goto error_exit;
  500. }
  501. memset (instance->token_recv_count, 0, sizeof (int) * interface_count);
  502. instance->mcast_recv_count = malloc (sizeof (int) * interface_count);
  503. if (instance->mcast_recv_count == 0) {
  504. free (instance->token_recv_count);
  505. free (instance->faulty);
  506. free (instance);
  507. instance = 0;
  508. goto error_exit;
  509. }
  510. memset (instance->mcast_recv_count, 0, sizeof (int) * interface_count);
  511. error_exit:
  512. return ((void *)instance);
  513. }
  514. static void timer_function_passive_token_expired (void *context)
  515. {
  516. struct passive_instance *passive_instance = (struct passive_instance *)context;
  517. struct totemrrp_instance *rrp_instance = passive_instance->rrp_instance;
  518. rrp_instance->totemrrp_deliver_fn (
  519. passive_instance->totemrrp_context,
  520. passive_instance->token,
  521. passive_instance->token_len);
  522. }
  523. /* TODO
  524. static void timer_function_passive_problem_decrementer (void *context)
  525. {
  526. // struct passive_instance *passive_instance = (struct passive_instance *)context;
  527. // struct totemrrp_instance *rrp_instance = passive_instance->rrp_instance;
  528. }
  529. */
  530. static void passive_timer_expired_token_start (
  531. struct passive_instance *passive_instance)
  532. {
  533. poll_timer_add (
  534. passive_instance->rrp_instance->poll_handle,
  535. passive_instance->rrp_instance->totem_config->rrp_token_expired_timeout,
  536. (void *)passive_instance,
  537. timer_function_passive_token_expired,
  538. &passive_instance->timer_expired_token);
  539. }
  540. static void passive_timer_expired_token_cancel (
  541. struct passive_instance *passive_instance)
  542. {
  543. poll_timer_delete (
  544. passive_instance->rrp_instance->poll_handle,
  545. passive_instance->timer_expired_token);
  546. }
  547. /*
  548. static void passive_timer_problem_decrementer_start (
  549. struct passive_instance *passive_instance)
  550. {
  551. poll_timer_add (
  552. passive_instance->rrp_instance->poll_handle,
  553. passive_instance->rrp_instance->totem_config->rrp_problem_count_timeout,
  554. (void *)passive_instance,
  555. timer_function_passive_problem_decrementer,
  556. &passive_instance->timer_problem_decrementer);
  557. }
  558. static void passive_timer_problem_decrementer_cancel (
  559. struct passive_instance *passive_instance)
  560. {
  561. poll_timer_delete (
  562. passive_instance->rrp_instance->poll_handle,
  563. passive_instance->timer_problem_decrementer);
  564. }
  565. */
  566. static void passive_mcast_recv (
  567. struct totemrrp_instance *rrp_instance,
  568. unsigned int iface_no,
  569. void *context,
  570. const void *msg,
  571. unsigned int msg_len)
  572. {
  573. struct passive_instance *passive_instance = (struct passive_instance *)rrp_instance->rrp_algo_instance;
  574. unsigned int max;
  575. unsigned int i;
  576. rrp_instance->totemrrp_deliver_fn (
  577. context,
  578. msg,
  579. msg_len);
  580. if (rrp_instance->totemrrp_msgs_missing() == 0 &&
  581. passive_instance->timer_expired_token) {
  582. /*
  583. * Delivers the last token
  584. */
  585. rrp_instance->totemrrp_deliver_fn (
  586. passive_instance->totemrrp_context,
  587. passive_instance->token,
  588. passive_instance->token_len);
  589. passive_timer_expired_token_cancel (passive_instance);
  590. }
  591. /*
  592. * Monitor for failures
  593. * TODO doesn't handle wrap-around of the mcast recv count
  594. */
  595. passive_instance->mcast_recv_count[iface_no] += 1;
  596. max = 0;
  597. for (i = 0; i < rrp_instance->interface_count; i++) {
  598. if (max < passive_instance->mcast_recv_count[i]) {
  599. max = passive_instance->mcast_recv_count[i];
  600. }
  601. }
  602. for (i = 0; i < rrp_instance->interface_count; i++) {
  603. if ((passive_instance->faulty[i] == 0) &&
  604. (max - passive_instance->mcast_recv_count[i] >
  605. rrp_instance->totem_config->rrp_problem_count_threshold)) {
  606. passive_instance->faulty[i] = 1;
  607. sprintf (rrp_instance->status[i],
  608. "Marking ringid %u interface %s FAULTY - adminisrtative intervention required.",
  609. i,
  610. totemnet_iface_print (rrp_instance->net_handles[i]));
  611. log_printf (
  612. rrp_instance->totemrrp_log_level_error,
  613. "%s",
  614. rrp_instance->status[i]);
  615. }
  616. }
  617. }
  618. static void passive_mcast_flush_send (
  619. struct totemrrp_instance *instance,
  620. const void *msg,
  621. unsigned int msg_len)
  622. {
  623. struct passive_instance *passive_instance = (struct passive_instance *)instance->rrp_algo_instance;
  624. do {
  625. passive_instance->msg_xmit_iface = (passive_instance->msg_xmit_iface + 1) % instance->interface_count;
  626. } while (passive_instance->faulty[passive_instance->msg_xmit_iface] == 1);
  627. totemnet_mcast_flush_send (instance->net_handles[passive_instance->msg_xmit_iface], msg, msg_len);
  628. }
  629. static void passive_mcast_noflush_send (
  630. struct totemrrp_instance *instance,
  631. const void *msg,
  632. unsigned int msg_len)
  633. {
  634. struct passive_instance *passive_instance = (struct passive_instance *)instance->rrp_algo_instance;
  635. do {
  636. passive_instance->msg_xmit_iface = (passive_instance->msg_xmit_iface + 1) % instance->interface_count;
  637. } while (passive_instance->faulty[passive_instance->msg_xmit_iface] == 1);
  638. totemnet_mcast_noflush_send (instance->net_handles[passive_instance->msg_xmit_iface], msg, msg_len);
  639. }
  640. static void passive_token_recv (
  641. struct totemrrp_instance *rrp_instance,
  642. unsigned int iface_no,
  643. void *context,
  644. const void *msg,
  645. unsigned int msg_len,
  646. unsigned int token_seq)
  647. {
  648. struct passive_instance *passive_instance = (struct passive_instance *)rrp_instance->rrp_algo_instance;
  649. unsigned int max;
  650. unsigned int i;
  651. passive_instance->totemrrp_context = context; // this should be in totemrrp_instance ? TODO
  652. if (rrp_instance->totemrrp_msgs_missing() == 0) {
  653. rrp_instance->totemrrp_deliver_fn (
  654. context,
  655. msg,
  656. msg_len);
  657. } else {
  658. memcpy (passive_instance->token, msg, msg_len);
  659. passive_timer_expired_token_start (passive_instance);
  660. }
  661. /*
  662. * Monitor for failures
  663. * TODO doesn't handle wrap-around of the token
  664. */
  665. passive_instance->token_recv_count[iface_no] += 1;
  666. max = 0;
  667. for (i = 0; i < rrp_instance->interface_count; i++) {
  668. if (max < passive_instance->token_recv_count[i]) {
  669. max = passive_instance->token_recv_count[i];
  670. }
  671. }
  672. for (i = 0; i < rrp_instance->interface_count; i++) {
  673. if ((passive_instance->faulty[i] == 0) &&
  674. (max - passive_instance->token_recv_count[i] >
  675. rrp_instance->totem_config->rrp_problem_count_threshold)) {
  676. passive_instance->faulty[i] = 1;
  677. sprintf (rrp_instance->status[i],
  678. "Marking seqid %d ringid %u interface %s FAULTY - adminisrtative intervention required.",
  679. token_seq,
  680. i,
  681. totemnet_iface_print (rrp_instance->net_handles[i]));
  682. log_printf (
  683. rrp_instance->totemrrp_log_level_error,
  684. "%s",
  685. rrp_instance->status[i]);
  686. }
  687. }
  688. }
  689. static void passive_token_send (
  690. struct totemrrp_instance *instance,
  691. const void *msg,
  692. unsigned int msg_len)
  693. {
  694. struct passive_instance *passive_instance = (struct passive_instance *)instance->rrp_algo_instance;
  695. do {
  696. passive_instance->token_xmit_iface = (passive_instance->token_xmit_iface + 1) % instance->interface_count;
  697. } while (passive_instance->faulty[passive_instance->token_xmit_iface] == 1);
  698. totemnet_token_send (
  699. instance->net_handles[passive_instance->token_xmit_iface],
  700. msg, msg_len);
  701. }
  702. static void passive_recv_flush (struct totemrrp_instance *instance)
  703. {
  704. struct passive_instance *rrp_algo_instance = (struct passive_instance *)instance->rrp_algo_instance;
  705. unsigned int i;
  706. for (i = 0; i < instance->interface_count; i++) {
  707. if (rrp_algo_instance->faulty[i] == 0) {
  708. totemnet_recv_flush (instance->net_handles[i]);
  709. }
  710. }
  711. }
  712. static void passive_send_flush (struct totemrrp_instance *instance)
  713. {
  714. struct passive_instance *rrp_algo_instance = (struct passive_instance *)instance->rrp_algo_instance;
  715. unsigned int i;
  716. for (i = 0; i < instance->interface_count; i++) {
  717. if (rrp_algo_instance->faulty[i] == 0) {
  718. totemnet_send_flush (instance->net_handles[i]);
  719. }
  720. }
  721. }
  722. static void passive_iface_check (struct totemrrp_instance *instance)
  723. {
  724. struct passive_instance *rrp_algo_instance = (struct passive_instance *)instance->rrp_algo_instance;
  725. unsigned int i;
  726. for (i = 0; i < instance->interface_count; i++) {
  727. if (rrp_algo_instance->faulty[i] == 0) {
  728. totemnet_iface_check (instance->net_handles[i]);
  729. }
  730. }
  731. }
  732. static void passive_processor_count_set (
  733. struct totemrrp_instance *instance,
  734. unsigned int processor_count)
  735. {
  736. struct passive_instance *rrp_algo_instance = (struct passive_instance *)instance->rrp_algo_instance;
  737. unsigned int i;
  738. for (i = 0; i < instance->interface_count; i++) {
  739. if (rrp_algo_instance->faulty[i] == 0) {
  740. totemnet_processor_count_set (instance->net_handles[i],
  741. processor_count);
  742. }
  743. }
  744. }
  745. static void passive_token_target_set (
  746. struct totemrrp_instance *instance,
  747. struct totem_ip_address *token_target,
  748. unsigned int iface_no)
  749. {
  750. totemnet_token_target_set (instance->net_handles[iface_no], token_target);
  751. }
  752. static void passive_ring_reenable (
  753. struct totemrrp_instance *instance)
  754. {
  755. struct passive_instance *rrp_algo_instance = (struct passive_instance *)instance->rrp_algo_instance;
  756. memset (rrp_algo_instance->mcast_recv_count, 0, sizeof (unsigned int) *
  757. instance->interface_count);
  758. memset (rrp_algo_instance->token_recv_count, 0, sizeof (unsigned int) *
  759. instance->interface_count);
  760. memset (rrp_algo_instance->faulty, 0, sizeof (unsigned int) *
  761. instance->interface_count);
  762. }
  763. /*
  764. * Active Replication Implementation
  765. */
  766. void *active_instance_initialize (
  767. struct totemrrp_instance *rrp_instance,
  768. int interface_count)
  769. {
  770. struct active_instance *instance;
  771. instance = malloc (sizeof (struct active_instance));
  772. if (instance == 0) {
  773. goto error_exit;
  774. }
  775. memset (instance, 0, sizeof (struct active_instance));
  776. instance->faulty = malloc (sizeof (int) * interface_count);
  777. if (instance->faulty == 0) {
  778. free (instance);
  779. instance = 0;
  780. goto error_exit;
  781. }
  782. memset (instance->faulty, 0, sizeof (unsigned int) * interface_count);
  783. instance->last_token_recv = malloc (sizeof (int) * interface_count);
  784. if (instance->last_token_recv == 0) {
  785. free (instance->faulty);
  786. free (instance);
  787. instance = 0;
  788. goto error_exit;
  789. }
  790. memset (instance->last_token_recv, 0, sizeof (unsigned int) * interface_count);
  791. instance->counter_problems = malloc (sizeof (int) * interface_count);
  792. if (instance->counter_problems == 0) {
  793. free (instance->last_token_recv);
  794. free (instance->faulty);
  795. free (instance);
  796. instance = 0;
  797. goto error_exit;
  798. }
  799. memset (instance->counter_problems, 0, sizeof (unsigned int) * interface_count);
  800. instance->timer_expired_token = 0;
  801. instance->timer_problem_decrementer = 0;
  802. instance->rrp_instance = rrp_instance;
  803. error_exit:
  804. return ((void *)instance);
  805. }
  806. static void timer_function_active_problem_decrementer (void *context)
  807. {
  808. struct active_instance *active_instance = (struct active_instance *)context;
  809. struct totemrrp_instance *rrp_instance = active_instance->rrp_instance;
  810. unsigned int problem_found = 0;
  811. unsigned int i;
  812. for (i = 0; i < rrp_instance->interface_count; i++) {
  813. if (active_instance->counter_problems[i] > 0) {
  814. problem_found = 1;
  815. active_instance->counter_problems[i] -= 1;
  816. if (active_instance->counter_problems[i] == 0) {
  817. sprintf (rrp_instance->status[i],
  818. "ring %d active with no faults", i);
  819. } else {
  820. sprintf (rrp_instance->status[i],
  821. "Decrementing problem counter for iface %s to [%d of %d]",
  822. totemnet_iface_print (rrp_instance->net_handles[i]),
  823. active_instance->counter_problems[i],
  824. rrp_instance->totem_config->rrp_problem_count_threshold);
  825. }
  826. log_printf (
  827. rrp_instance->totemrrp_log_level_warning,
  828. "%s",
  829. rrp_instance->status[i]);
  830. }
  831. }
  832. if (problem_found) {
  833. active_timer_problem_decrementer_start (active_instance);
  834. } else {
  835. active_instance->timer_problem_decrementer = 0;
  836. }
  837. }
  838. static void timer_function_active_token_expired (void *context)
  839. {
  840. struct active_instance *active_instance = (struct active_instance *)context;
  841. struct totemrrp_instance *rrp_instance = active_instance->rrp_instance;
  842. unsigned int i;
  843. for (i = 0; i < rrp_instance->interface_count; i++) {
  844. if (active_instance->last_token_recv[i] == 0) {
  845. active_instance->counter_problems[i] += 1;
  846. if (active_instance->timer_problem_decrementer == 0) {
  847. active_timer_problem_decrementer_start (active_instance);
  848. }
  849. sprintf (rrp_instance->status[i],
  850. "Incrementing problem counter for seqid %d iface %s to [%d of %d]",
  851. active_instance->last_token_seq,
  852. totemnet_iface_print (rrp_instance->net_handles[i]),
  853. active_instance->counter_problems[i],
  854. rrp_instance->totem_config->rrp_problem_count_threshold);
  855. log_printf (
  856. rrp_instance->totemrrp_log_level_warning,
  857. "%s",
  858. rrp_instance->status[i]);
  859. }
  860. }
  861. for (i = 0; i < rrp_instance->interface_count; i++) {
  862. if (active_instance->counter_problems[i] >= rrp_instance->totem_config->rrp_problem_count_threshold)
  863. {
  864. active_instance->faulty[i] = 1;
  865. sprintf (rrp_instance->status[i],
  866. "Marking seqid %d ringid %u interface %s FAULTY - adminisrtative intervention required.",
  867. active_instance->last_token_seq,
  868. i,
  869. totemnet_iface_print (rrp_instance->net_handles[i]));
  870. log_printf (
  871. rrp_instance->totemrrp_log_level_error,
  872. "%s",
  873. rrp_instance->status[i]);
  874. active_timer_problem_decrementer_cancel (active_instance);
  875. }
  876. }
  877. rrp_instance->totemrrp_deliver_fn (
  878. active_instance->totemrrp_context,
  879. active_instance->token,
  880. active_instance->token_len);
  881. }
  882. static void active_timer_expired_token_start (
  883. struct active_instance *active_instance)
  884. {
  885. poll_timer_add (
  886. active_instance->rrp_instance->poll_handle,
  887. active_instance->rrp_instance->totem_config->rrp_token_expired_timeout,
  888. (void *)active_instance,
  889. timer_function_active_token_expired,
  890. &active_instance->timer_expired_token);
  891. }
  892. static void active_timer_expired_token_cancel (
  893. struct active_instance *active_instance)
  894. {
  895. poll_timer_delete (
  896. active_instance->rrp_instance->poll_handle,
  897. active_instance->timer_expired_token);
  898. }
  899. static void active_timer_problem_decrementer_start (
  900. struct active_instance *active_instance)
  901. {
  902. poll_timer_add (
  903. active_instance->rrp_instance->poll_handle,
  904. active_instance->rrp_instance->totem_config->rrp_problem_count_timeout,
  905. (void *)active_instance,
  906. timer_function_active_problem_decrementer,
  907. &active_instance->timer_problem_decrementer);
  908. }
  909. static void active_timer_problem_decrementer_cancel (
  910. struct active_instance *active_instance)
  911. {
  912. poll_timer_delete (
  913. active_instance->rrp_instance->poll_handle,
  914. active_instance->timer_problem_decrementer);
  915. }
  916. /*
  917. * active replication
  918. */
  919. static void active_mcast_recv (
  920. struct totemrrp_instance *instance,
  921. unsigned int iface_no,
  922. void *context,
  923. const void *msg,
  924. unsigned int msg_len)
  925. {
  926. instance->totemrrp_deliver_fn (
  927. context,
  928. msg,
  929. msg_len);
  930. }
  931. static void active_mcast_flush_send (
  932. struct totemrrp_instance *instance,
  933. const void *msg,
  934. unsigned int msg_len)
  935. {
  936. int i;
  937. struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
  938. for (i = 0; i < instance->interface_count; i++) {
  939. if (rrp_algo_instance->faulty[i] == 0) {
  940. totemnet_mcast_flush_send (instance->net_handles[i], msg, msg_len);
  941. }
  942. }
  943. }
  944. static void active_mcast_noflush_send (
  945. struct totemrrp_instance *instance,
  946. const void *msg,
  947. unsigned int msg_len)
  948. {
  949. int i;
  950. struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
  951. for (i = 0; i < instance->interface_count; i++) {
  952. if (rrp_algo_instance->faulty[i] == 0) {
  953. totemnet_mcast_noflush_send (instance->net_handles[i], msg, msg_len);
  954. }
  955. }
  956. }
  957. static void active_token_recv (
  958. struct totemrrp_instance *instance,
  959. unsigned int iface_no,
  960. void *context,
  961. const void *msg,
  962. unsigned int msg_len,
  963. unsigned int token_seq)
  964. {
  965. int i;
  966. struct active_instance *active_instance = (struct active_instance *)instance->rrp_algo_instance;
  967. active_instance->totemrrp_context = context; // this should be in totemrrp_instance ?
  968. if (token_seq > active_instance->last_token_seq) {
  969. memcpy (active_instance->token, msg, msg_len);
  970. active_instance->token_len = msg_len;
  971. for (i = 0; i < instance->interface_count; i++) {
  972. active_instance->last_token_recv[i] = 0;
  973. }
  974. active_instance->last_token_recv[iface_no] = 1;
  975. active_timer_expired_token_start (active_instance);
  976. }
  977. active_instance->last_token_seq = token_seq;
  978. if (token_seq == active_instance->last_token_seq) {
  979. active_instance->last_token_recv[iface_no] = 1;
  980. for (i = 0; i < instance->interface_count; i++) {
  981. if ((active_instance->last_token_recv[i] == 0) &&
  982. active_instance->faulty[i] == 0) {
  983. return; /* don't deliver token */
  984. }
  985. }
  986. active_timer_expired_token_cancel (active_instance);
  987. instance->totemrrp_deliver_fn (
  988. context,
  989. msg,
  990. msg_len);
  991. }
  992. }
  993. static void active_token_send (
  994. struct totemrrp_instance *instance,
  995. const void *msg,
  996. unsigned int msg_len)
  997. {
  998. struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
  999. int i;
  1000. for (i = 0; i < instance->interface_count; i++) {
  1001. if (rrp_algo_instance->faulty[i] == 0) {
  1002. totemnet_token_send (
  1003. instance->net_handles[i],
  1004. msg, msg_len);
  1005. }
  1006. }
  1007. }
  1008. static void active_recv_flush (struct totemrrp_instance *instance)
  1009. {
  1010. struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
  1011. unsigned int i;
  1012. for (i = 0; i < instance->interface_count; i++) {
  1013. if (rrp_algo_instance->faulty[i] == 0) {
  1014. totemnet_recv_flush (instance->net_handles[i]);
  1015. }
  1016. }
  1017. }
  1018. static void active_send_flush (struct totemrrp_instance *instance)
  1019. {
  1020. struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
  1021. unsigned int i;
  1022. for (i = 0; i < instance->interface_count; i++) {
  1023. if (rrp_algo_instance->faulty[i] == 0) {
  1024. totemnet_send_flush (instance->net_handles[i]);
  1025. }
  1026. }
  1027. }
  1028. static void active_iface_check (struct totemrrp_instance *instance)
  1029. {
  1030. struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
  1031. unsigned int i;
  1032. for (i = 0; i < instance->interface_count; i++) {
  1033. if (rrp_algo_instance->faulty[i] == 0) {
  1034. totemnet_iface_check (instance->net_handles[i]);
  1035. }
  1036. }
  1037. }
  1038. static void active_processor_count_set (
  1039. struct totemrrp_instance *instance,
  1040. unsigned int processor_count)
  1041. {
  1042. struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
  1043. unsigned int i;
  1044. for (i = 0; i < instance->interface_count; i++) {
  1045. if (rrp_algo_instance->faulty[i] == 0) {
  1046. totemnet_processor_count_set (instance->net_handles[i],
  1047. processor_count);
  1048. }
  1049. }
  1050. }
  1051. static void active_token_target_set (
  1052. struct totemrrp_instance *instance,
  1053. struct totem_ip_address *token_target,
  1054. unsigned int iface_no)
  1055. {
  1056. totemnet_token_target_set (instance->net_handles[iface_no], token_target);
  1057. }
  1058. static void active_ring_reenable (
  1059. struct totemrrp_instance *instance)
  1060. {
  1061. struct active_instance *rrp_algo_instance = (struct active_instance *)instance->rrp_algo_instance;
  1062. memset (rrp_algo_instance->last_token_recv, 0, sizeof (unsigned int) *
  1063. instance->interface_count);
  1064. memset (rrp_algo_instance->faulty, 0, sizeof (unsigned int) *
  1065. instance->interface_count);
  1066. memset (rrp_algo_instance->counter_problems, 0, sizeof (unsigned int) *
  1067. instance->interface_count);
  1068. }
  1069. struct deliver_fn_context {
  1070. struct totemrrp_instance *instance;
  1071. void *context;
  1072. int iface_no;
  1073. };
  1074. static void totemrrp_instance_initialize (struct totemrrp_instance *instance)
  1075. {
  1076. memset (instance, 0, sizeof (struct totemrrp_instance));
  1077. }
  1078. static int totemrrp_algorithm_set (
  1079. struct totem_config *totem_config,
  1080. struct totemrrp_instance *instance)
  1081. {
  1082. unsigned int res = -1;
  1083. unsigned int i;
  1084. for (i = 0; i < RRP_ALGOS_COUNT; i++) {
  1085. if (strcmp (totem_config->rrp_mode, rrp_algos[i]->name) == 0) {
  1086. instance->rrp_algo = rrp_algos[i];
  1087. if (rrp_algos[i]->initialize) {
  1088. instance->rrp_algo_instance = rrp_algos[i]->initialize (
  1089. instance,
  1090. totem_config->interface_count);
  1091. }
  1092. res = 0;
  1093. break;
  1094. }
  1095. }
  1096. for (i = 0; i < totem_config->interface_count; i++) {
  1097. instance->status[i] = malloc (1024);
  1098. sprintf (instance->status[i], "ring %d active with no faults", i);
  1099. }
  1100. return (res);
  1101. }
  1102. void rrp_deliver_fn (
  1103. void *context,
  1104. const void *msg,
  1105. unsigned int msg_len)
  1106. {
  1107. unsigned int token_seqid;
  1108. unsigned int token_is;
  1109. struct deliver_fn_context *deliver_fn_context = (struct deliver_fn_context *)context;
  1110. deliver_fn_context->instance->totemrrp_token_seqid_get (
  1111. msg,
  1112. &token_seqid,
  1113. &token_is);
  1114. if (token_is) {
  1115. /*
  1116. * Deliver to the token receiver for this rrp algorithm
  1117. */
  1118. deliver_fn_context->instance->rrp_algo->token_recv (
  1119. deliver_fn_context->instance,
  1120. deliver_fn_context->iface_no,
  1121. deliver_fn_context->context,
  1122. msg,
  1123. msg_len,
  1124. token_seqid);
  1125. } else {
  1126. /*
  1127. * Deliver to the mcast receiver for this rrp algorithm
  1128. */
  1129. deliver_fn_context->instance->rrp_algo->mcast_recv (
  1130. deliver_fn_context->instance,
  1131. deliver_fn_context->iface_no,
  1132. deliver_fn_context->context,
  1133. msg,
  1134. msg_len);
  1135. }
  1136. }
  1137. void rrp_iface_change_fn (
  1138. void *context,
  1139. const struct totem_ip_address *iface_addr)
  1140. {
  1141. struct deliver_fn_context *deliver_fn_context = (struct deliver_fn_context *)context;
  1142. deliver_fn_context->instance->totemrrp_iface_change_fn (
  1143. deliver_fn_context->context,
  1144. iface_addr,
  1145. deliver_fn_context->iface_no);
  1146. }
  1147. int totemrrp_finalize (
  1148. hdb_handle_t handle)
  1149. {
  1150. struct totemrrp_instance *instance;
  1151. int res = 0;
  1152. int i;
  1153. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1154. (void *)&instance);
  1155. if (res != 0) {
  1156. res = ENOENT;
  1157. goto error_exit;
  1158. }
  1159. for (i = 0; i < instance->interface_count; i++) {
  1160. totemnet_finalize (instance->net_handles[i]);
  1161. }
  1162. hdb_handle_put (&totemrrp_instance_database, handle);
  1163. error_exit:
  1164. return (res);
  1165. }
  1166. /*
  1167. * Totem Redundant Ring interface
  1168. * depends on poll abstraction, POSIX, IPV4
  1169. */
  1170. /*
  1171. * Create an instance
  1172. */
  1173. int totemrrp_initialize (
  1174. hdb_handle_t poll_handle,
  1175. hdb_handle_t *handle,
  1176. struct totem_config *totem_config,
  1177. void *context,
  1178. void (*deliver_fn) (
  1179. void *context,
  1180. const void *msg,
  1181. unsigned int msg_len),
  1182. void (*iface_change_fn) (
  1183. void *context,
  1184. const struct totem_ip_address *iface_addr,
  1185. unsigned int iface_no),
  1186. void (*token_seqid_get) (
  1187. const void *msg,
  1188. unsigned int *seqid,
  1189. unsigned int *token_is),
  1190. unsigned int (*msgs_missing) (void))
  1191. {
  1192. struct totemrrp_instance *instance;
  1193. unsigned int res;
  1194. int i;
  1195. res = hdb_handle_create (&totemrrp_instance_database,
  1196. sizeof (struct totemrrp_instance), handle);
  1197. if (res != 0) {
  1198. goto error_exit;
  1199. }
  1200. res = hdb_handle_get (&totemrrp_instance_database, *handle,
  1201. (void *)&instance);
  1202. if (res != 0) {
  1203. goto error_destroy;
  1204. }
  1205. totemrrp_instance_initialize (instance);
  1206. instance->totem_config = totem_config;
  1207. res = totemrrp_algorithm_set (
  1208. instance->totem_config,
  1209. instance);
  1210. if (res == -1) {
  1211. goto error_put;
  1212. }
  1213. /*
  1214. * Configure logging
  1215. */
  1216. instance->totemrrp_log_level_security = totem_config->totem_logging_configuration.log_level_security;
  1217. instance->totemrrp_log_level_error = totem_config->totem_logging_configuration.log_level_error;
  1218. instance->totemrrp_log_level_warning = totem_config->totem_logging_configuration.log_level_warning;
  1219. instance->totemrrp_log_level_notice = totem_config->totem_logging_configuration.log_level_notice;
  1220. instance->totemrrp_log_level_debug = totem_config->totem_logging_configuration.log_level_debug;
  1221. instance->totemrrp_subsys_id = totem_config->totem_logging_configuration.log_subsys_id;
  1222. instance->totemrrp_log_printf = totem_config->totem_logging_configuration.log_printf;
  1223. instance->interfaces = totem_config->interfaces;
  1224. instance->totemrrp_poll_handle = poll_handle;
  1225. instance->totemrrp_deliver_fn = deliver_fn;
  1226. instance->totemrrp_iface_change_fn = iface_change_fn;
  1227. instance->totemrrp_token_seqid_get = token_seqid_get;
  1228. instance->totemrrp_msgs_missing = msgs_missing;
  1229. instance->interface_count = totem_config->interface_count;
  1230. instance->net_handles = malloc (sizeof (hdb_handle_t) * totem_config->interface_count);
  1231. instance->context = context;
  1232. instance->poll_handle = poll_handle;
  1233. for (i = 0; i < totem_config->interface_count; i++) {
  1234. struct deliver_fn_context *deliver_fn_context;
  1235. deliver_fn_context = malloc (sizeof (struct deliver_fn_context));
  1236. assert (deliver_fn_context);
  1237. deliver_fn_context->instance = instance;
  1238. deliver_fn_context->context = context;
  1239. deliver_fn_context->iface_no = i;
  1240. totemnet_initialize (
  1241. poll_handle,
  1242. &instance->net_handles[i],
  1243. totem_config,
  1244. i,
  1245. (void *)deliver_fn_context,
  1246. rrp_deliver_fn,
  1247. rrp_iface_change_fn);
  1248. }
  1249. totemnet_net_mtu_adjust (totem_config);
  1250. error_exit:
  1251. hdb_handle_put (&totemrrp_instance_database, *handle);
  1252. return (0);
  1253. error_put:
  1254. hdb_handle_put (&totemrrp_instance_database, *handle);
  1255. error_destroy:
  1256. hdb_handle_destroy (&totemrrp_instance_database, *handle);
  1257. return (res);
  1258. }
  1259. int totemrrp_processor_count_set (
  1260. hdb_handle_t handle,
  1261. unsigned int processor_count)
  1262. {
  1263. struct totemrrp_instance *instance;
  1264. int res = 0;
  1265. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1266. (void *)&instance);
  1267. if (res != 0) {
  1268. res = ENOENT;
  1269. goto error_exit;
  1270. }
  1271. instance->rrp_algo->processor_count_set (instance, processor_count);
  1272. instance->processor_count = processor_count;
  1273. hdb_handle_put (&totemrrp_instance_database, handle);
  1274. error_exit:
  1275. return (res);
  1276. }
  1277. int totemrrp_token_target_set (
  1278. hdb_handle_t handle,
  1279. struct totem_ip_address *addr,
  1280. unsigned int iface_no)
  1281. {
  1282. struct totemrrp_instance *instance;
  1283. int res = 0;
  1284. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1285. (void *)&instance);
  1286. if (res != 0) {
  1287. res = ENOENT;
  1288. goto error_exit;
  1289. }
  1290. instance->rrp_algo->token_target_set (instance, addr, iface_no);
  1291. hdb_handle_put (&totemrrp_instance_database, handle);
  1292. error_exit:
  1293. return (res);
  1294. }
  1295. int totemrrp_recv_flush (hdb_handle_t handle)
  1296. {
  1297. struct totemrrp_instance *instance;
  1298. int res = 0;
  1299. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1300. (void *)&instance);
  1301. if (res != 0) {
  1302. res = ENOENT;
  1303. goto error_exit;
  1304. }
  1305. instance->rrp_algo->recv_flush (instance);
  1306. hdb_handle_put (&totemrrp_instance_database, handle);
  1307. error_exit:
  1308. return (res);
  1309. }
  1310. int totemrrp_send_flush (hdb_handle_t handle)
  1311. {
  1312. struct totemrrp_instance *instance;
  1313. int res = 0;
  1314. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1315. (void *)&instance);
  1316. if (res != 0) {
  1317. res = ENOENT;
  1318. goto error_exit;
  1319. }
  1320. instance->rrp_algo->send_flush (instance);
  1321. hdb_handle_put (&totemrrp_instance_database, handle);
  1322. error_exit:
  1323. return (res);
  1324. }
  1325. int totemrrp_token_send (
  1326. hdb_handle_t handle,
  1327. const void *msg,
  1328. unsigned int msg_len)
  1329. {
  1330. struct totemrrp_instance *instance;
  1331. int res = 0;
  1332. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1333. (void *)&instance);
  1334. if (res != 0) {
  1335. res = ENOENT;
  1336. goto error_exit;
  1337. }
  1338. instance->rrp_algo->token_send (instance, msg, msg_len);
  1339. hdb_handle_put (&totemrrp_instance_database, handle);
  1340. error_exit:
  1341. return (res);
  1342. }
  1343. int totemrrp_mcast_flush_send (
  1344. hdb_handle_t handle,
  1345. const void *msg,
  1346. unsigned int msg_len)
  1347. {
  1348. struct totemrrp_instance *instance;
  1349. int res = 0;
  1350. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1351. (void *)&instance);
  1352. if (res != 0) {
  1353. res = ENOENT;
  1354. goto error_exit;
  1355. }
  1356. // TODO this needs to return the result
  1357. instance->rrp_algo->mcast_flush_send (instance, msg, msg_len);
  1358. hdb_handle_put (&totemrrp_instance_database, handle);
  1359. error_exit:
  1360. return (res);
  1361. }
  1362. int totemrrp_mcast_noflush_send (
  1363. hdb_handle_t handle,
  1364. const void *msg,
  1365. unsigned int msg_len)
  1366. {
  1367. struct totemrrp_instance *instance;
  1368. int res = 0;
  1369. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1370. (void *)&instance);
  1371. if (res != 0) {
  1372. res = ENOENT;
  1373. goto error_exit;
  1374. }
  1375. /*
  1376. * merge detects go out through mcast_flush_send so it is safe to
  1377. * flush these messages if we are only one processor. This avoids
  1378. * an encryption/hmac and decryption/hmac
  1379. */
  1380. if (instance->processor_count > 1) {
  1381. // TODO this needs to return the result
  1382. instance->rrp_algo->mcast_noflush_send (instance, msg, msg_len);
  1383. }
  1384. hdb_handle_put (&totemrrp_instance_database, handle);
  1385. error_exit:
  1386. return (res);
  1387. }
  1388. int totemrrp_iface_check (hdb_handle_t handle)
  1389. {
  1390. struct totemrrp_instance *instance;
  1391. int res = 0;
  1392. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1393. (void *)&instance);
  1394. if (res != 0) {
  1395. res = ENOENT;
  1396. goto error_exit;
  1397. }
  1398. instance->rrp_algo->iface_check (instance);
  1399. hdb_handle_put (&totemrrp_instance_database, handle);
  1400. error_exit:
  1401. return (res);
  1402. }
  1403. int totemrrp_ifaces_get (
  1404. hdb_handle_t handle,
  1405. char ***status,
  1406. unsigned int *iface_count)
  1407. {
  1408. struct totemrrp_instance *instance;
  1409. int res = 0;
  1410. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1411. (void *)&instance);
  1412. if (res != 0) {
  1413. res = ENOENT;
  1414. goto error_exit;
  1415. }
  1416. *status = instance->status;
  1417. if (iface_count) {
  1418. *iface_count = instance->interface_count;
  1419. }
  1420. hdb_handle_put (&totemrrp_instance_database, handle);
  1421. error_exit:
  1422. return (res);
  1423. }
  1424. int totemrrp_crypto_set (
  1425. hdb_handle_t handle,
  1426. unsigned int type)
  1427. {
  1428. int res;
  1429. struct totemrrp_instance *instance;
  1430. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1431. (void *)&instance);
  1432. if (res != 0) {
  1433. return (0);
  1434. }
  1435. res = totemnet_crypto_set(instance->net_handles[0], type);
  1436. hdb_handle_put (&totemrrp_instance_database, handle);
  1437. return (res);
  1438. }
  1439. int totemrrp_ring_reenable (
  1440. hdb_handle_t handle)
  1441. {
  1442. struct totemrrp_instance *instance;
  1443. int res = 0;
  1444. unsigned int i;
  1445. printf ("totemrrp ring reenable\n");
  1446. res = hdb_handle_get (&totemrrp_instance_database, handle,
  1447. (void *)&instance);
  1448. if (res != 0) {
  1449. res = ENOENT;
  1450. goto error_exit;
  1451. }
  1452. instance->rrp_algo->ring_reenable (instance);
  1453. for (i = 0; i < instance->interface_count; i++) {
  1454. sprintf (instance->status[i], "ring %d active with no faults", i);
  1455. }
  1456. hdb_handle_put (&totemrrp_instance_database, handle);
  1457. error_exit:
  1458. return (res);
  1459. }