totemrrp.c 40 KB

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