lck.c 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533
  1. /*
  2. * Copyright (c) 2003-2004 MontaVista Software, Inc.
  3. *
  4. * All rights reserved.
  5. *
  6. * Author: Steven Dake (sdake@mvista.com)
  7. *
  8. * This software licensed under BSD license, the text of which follows:
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * - Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. * - Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  32. * THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include <sys/types.h>
  35. #include <sys/uio.h>
  36. #include <sys/socket.h>
  37. #include <sys/un.h>
  38. #include <sys/time.h>
  39. #include <netinet/in.h>
  40. #include <unistd.h>
  41. #include <fcntl.h>
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include <errno.h>
  45. #include <signal.h>
  46. #include <arpa/inet.h>
  47. #include "../include/saAis.h"
  48. #include "../include/saLck.h"
  49. #include "../include/ipc_lck.h"
  50. #include "../include/list.h"
  51. #include "../include/queue.h"
  52. #include "../lcr/lcr_comp.h"
  53. #include "aispoll.h"
  54. #include "mempool.h"
  55. #include "util.h"
  56. #include "main.h"
  57. #include "totempg.h"
  58. #define LOG_SERVICE LOG_SERVICE_LCK
  59. #include "print.h"
  60. enum lck_message_req_types {
  61. MESSAGE_REQ_EXEC_LCK_RESOURCEOPEN = 0,
  62. MESSAGE_REQ_EXEC_LCK_RESOURCECLOSE = 1,
  63. MESSAGE_REQ_EXEC_LCK_RESOURCELOCK = 2,
  64. MESSAGE_REQ_EXEC_LCK_RESOURCEUNLOCK = 3,
  65. MESSAGE_REQ_EXEC_LCK_RESOURCELOCKORPHAN = 4,
  66. MESSAGE_REQ_EXEC_LCK_LOCKPURGE = 5
  67. };
  68. struct resource;
  69. struct resource_lock {
  70. SaLckLockModeT lock_mode;
  71. SaLckLockIdT lock_id;
  72. SaLckLockFlagsT lock_flags;
  73. SaLckWaiterSignalT waiter_signal;
  74. SaLckLockStatusT lock_status;
  75. SaTimeT timeout;
  76. struct resource *resource;
  77. int async_call;
  78. SaInvocationT invocation;
  79. struct message_source callback_source;
  80. struct message_source response_source;
  81. struct list_head list; /* locked resource lock list */
  82. struct list_head resource_list; /* resource locks on a resource */
  83. struct list_head resource_cleanup_list; /* cleanup data for resource locks */
  84. };
  85. struct resource {
  86. SaNameT name;
  87. int refcount;
  88. struct list_head list;
  89. struct list_head resource_lock_list_head;
  90. struct list_head pr_granted_list_head;
  91. struct list_head pr_pending_list_head;
  92. struct list_head ex_pending_list_head;
  93. struct resource_lock *ex_granted;
  94. };
  95. struct resource_cleanup {
  96. struct resource *resource;
  97. SaLckResourceHandleT resource_handle;
  98. struct list_head resource_lock_list_head;
  99. struct list_head list;
  100. };
  101. DECLARE_LIST_INIT(resource_list_head);
  102. static int lck_exec_init_fn (struct openais_config *);
  103. static int lck_exit_fn (struct conn_info *conn_info);
  104. static int lck_init_two_fn (struct conn_info *conn_info);
  105. static int message_handler_req_exec_lck_resourceopen (
  106. void *message,
  107. struct in_addr source_addr,
  108. int endian_conversion_required);
  109. static int message_handler_req_exec_lck_resourceclose (
  110. void *message,
  111. struct in_addr source_addr,
  112. int endian_conversion_required);
  113. static int message_handler_req_exec_lck_resourcelock (
  114. void *message,
  115. struct in_addr source_addr,
  116. int endian_conversion_required);
  117. static int message_handler_req_exec_lck_resourceunlock (
  118. void *message,
  119. struct in_addr source_addr,
  120. int endian_conversion_required);
  121. static int message_handler_req_exec_lck_resourcelockorphan (
  122. void *message,
  123. struct in_addr source_addr,
  124. int endian_conversion_required);
  125. static int message_handler_req_exec_lck_lockpurge (
  126. void *message,
  127. struct in_addr source_addr,
  128. int endian_conversion_required);
  129. static int message_handler_req_lib_lck_resourceopen (
  130. struct conn_info *conn_info,
  131. void *message);
  132. static int message_handler_req_lib_lck_resourceopenasync (
  133. struct conn_info *conn_info,
  134. void *message);
  135. static int message_handler_req_lib_lck_resourceclose (
  136. struct conn_info *conn_info,
  137. void *message);
  138. static int message_handler_req_lib_lck_resourcelock (
  139. struct conn_info *conn_info,
  140. void *message);
  141. static int message_handler_req_lib_lck_resourcelockasync (
  142. struct conn_info *conn_info,
  143. void *message);
  144. static int message_handler_req_lib_lck_resourceunlock (
  145. struct conn_info *conn_info,
  146. void *message);
  147. static int message_handler_req_lib_lck_resourceunlockasync (
  148. struct conn_info *conn_info,
  149. void *message);
  150. static int message_handler_req_lib_lck_lockpurge (
  151. struct conn_info *conn_info,
  152. void *message);
  153. static void lck_recovery_activate (void);
  154. static void lck_recovery_initialize (void);
  155. static int lck_recovery_process (void);
  156. static void lck_recovery_finalize();
  157. static void lck_recovery_abort(void);
  158. void resource_release (struct resource *resource);
  159. /*
  160. static struct list_head *recovery_lck_next = 0;
  161. static struct list_head *recovery_lck_section_next = 0;
  162. static int recovery_section_data_offset = 0;
  163. static int recovery_section_send_flag = 0;
  164. static int recovery_abort = 0;
  165. */
  166. static struct memb_ring_id saved_ring_id;
  167. static int lck_confchg_fn (
  168. enum totem_configuration_type configuration_type,
  169. struct in_addr *member_list, int member_list_entries,
  170. struct in_addr *left_list, int left_list_entries,
  171. struct in_addr *joined_list, int joined_list_entries,
  172. struct memb_ring_id *ring_id);
  173. /*
  174. * Executive Handler Definition
  175. */
  176. struct libais_handler lck_libais_handlers[] =
  177. {
  178. { /* 0 */
  179. .libais_handler_fn = message_handler_req_lib_lck_resourceopen,
  180. .response_size = sizeof (struct res_lib_lck_resourceopen),
  181. .response_id = MESSAGE_RES_LCK_RESOURCEOPEN,
  182. .flow_control = FLOW_CONTROL_REQUIRED
  183. },
  184. { /* 1 */
  185. .libais_handler_fn = message_handler_req_lib_lck_resourceopenasync,
  186. .response_size = sizeof (struct res_lib_lck_resourceopenasync),
  187. .response_id = MESSAGE_RES_LCK_RESOURCEOPENASYNC,
  188. .flow_control = FLOW_CONTROL_REQUIRED
  189. },
  190. { /* 2 */
  191. .libais_handler_fn = message_handler_req_lib_lck_resourceclose,
  192. .response_size = sizeof (struct res_lib_lck_resourceclose),
  193. .response_id = MESSAGE_RES_LCK_RESOURCECLOSE,
  194. .flow_control = FLOW_CONTROL_REQUIRED
  195. },
  196. { /* 3 */
  197. .libais_handler_fn = message_handler_req_lib_lck_resourcelock,
  198. .response_size = sizeof (struct res_lib_lck_resourcelock),
  199. .response_id = MESSAGE_RES_LCK_RESOURCELOCK,
  200. .flow_control = FLOW_CONTROL_REQUIRED
  201. },
  202. { /* 4 */
  203. .libais_handler_fn = message_handler_req_lib_lck_resourcelockasync,
  204. .response_size = sizeof (struct res_lib_lck_resourcelockasync),
  205. .response_id = MESSAGE_RES_LCK_RESOURCELOCKASYNC,
  206. .flow_control = FLOW_CONTROL_REQUIRED
  207. },
  208. { /* 5 */
  209. .libais_handler_fn = message_handler_req_lib_lck_resourceunlock,
  210. .response_size = sizeof (struct res_lib_lck_resourceunlock),
  211. .response_id = MESSAGE_RES_LCK_RESOURCELOCK,
  212. .flow_control = FLOW_CONTROL_REQUIRED
  213. },
  214. { /* 6 */
  215. .libais_handler_fn = message_handler_req_lib_lck_resourceunlockasync,
  216. .response_size = sizeof (struct res_lib_lck_resourceunlock),
  217. .response_id = MESSAGE_RES_LCK_RESOURCEUNLOCKASYNC,
  218. .flow_control = FLOW_CONTROL_REQUIRED
  219. },
  220. { /* 7 */
  221. .libais_handler_fn = message_handler_req_lib_lck_lockpurge,
  222. .response_size = sizeof (struct res_lib_lck_lockpurge),
  223. .response_id = MESSAGE_RES_LCK_LOCKPURGE,
  224. .flow_control = FLOW_CONTROL_REQUIRED
  225. }
  226. };
  227. static int (*lck_aisexec_handler_fns[]) (void *msg, struct in_addr source_addr, int endian_conversion_required) = {
  228. message_handler_req_exec_lck_resourceopen,
  229. message_handler_req_exec_lck_resourceclose,
  230. message_handler_req_exec_lck_resourcelock,
  231. message_handler_req_exec_lck_resourceunlock,
  232. message_handler_req_exec_lck_resourcelockorphan,
  233. message_handler_req_exec_lck_lockpurge,
  234. };
  235. struct service_handler lck_service_handler = {
  236. .name = "openais distributed locking service B.01.01",
  237. .id = LCK_SERVICE,
  238. .libais_handlers = lck_libais_handlers,
  239. .libais_handlers_count = sizeof (lck_libais_handlers) / sizeof (struct libais_handler),
  240. .aisexec_handler_fns = lck_aisexec_handler_fns,
  241. .aisexec_handler_fns_count = sizeof (lck_aisexec_handler_fns) / sizeof (int (*)),
  242. .confchg_fn = lck_confchg_fn,
  243. .libais_init_two_fn = lck_init_two_fn,
  244. .libais_exit_fn = lck_exit_fn,
  245. .exec_init_fn = lck_exec_init_fn,
  246. .exec_dump_fn = NULL,
  247. .sync_init = NULL, // TODO lck_recovery_initialize,
  248. .sync_process = lck_recovery_process,
  249. .sync_activate = lck_recovery_activate,
  250. .sync_abort = lck_recovery_abort,
  251. };
  252. #ifdef BUILD_DYNAMIC
  253. struct service_handler *lck_get_handler_ver0 (void);
  254. struct aisexec_iface_ver0 lck_service_handler_iface = {
  255. .test = NULL,
  256. .get_handler_ver0 = lck_get_handler_ver0
  257. };
  258. struct lcr_iface openais_lck_ver0[1] = {
  259. {
  260. .name = "openais_lck",
  261. .version = 0,
  262. .versions_replace = 0,
  263. .versions_replace_count = 0,
  264. .dependencies = 0,
  265. .dependency_count = 0,
  266. .constructor = NULL,
  267. .destructor = NULL,
  268. .interfaces = (void **)&lck_service_handler_iface,
  269. }
  270. };
  271. struct lcr_comp lck_comp_ver0 = {
  272. .iface_count = 1,
  273. .ifaces = openais_lck_ver0
  274. };
  275. extern int lcr_comp_get (struct lcr_comp **component)
  276. {
  277. *component = &lck_comp_ver0;
  278. return (0);
  279. }
  280. struct service_handler *lck_get_handler_ver0 (void)
  281. {
  282. return (&lck_service_handler);
  283. }
  284. #endif /* BUILD_DYNAMIC */
  285. /*
  286. * All data types used for executive messages
  287. */
  288. struct req_exec_lck_resourceopen {
  289. struct req_header header;
  290. struct message_source source;
  291. SaNameT resource_name;
  292. SaLckResourceHandleT resource_handle;
  293. SaInvocationT invocation;
  294. SaTimeT timeout;
  295. SaLckResourceOpenFlagsT open_flags;
  296. int async_call;
  297. SaAisErrorT fail_with_error;
  298. };
  299. struct req_exec_lck_resourceclose {
  300. struct req_header header;
  301. struct message_source source;
  302. SaNameT lockResourceName;
  303. SaLckResourceHandleT resource_handle;
  304. };
  305. struct req_exec_lck_resourcelock {
  306. struct req_header header;
  307. SaLckResourceHandleT resource_handle;
  308. SaInvocationT invocation;
  309. int async_call;
  310. SaAisErrorT fail_with_error;
  311. struct message_source source;
  312. struct req_lib_lck_resourcelock req_lib_lck_resourcelock;
  313. };
  314. struct req_exec_lck_resourceunlock {
  315. struct req_header header;
  316. struct message_source source;
  317. SaNameT resource_name;
  318. SaLckLockIdT lock_id;
  319. SaInvocationT invocation;
  320. SaTimeT timeout;
  321. int async_call;
  322. };
  323. struct req_exec_lck_resourcelockorphan {
  324. struct req_header header;
  325. struct message_source source;
  326. SaNameT resource_name;
  327. SaLckLockIdT lock_id;
  328. };
  329. struct req_exec_lck_lockpurge {
  330. struct req_header header;
  331. struct message_source source;
  332. struct req_lib_lck_lockpurge req_lib_lck_lockpurge;
  333. };
  334. static void lck_recovery_initialize (void)
  335. {
  336. return;
  337. }
  338. static int lck_recovery_process (void)
  339. {
  340. return (0);
  341. }
  342. static void lck_recovery_finalize ()
  343. {
  344. return;
  345. }
  346. static void lck_recovery_activate (void)
  347. {
  348. return;
  349. }
  350. static void lck_recovery_abort (void)
  351. {
  352. return;
  353. }
  354. static int lck_confchg_fn (
  355. enum totem_configuration_type configuration_type,
  356. struct in_addr *member_list, int member_list_entries,
  357. struct in_addr *left_list, int left_list_entries,
  358. struct in_addr *joined_list, int joined_list_entries,
  359. struct memb_ring_id *ring_id)
  360. {
  361. return (0);
  362. }
  363. static struct resource *resource_find (SaNameT *name)
  364. {
  365. struct list_head *resource_list;
  366. struct resource *resource;
  367. for (resource_list = resource_list_head.next;
  368. resource_list != &resource_list_head;
  369. resource_list = resource_list->next) {
  370. resource = list_entry (resource_list,
  371. struct resource, list);
  372. if (name_match (name, &resource->name)) {
  373. return (resource);
  374. }
  375. }
  376. return (0);
  377. }
  378. static struct resource_lock *resource_lock_find (
  379. struct resource *resource,
  380. struct message_source *source,
  381. SaLckLockIdT lock_id)
  382. {
  383. struct list_head *list;
  384. struct resource_lock *resource_lock;
  385. for (list = resource->resource_lock_list_head.next;
  386. list != &resource->resource_lock_list_head;
  387. list = list->next) {
  388. resource_lock = list_entry (list, struct resource_lock, resource_list);
  389. if ((memcmp (&resource_lock->callback_source,
  390. source, sizeof (struct message_source)) == 0) &&
  391. (lock_id == resource_lock->lock_id)) {
  392. return (resource_lock);
  393. }
  394. }
  395. return (0);
  396. }
  397. struct resource_cleanup *lck_resource_cleanup_find (
  398. struct conn_info *conn_info,
  399. SaLckResourceHandleT resource_handle)
  400. {
  401. struct list_head *list;
  402. struct resource_cleanup *resource_cleanup;
  403. for (list = conn_info->ais_ci.u.liblck_ci.resource_cleanup_list.next;
  404. list != &conn_info->ais_ci.u.liblck_ci.resource_cleanup_list;
  405. list = list->next) {
  406. resource_cleanup = list_entry (list, struct resource_cleanup, list);
  407. if (resource_cleanup->resource_handle == resource_handle) {
  408. return (resource_cleanup);
  409. }
  410. }
  411. return (0);
  412. }
  413. int lck_resource_close (struct resource *resource)
  414. {
  415. struct req_exec_lck_resourceclose req_exec_lck_resourceclose;
  416. struct iovec iovec;
  417. req_exec_lck_resourceclose.header.size =
  418. sizeof (struct req_exec_lck_resourceclose);
  419. req_exec_lck_resourceclose.header.id =
  420. SERVICE_ID_MAKE (LCK_SERVICE, MESSAGE_REQ_EXEC_LCK_RESOURCECLOSE);
  421. memcpy (&req_exec_lck_resourceclose.lockResourceName,
  422. &resource->name, sizeof (SaNameT));
  423. iovec.iov_base = (char *)&req_exec_lck_resourceclose;
  424. iovec.iov_len = sizeof (req_exec_lck_resourceclose);
  425. if (totempg_groups_send_ok_joined (openais_group_handle, &iovec, 1)) {
  426. assert (totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED) == 0);
  427. return (0);
  428. }
  429. return (-1);
  430. }
  431. void resource_lock_orphan (struct resource_lock *resource_lock)
  432. {
  433. struct req_exec_lck_resourcelockorphan req_exec_lck_resourcelockorphan;
  434. struct iovec iovec;
  435. req_exec_lck_resourcelockorphan.header.size =
  436. sizeof (struct req_exec_lck_resourcelockorphan);
  437. req_exec_lck_resourcelockorphan.header.id =
  438. SERVICE_ID_MAKE (LCK_SERVICE, MESSAGE_REQ_EXEC_LCK_RESOURCELOCKORPHAN);
  439. memcpy (&req_exec_lck_resourcelockorphan.source,
  440. &resource_lock->callback_source,
  441. sizeof (struct message_source));
  442. memcpy (&req_exec_lck_resourcelockorphan.resource_name,
  443. &resource_lock->resource->name,
  444. sizeof (SaNameT));
  445. req_exec_lck_resourcelockorphan.lock_id = resource_lock->lock_id;
  446. iovec.iov_base = (char *)&req_exec_lck_resourcelockorphan;
  447. iovec.iov_len = sizeof (req_exec_lck_resourcelockorphan);
  448. assert (totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED) == 0);
  449. // AAA
  450. }
  451. void lck_resource_cleanup_lock_remove (
  452. struct resource_cleanup *resource_cleanup)
  453. {
  454. struct list_head *list;
  455. struct resource_lock *resource_lock;
  456. for (list = resource_cleanup->resource_lock_list_head.next;
  457. list != &resource_cleanup->resource_lock_list_head;
  458. list = list->next) {
  459. resource_lock = list_entry (list, struct resource_lock, resource_cleanup_list);
  460. resource_lock_orphan (resource_lock);
  461. }
  462. }
  463. void lck_resource_cleanup_remove (
  464. struct conn_info *conn_info,
  465. SaLckResourceHandleT resource_handle)
  466. {
  467. struct list_head *list;
  468. struct resource_cleanup *resource_cleanup;
  469. for (list = conn_info->ais_ci.u.liblck_ci.resource_cleanup_list.next;
  470. list != &conn_info->ais_ci.u.liblck_ci.resource_cleanup_list;
  471. list = list->next) {
  472. resource_cleanup = list_entry (list, struct resource_cleanup, list);
  473. if (resource_cleanup->resource_handle == resource_handle) {
  474. list_del (&resource_cleanup->list);
  475. free (resource_cleanup);
  476. return;
  477. }
  478. }
  479. }
  480. static int lck_exec_init_fn (struct openais_config *openais_config)
  481. {
  482. /*
  483. * Initialize the saved ring ID.
  484. */
  485. #ifdef TODO
  486. saved_ring_id.seq = 0;
  487. saved_ring_id.rep.s_addr = this_ip->sin_addr.s_addr;
  488. #endif
  489. return (0);
  490. }
  491. static int lck_exit_fn (struct conn_info *conn_info)
  492. {
  493. struct resource_cleanup *resource_cleanup;
  494. struct list_head *list;
  495. if (conn_info->conn_info_partner->service != LCK_SERVICE) {
  496. return 0;
  497. }
  498. log_printf(LOG_LEVEL_NOTICE, "lck_exit_fn conn_info = %p, with fd = %d\n", conn_info, conn_info->fd);
  499. /*
  500. * close all resources opened on this fd
  501. */
  502. list = conn_info->conn_info_partner->ais_ci.u.liblck_ci.resource_cleanup_list.next;
  503. while (!list_empty(&conn_info->conn_info_partner->ais_ci.u.liblck_ci.resource_cleanup_list)) {
  504. resource_cleanup = list_entry (list, struct resource_cleanup, list);
  505. if (resource_cleanup->resource->name.length > 0) {
  506. lck_resource_cleanup_lock_remove (resource_cleanup);
  507. lck_resource_close (resource_cleanup->resource);
  508. }
  509. list_del (&resource_cleanup->list);
  510. free (resource_cleanup);
  511. list = conn_info->conn_info_partner->ais_ci.u.liblck_ci.resource_cleanup_list.next;
  512. }
  513. return (0);
  514. }
  515. static int lck_init_two_fn (struct conn_info *conn_info)
  516. {
  517. list_init (&conn_info->conn_info_partner->ais_ci.u.liblck_ci.resource_list);
  518. list_init (&conn_info->conn_info_partner->ais_ci.u.liblck_ci.resource_cleanup_list);
  519. return (0);
  520. }
  521. static int message_handler_req_exec_lck_resourceopen (
  522. void *message,
  523. struct in_addr source_addr,
  524. int endian_conversion_required)
  525. {
  526. struct req_exec_lck_resourceopen *req_exec_lck_resourceopen = (struct req_exec_lck_resourceopen *)message;
  527. struct res_lib_lck_resourceopen res_lib_lck_resourceopen;
  528. struct res_lib_lck_resourceopenasync res_lib_lck_resourceopenasync;
  529. struct resource *resource;
  530. struct resource_cleanup *resource_cleanup;
  531. SaErrorT error = SA_AIS_OK;
  532. log_printf (LOG_LEVEL_NOTICE, "EXEC request: saLckResourceOpen %s\n",
  533. getSaNameT (&req_exec_lck_resourceopen->resource_name));
  534. if (req_exec_lck_resourceopen->fail_with_error != SA_AIS_OK) {
  535. error = req_exec_lck_resourceopen->fail_with_error;
  536. goto error_exit;
  537. }
  538. resource = resource_find (&req_exec_lck_resourceopen->resource_name);
  539. /*
  540. * If resource doesn't exist, create one
  541. */
  542. if (resource == 0) {
  543. if ((req_exec_lck_resourceopen->open_flags & SA_LCK_RESOURCE_CREATE) == 0) {
  544. error = SA_AIS_ERR_NOT_EXIST;
  545. goto error_exit;
  546. }
  547. resource = malloc (sizeof (struct resource));
  548. if (resource == 0) {
  549. error = SA_AIS_ERR_NO_MEMORY;
  550. goto error_exit;
  551. }
  552. memset (resource, 0, sizeof (struct resource));
  553. memcpy (&resource->name,
  554. &req_exec_lck_resourceopen->resource_name,
  555. sizeof (SaNameT));
  556. list_init (&resource->list);
  557. list_init (&resource->resource_lock_list_head);
  558. list_add (&resource->list, &resource_list_head);
  559. list_init (&resource->pr_granted_list_head);
  560. list_init (&resource->pr_pending_list_head);
  561. list_init (&resource->ex_pending_list_head);
  562. resource->refcount = 0;
  563. resource->ex_granted = NULL;
  564. }
  565. /*
  566. * Setup connection information and mark resource as referenced
  567. */
  568. if (message_source_is_local (&req_exec_lck_resourceopen->source)) {
  569. log_printf (LOG_LEVEL_DEBUG, "Lock resource opened is %p\n", resource);
  570. resource_cleanup = malloc (sizeof (struct resource_cleanup));
  571. if (resource_cleanup == 0) {
  572. free (resource);
  573. error = SA_AIS_ERR_NO_MEMORY;
  574. } else {
  575. list_init (&resource_cleanup->list);
  576. list_init (&resource_cleanup->resource_lock_list_head);
  577. resource_cleanup->resource = resource;
  578. resource_cleanup->resource_handle = req_exec_lck_resourceopen->resource_handle;
  579. list_add (
  580. &resource_cleanup->list,
  581. &req_exec_lck_resourceopen->source.conn_info->ais_ci.u.liblck_ci.resource_cleanup_list);
  582. }
  583. resource->refcount += 1;
  584. }
  585. /*
  586. * Send error result to LCK library
  587. */
  588. error_exit:
  589. /*
  590. * If this node was the source of the message, respond to this node
  591. */
  592. if (message_source_is_local (&req_exec_lck_resourceopen->source)) {
  593. /*
  594. * If its an async call respond with the invocation and handle
  595. */
  596. if (req_exec_lck_resourceopen->async_call) {
  597. res_lib_lck_resourceopenasync.header.size = sizeof (struct res_lib_lck_resourceopenasync);
  598. res_lib_lck_resourceopenasync.header.id = MESSAGE_RES_LCK_RESOURCEOPENASYNC;
  599. res_lib_lck_resourceopenasync.header.error = error;
  600. res_lib_lck_resourceopenasync.resourceHandle = req_exec_lck_resourceopen->resource_handle;
  601. res_lib_lck_resourceopenasync.invocation = req_exec_lck_resourceopen->invocation;
  602. memcpy (&res_lib_lck_resourceopenasync.source,
  603. &req_exec_lck_resourceopen->source,
  604. sizeof (struct message_source));
  605. libais_send_response (
  606. req_exec_lck_resourceopen->source.conn_info,
  607. &res_lib_lck_resourceopenasync,
  608. sizeof (struct res_lib_lck_resourceopenasync));
  609. libais_send_response (
  610. req_exec_lck_resourceopen->source.conn_info->conn_info_partner,
  611. &res_lib_lck_resourceopenasync,
  612. sizeof (struct res_lib_lck_resourceopenasync));
  613. } else {
  614. /*
  615. * otherwise respond with the normal resourceopen response
  616. */
  617. res_lib_lck_resourceopen.header.size = sizeof (struct res_lib_lck_resourceopen);
  618. res_lib_lck_resourceopen.header.id = MESSAGE_RES_LCK_RESOURCEOPEN;
  619. res_lib_lck_resourceopen.header.error = error;
  620. memcpy (&res_lib_lck_resourceopen.source,
  621. &req_exec_lck_resourceopen->source,
  622. sizeof (struct message_source));
  623. libais_send_response (req_exec_lck_resourceopen->source.conn_info, &res_lib_lck_resourceopen,
  624. sizeof (struct res_lib_lck_resourceopen));
  625. }
  626. }
  627. return (0);
  628. }
  629. static int message_handler_req_exec_lck_resourceclose (
  630. void *message,
  631. struct in_addr source_addr,
  632. int endian_conversion_required)
  633. {
  634. struct req_exec_lck_resourceclose *req_exec_lck_resourceclose = (struct req_exec_lck_resourceclose *)message;
  635. struct res_lib_lck_resourceclose res_lib_lck_resourceclose;
  636. struct resource *resource = 0;
  637. SaAisErrorT error = SA_AIS_OK;
  638. log_printf (LOG_LEVEL_NOTICE, "EXEC request: saLckResourceClose %s\n",
  639. getSaNameT (&req_exec_lck_resourceclose->lockResourceName));
  640. resource = resource_find (&req_exec_lck_resourceclose->lockResourceName);
  641. if (resource == 0) {
  642. goto error_exit;
  643. }
  644. resource->refcount -= 1;
  645. if (resource->refcount == 0) {
  646. }
  647. error_exit:
  648. if (message_source_is_local(&req_exec_lck_resourceclose->source)) {
  649. lck_resource_cleanup_remove (
  650. req_exec_lck_resourceclose->source.conn_info,
  651. req_exec_lck_resourceclose->resource_handle);
  652. res_lib_lck_resourceclose.header.size = sizeof (struct res_lib_lck_resourceclose);
  653. res_lib_lck_resourceclose.header.id = MESSAGE_RES_LCK_RESOURCECLOSE;
  654. res_lib_lck_resourceclose.header.error = error;
  655. libais_send_response (req_exec_lck_resourceclose->source.conn_info,
  656. &res_lib_lck_resourceclose, sizeof (struct res_lib_lck_resourceclose));
  657. }
  658. return (0);
  659. }
  660. void waiter_notification_send (struct resource_lock *resource_lock)
  661. {
  662. struct res_lib_lck_lockwaitercallback res_lib_lck_lockwaitercallback;
  663. if (message_source_is_local (&resource_lock->callback_source) == 0) {
  664. return;
  665. }
  666. res_lib_lck_lockwaitercallback.header.size = sizeof (struct res_lib_lck_lockwaitercallback);
  667. res_lib_lck_lockwaitercallback.header.id = MESSAGE_RES_LCK_LOCKWAITERCALLBACK;
  668. res_lib_lck_lockwaitercallback.header.error = SA_AIS_OK;
  669. res_lib_lck_lockwaitercallback.waiter_signal = resource_lock->waiter_signal;
  670. res_lib_lck_lockwaitercallback.lock_id = resource_lock->lock_id;
  671. res_lib_lck_lockwaitercallback.mode_requested = resource_lock->lock_mode;
  672. if (resource_lock->resource->ex_granted) {
  673. res_lib_lck_lockwaitercallback.mode_held = SA_LCK_EX_LOCK_MODE;
  674. } else {
  675. res_lib_lck_lockwaitercallback.mode_held = SA_LCK_PR_LOCK_MODE;
  676. }
  677. libais_send_response (
  678. resource_lock->callback_source.conn_info->conn_info_partner,
  679. &res_lib_lck_lockwaitercallback,
  680. sizeof (struct res_lib_lck_lockwaitercallback));
  681. }
  682. void waiter_notification_list_send (struct list_head *list_notify_head)
  683. {
  684. struct list_head *list;
  685. struct resource_lock *resource_lock;
  686. for (list = list_notify_head->next;
  687. list != list_notify_head;
  688. list = list->next) {
  689. resource_lock = list_entry (list, struct resource_lock, list);
  690. waiter_notification_send (resource_lock);
  691. }
  692. }
  693. void resource_lock_async_deliver (
  694. struct message_source *source,
  695. struct resource_lock *resource_lock,
  696. SaAisErrorT error)
  697. {
  698. struct res_lib_lck_resourcelockasync res_lib_lck_resourcelockasync;
  699. if (source && message_source_is_local(source)) {
  700. if (resource_lock->async_call) {
  701. res_lib_lck_resourcelockasync.header.size = sizeof (struct res_lib_lck_resourcelockasync);
  702. res_lib_lck_resourcelockasync.header.id = MESSAGE_RES_LCK_RESOURCELOCKASYNC;
  703. res_lib_lck_resourcelockasync.header.error = error;
  704. res_lib_lck_resourcelockasync.resource_lock = (void *)resource_lock;
  705. res_lib_lck_resourcelockasync.lockStatus = resource_lock->lock_status;
  706. res_lib_lck_resourcelockasync.invocation = resource_lock->invocation;
  707. res_lib_lck_resourcelockasync.lockId = resource_lock->lock_id;
  708. libais_send_response (source->conn_info->conn_info_partner,
  709. &res_lib_lck_resourcelockasync,
  710. sizeof (struct res_lib_lck_resourcelockasync));
  711. }
  712. }
  713. }
  714. void lock_response_deliver (
  715. struct message_source *source,
  716. struct resource_lock *resource_lock,
  717. SaAisErrorT error)
  718. {
  719. struct res_lib_lck_resourcelock res_lib_lck_resourcelock;
  720. if (source && message_source_is_local(source)) {
  721. if (resource_lock->async_call) {
  722. resource_lock_async_deliver (&resource_lock->callback_source, resource_lock, error);
  723. } else {
  724. res_lib_lck_resourcelock.header.size = sizeof (struct res_lib_lck_resourcelock);
  725. res_lib_lck_resourcelock.header.id = MESSAGE_RES_LCK_RESOURCELOCK;
  726. res_lib_lck_resourcelock.header.error = error;
  727. res_lib_lck_resourcelock.resource_lock = (void *)resource_lock;
  728. res_lib_lck_resourcelock.lockStatus = resource_lock->lock_status;
  729. libais_send_response (source->conn_info,
  730. &res_lib_lck_resourcelock,
  731. sizeof (struct res_lib_lck_resourcelock));
  732. }
  733. }
  734. }
  735. /*
  736. * Queue a lock if resource flags allow it
  737. */
  738. void lock_queue (
  739. struct resource *resource,
  740. struct resource_lock *resource_lock)
  741. {
  742. if ((resource_lock->lock_flags & SA_LCK_LOCK_NO_QUEUE) == 0) {
  743. /*
  744. * Add lock to the list
  745. */
  746. if (resource_lock->lock_mode == SA_LCK_PR_LOCK_MODE) {
  747. list_add_tail (&resource_lock->list,
  748. &resource->pr_pending_list_head);
  749. waiter_notification_send (resource->ex_granted);
  750. } else
  751. if (resource_lock->lock_mode == SA_LCK_EX_LOCK_MODE) {
  752. list_add_tail (&resource_lock->list,
  753. &resource->ex_pending_list_head);
  754. waiter_notification_list_send (&resource->pr_granted_list_head);
  755. }
  756. } else {
  757. resource_lock->lock_status = SA_LCK_LOCK_NOT_QUEUED;
  758. }
  759. }
  760. /*
  761. The algorithm:
  762. if ex lock granted
  763. if ex pending list has locks
  764. send waiter notification to ex lock granted
  765. else
  766. if ex pending list has locks
  767. if pr granted list has locks
  768. send waiter notification to all pr granted locks
  769. else
  770. grant ex lock from pending to granted
  771. else
  772. grant all pr pending locks to pr granted list
  773. */
  774. #define SA_LCK_LOCK_NO_STATUS 0
  775. void lock_algorithm (
  776. struct resource *resource,
  777. struct resource_lock *resource_lock)
  778. {
  779. resource_lock->lock_status = SA_LCK_LOCK_NO_STATUS; /* no status */
  780. if (resource->ex_granted) {
  781. /*
  782. * Exclusive lock granted
  783. */
  784. if (resource_lock->lock_mode == SA_LCK_PR_LOCK_MODE) {
  785. lock_queue (resource, resource_lock);
  786. }
  787. } else {
  788. /*
  789. * Exclusive lock not granted
  790. */
  791. if (resource_lock->lock_mode == SA_LCK_EX_LOCK_MODE) {
  792. if (list_empty (&resource->pr_granted_list_head) == 0) {
  793. lock_queue (resource, resource_lock);
  794. } else {
  795. /*
  796. * grant ex lock from pending to granted
  797. */
  798. resource->ex_granted = resource_lock;
  799. resource_lock->lock_status = SA_LCK_LOCK_GRANTED;
  800. }
  801. } else {
  802. /*
  803. * grant all pr pending locks to pr granted list
  804. */
  805. list_add (&resource_lock->list,
  806. &resource->pr_granted_list_head);
  807. resource_lock->lock_status = SA_LCK_LOCK_GRANTED;
  808. }
  809. }
  810. }
  811. /*
  812. * if lock in ex, set ex to null
  813. * delete resource lock from list
  814. *
  815. * if ex lock not granted
  816. * if ex pending list has locks
  817. * grant first ex pending list lock to ex lock
  818. * if ex lock not granted
  819. * if pr pending list has locks
  820. * assign all pr pending locks to pr granted lock list
  821. */
  822. void unlock_algorithm (
  823. struct resource *resource,
  824. struct resource_lock *resource_lock)
  825. {
  826. struct resource_lock *resource_lock_grant;
  827. struct list_head *list;
  828. struct list_head *list_p;
  829. /*
  830. * If unlocking the ex lock, reset ex granted
  831. */
  832. if (resource_lock == resource->ex_granted) {
  833. resource->ex_granted = 0;
  834. }
  835. /*
  836. * Delete resource lock from whichever list it is on
  837. */
  838. list_del (&resource_lock->list);
  839. /*
  840. * Check if EX locks are available, if so assign one
  841. */
  842. if (resource->ex_granted == 0) {
  843. if (list_empty (&resource->ex_pending_list_head) == 0) {
  844. /*
  845. * grant first ex pending list lock to ex lock
  846. */
  847. resource_lock_grant = list_entry (
  848. resource->ex_pending_list_head.next,
  849. struct resource_lock, list);
  850. list_del (&resource_lock_grant->list);
  851. resource->ex_granted = resource_lock_grant;
  852. resource_lock_grant->lock_status = SA_LCK_LOCK_GRANTED;
  853. lock_response_deliver (
  854. &resource_lock_grant->response_source,
  855. resource_lock_grant,
  856. SA_AIS_OK);
  857. }
  858. }
  859. /*
  860. * Couldn't assign EX lock, so assign any pending PR locks
  861. */
  862. if (resource->ex_granted == 0) {
  863. if (list_empty (&resource->pr_pending_list_head) == 0) {
  864. /*
  865. * assign all pr pending locks to pr granted lock list
  866. */
  867. for (list = resource->pr_pending_list_head.next;
  868. list != &resource->pr_pending_list_head;
  869. list = list->next) {
  870. resource_lock_grant = list_entry (list, struct resource_lock, list);
  871. resource_lock_grant->lock_status = SA_LCK_LOCK_GRANTED;
  872. lock_response_deliver (
  873. &resource_lock_grant->response_source,
  874. resource_lock_grant,
  875. SA_AIS_OK);
  876. }
  877. /*
  878. * Add pending locks to granted list
  879. */
  880. list_p = &resource->pr_pending_list_head.next;
  881. list_del (&resource->pr_pending_list_head);
  882. list_add_tail (list_p,
  883. &resource->pr_granted_list_head);
  884. }
  885. }
  886. }
  887. static int message_handler_req_exec_lck_resourcelock (
  888. void *message,
  889. struct in_addr source_addr,
  890. int endian_conversion_required)
  891. {
  892. struct req_exec_lck_resourcelock *req_exec_lck_resourcelock = (struct req_exec_lck_resourcelock *)message;
  893. struct resource *resource = 0;
  894. struct resource_lock *resource_lock = 0;
  895. struct resource_cleanup *resource_cleanup = 0;
  896. log_printf (LOG_LEVEL_NOTICE, "EXEC request: saLckResourceLock %s\n",
  897. getSaNameT (&req_exec_lck_resourcelock->req_lib_lck_resourcelock.lockResourceName));
  898. resource = resource_find (&req_exec_lck_resourcelock->req_lib_lck_resourcelock.lockResourceName);
  899. if (resource == 0) {
  900. goto error_exit;
  901. }
  902. resource->refcount += 1;
  903. resource_lock = malloc (sizeof (struct resource_lock));
  904. if (resource_lock == 0) {
  905. lock_response_deliver (&req_exec_lck_resourcelock->source,
  906. resource_lock,
  907. SA_AIS_ERR_NO_MEMORY);
  908. goto error_exit;
  909. }
  910. /*
  911. * Build resource lock structure
  912. */
  913. memset (resource_lock, 0, sizeof (struct resource_lock));
  914. list_init (&resource_lock->list);
  915. list_init (&resource_lock->resource_list);
  916. list_init (&resource_lock->resource_cleanup_list);
  917. list_add (&resource_lock->resource_list, &resource->resource_lock_list_head);
  918. resource_lock->resource = resource;
  919. resource_lock->lock_mode =
  920. req_exec_lck_resourcelock->req_lib_lck_resourcelock.lockMode;
  921. resource_lock->lock_flags =
  922. req_exec_lck_resourcelock->req_lib_lck_resourcelock.lockFlags;
  923. resource_lock->waiter_signal =
  924. req_exec_lck_resourcelock->req_lib_lck_resourcelock.waiterSignal;
  925. resource_lock->timeout =
  926. req_exec_lck_resourcelock->req_lib_lck_resourcelock.timeout;
  927. resource_lock->lock_id =
  928. req_exec_lck_resourcelock->req_lib_lck_resourcelock.lockId;
  929. resource_lock->async_call =
  930. req_exec_lck_resourcelock->req_lib_lck_resourcelock.async_call;
  931. resource_lock->invocation =
  932. req_exec_lck_resourcelock->req_lib_lck_resourcelock.invocation;
  933. /*
  934. * Waiter callback source
  935. */
  936. memcpy (&resource_lock->callback_source,
  937. &req_exec_lck_resourcelock->req_lib_lck_resourcelock.source,
  938. sizeof (struct message_source));
  939. lock_algorithm (resource, resource_lock);
  940. /*
  941. * Add resource lock to cleanup handler for this api resource instance
  942. */
  943. if (message_source_is_local (&req_exec_lck_resourcelock->source)) {
  944. resource_cleanup = lck_resource_cleanup_find (
  945. resource_lock->callback_source.conn_info,
  946. req_exec_lck_resourcelock->resource_handle);
  947. assert (resource_cleanup);
  948. list_add (&resource_lock->resource_cleanup_list,
  949. &resource_cleanup->resource_lock_list_head);
  950. /*
  951. * If lock queued by lock algorithm, dont send response to library now
  952. */
  953. if (resource_lock->lock_status != SA_LCK_LOCK_NO_STATUS) {
  954. /*
  955. * If lock granted or denied, deliver callback or
  956. * response to library for non-async calls
  957. */
  958. lock_response_deliver (
  959. &req_exec_lck_resourcelock->source,
  960. resource_lock,
  961. SA_AIS_OK);
  962. } else {
  963. memcpy (&resource_lock->response_source,
  964. &req_exec_lck_resourcelock->source,
  965. sizeof (struct message_source));
  966. }
  967. /*
  968. * Deliver async response to library
  969. */
  970. req_exec_lck_resourcelock->source.conn_info =
  971. req_exec_lck_resourcelock->source.conn_info->conn_info_partner;
  972. resource_lock_async_deliver (
  973. &req_exec_lck_resourcelock->source,
  974. resource_lock,
  975. SA_AIS_OK);
  976. req_exec_lck_resourcelock->source.conn_info =
  977. req_exec_lck_resourcelock->source.conn_info->conn_info_partner;
  978. }
  979. error_exit:
  980. return (0);
  981. }
  982. static int message_handler_req_exec_lck_resourceunlock (
  983. void *message,
  984. struct in_addr source_addr,
  985. int endian_conversion_required)
  986. {
  987. struct req_exec_lck_resourceunlock *req_exec_lck_resourceunlock = (struct req_exec_lck_resourceunlock *)message;
  988. struct res_lib_lck_resourceunlock res_lib_lck_resourceunlock;
  989. struct res_lib_lck_resourceunlockasync res_lib_lck_resourceunlockasync;
  990. struct resource *resource = 0;
  991. struct resource_lock *resource_lock = 0;
  992. SaAisErrorT error = SA_AIS_OK;
  993. log_printf (LOG_LEVEL_NOTICE, "EXEC request: saLckResourceUnlock %s\n",
  994. getSaNameT (&req_exec_lck_resourceunlock->resource_name));
  995. resource = resource_find (&req_exec_lck_resourceunlock->resource_name);
  996. if (resource == 0) {
  997. goto error_exit;
  998. }
  999. resource->refcount -= 1;
  1000. resource_lock = resource_lock_find (resource,
  1001. &req_exec_lck_resourceunlock->source,
  1002. req_exec_lck_resourceunlock->lock_id);
  1003. assert (resource_lock);
  1004. list_del (&resource_lock->resource_cleanup_list);
  1005. unlock_algorithm (resource, resource_lock);
  1006. error_exit:
  1007. if (message_source_is_local(&req_exec_lck_resourceunlock->source)) {
  1008. if (req_exec_lck_resourceunlock->async_call) {
  1009. res_lib_lck_resourceunlockasync.header.size = sizeof (struct res_lib_lck_resourceunlockasync);
  1010. res_lib_lck_resourceunlockasync.header.id = MESSAGE_RES_LCK_RESOURCEUNLOCKASYNC;
  1011. res_lib_lck_resourceunlockasync.header.error = error;
  1012. res_lib_lck_resourceunlockasync.invocation =
  1013. req_exec_lck_resourceunlock->invocation;
  1014. libais_send_response (
  1015. req_exec_lck_resourceunlock->source.conn_info,
  1016. &res_lib_lck_resourceunlockasync,
  1017. sizeof (struct res_lib_lck_resourceunlockasync));
  1018. libais_send_response (
  1019. resource_lock->callback_source.conn_info,
  1020. &res_lib_lck_resourceunlockasync,
  1021. sizeof (struct res_lib_lck_resourceunlockasync));
  1022. } else {
  1023. res_lib_lck_resourceunlock.header.size = sizeof (struct res_lib_lck_resourceunlock);
  1024. res_lib_lck_resourceunlock.header.id = MESSAGE_RES_LCK_RESOURCEUNLOCK;
  1025. res_lib_lck_resourceunlock.header.error = error;
  1026. libais_send_response (req_exec_lck_resourceunlock->source.conn_info,
  1027. &res_lib_lck_resourceunlock, sizeof (struct res_lib_lck_resourceunlock));
  1028. }
  1029. }
  1030. return (0);
  1031. }
  1032. static int message_handler_req_exec_lck_resourcelockorphan (
  1033. void *message,
  1034. struct in_addr source_addr,
  1035. int endian_conversion_required)
  1036. {
  1037. struct req_exec_lck_resourcelockorphan *req_exec_lck_resourcelockorphan = (struct req_exec_lck_resourcelockorphan *)message;
  1038. struct resource *resource = 0;
  1039. struct resource_lock *resource_lock = 0;
  1040. log_printf (LOG_LEVEL_NOTICE, "EXEC request: Orphan resource locks for resource %s\n",
  1041. getSaNameT (&req_exec_lck_resourcelockorphan->resource_name));
  1042. resource = resource_find (&req_exec_lck_resourcelockorphan->resource_name);
  1043. if (resource == 0) {
  1044. assert (0);
  1045. }
  1046. resource->refcount -= 1;
  1047. resource_lock = resource_lock_find (resource,
  1048. &req_exec_lck_resourcelockorphan->source,
  1049. req_exec_lck_resourcelockorphan->lock_id);
  1050. assert (resource_lock);
  1051. list_del (&resource_lock->resource_cleanup_list);
  1052. unlock_algorithm (resource, resource_lock);
  1053. return (0);
  1054. }
  1055. static int message_handler_req_exec_lck_lockpurge (
  1056. void *message,
  1057. struct in_addr source_addr,
  1058. int endian_conversion_required)
  1059. {
  1060. struct req_exec_lck_lockpurge *req_exec_lck_lockpurge = (struct req_exec_lck_lockpurge *)message;
  1061. struct res_lib_lck_lockpurge res_lib_lck_lockpurge;
  1062. struct resource *resource = 0;
  1063. SaAisErrorT error = SA_AIS_OK;
  1064. log_printf (LOG_LEVEL_DEBUG, "EXEC request: saLckLockPurge %s\n",
  1065. getSaNameT (&req_exec_lck_lockpurge->req_lib_lck_lockpurge.lockResourceName));
  1066. resource = resource_find (&req_exec_lck_lockpurge->req_lib_lck_lockpurge.lockResourceName);
  1067. if (resource == 0) {
  1068. goto error_exit;
  1069. }
  1070. error_exit:
  1071. if (message_source_is_local(&req_exec_lck_lockpurge->source)) {
  1072. // lck_resource_cleanup_remove (req_exec_lck_lockpurge->source.conn_info,
  1073. // resource);
  1074. res_lib_lck_lockpurge.header.size = sizeof (struct res_lib_lck_lockpurge);
  1075. res_lib_lck_lockpurge.header.id = MESSAGE_RES_LCK_LOCKPURGE;
  1076. res_lib_lck_lockpurge.header.error = error;
  1077. libais_send_response (req_exec_lck_lockpurge->source.conn_info,
  1078. &res_lib_lck_lockpurge, sizeof (struct res_lib_lck_lockpurge));
  1079. }
  1080. return (0);
  1081. }
  1082. static int message_handler_req_lib_lck_resourceopen (struct conn_info *conn_info, void *message)
  1083. {
  1084. struct req_lib_lck_resourceopen *req_lib_lck_resourceopen = (struct req_lib_lck_resourceopen *)message;
  1085. struct req_exec_lck_resourceopen req_exec_lck_resourceopen;
  1086. struct iovec iovec;
  1087. log_printf (LOG_LEVEL_NOTICE, "LIB request: saLckResourceOpen %s\n",
  1088. getSaNameT (&req_lib_lck_resourceopen->lockResourceName));
  1089. req_exec_lck_resourceopen.header.size =
  1090. sizeof (struct req_exec_lck_resourceopen);
  1091. req_exec_lck_resourceopen.header.id =
  1092. SERVICE_ID_MAKE (LCK_SERVICE, MESSAGE_REQ_EXEC_LCK_RESOURCEOPEN);
  1093. message_source_set (&req_exec_lck_resourceopen.source, conn_info);
  1094. memcpy (&req_exec_lck_resourceopen.resource_name,
  1095. &req_lib_lck_resourceopen->lockResourceName,
  1096. sizeof (SaNameT));
  1097. req_exec_lck_resourceopen.open_flags = req_lib_lck_resourceopen->resourceOpenFlags;
  1098. req_exec_lck_resourceopen.async_call = 0;
  1099. req_exec_lck_resourceopen.invocation = 0;
  1100. req_exec_lck_resourceopen.resource_handle = req_lib_lck_resourceopen->resourceHandle;
  1101. req_exec_lck_resourceopen.fail_with_error = SA_AIS_OK;
  1102. iovec.iov_base = (char *)&req_exec_lck_resourceopen;
  1103. iovec.iov_len = sizeof (req_exec_lck_resourceopen);
  1104. assert (totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED) == 0);
  1105. return (0);
  1106. }
  1107. static int message_handler_req_lib_lck_resourceopenasync (struct conn_info *conn_info, void *message)
  1108. {
  1109. struct req_lib_lck_resourceopen *req_lib_lck_resourceopen = (struct req_lib_lck_resourceopen *)message;
  1110. struct req_exec_lck_resourceopen req_exec_lck_resourceopen;
  1111. struct iovec iovec;
  1112. log_printf (LOG_LEVEL_NOTICE, "LIB request: saLckResourceOpenAsync %s\n",
  1113. getSaNameT (&req_lib_lck_resourceopen->lockResourceName));
  1114. req_exec_lck_resourceopen.header.size =
  1115. sizeof (struct req_exec_lck_resourceopen);
  1116. req_exec_lck_resourceopen.header.id =
  1117. SERVICE_ID_MAKE (LCK_SERVICE, MESSAGE_REQ_EXEC_LCK_RESOURCEOPEN);
  1118. message_source_set (&req_exec_lck_resourceopen.source, conn_info);
  1119. memcpy (&req_exec_lck_resourceopen.resource_name,
  1120. &req_lib_lck_resourceopen->lockResourceName,
  1121. sizeof (SaNameT));
  1122. req_exec_lck_resourceopen.resource_handle = req_lib_lck_resourceopen->resourceHandle;
  1123. req_exec_lck_resourceopen.invocation = req_lib_lck_resourceopen->invocation;
  1124. req_exec_lck_resourceopen.open_flags = req_lib_lck_resourceopen->resourceOpenFlags;
  1125. req_exec_lck_resourceopen.timeout = 0;
  1126. req_exec_lck_resourceopen.async_call = 1;
  1127. iovec.iov_base = (char *)&req_exec_lck_resourceopen;
  1128. iovec.iov_len = sizeof (req_exec_lck_resourceopen);
  1129. assert (totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED) == 0);
  1130. return (0);
  1131. }
  1132. static int message_handler_req_lib_lck_resourceclose (struct conn_info *conn_info, void *message) {
  1133. struct req_lib_lck_resourceclose *req_lib_lck_resourceclose = (struct req_lib_lck_resourceclose *)message;
  1134. struct req_exec_lck_resourceclose req_exec_lck_resourceclose;
  1135. struct iovec iovecs[2];
  1136. struct resource *resource;
  1137. struct res_lib_lck_resourceclose res_lib_lck_resourceclose;
  1138. log_printf (LOG_LEVEL_NOTICE, "LIB request: saLckResourceClose %s\n",
  1139. getSaNameT (&req_lib_lck_resourceclose->lockResourceName));
  1140. resource = resource_find (&req_lib_lck_resourceclose->lockResourceName);
  1141. if (resource) {
  1142. req_exec_lck_resourceclose.header.size =
  1143. sizeof (struct req_exec_lck_resourceclose);
  1144. req_exec_lck_resourceclose.header.id =
  1145. SERVICE_ID_MAKE (LCK_SERVICE, MESSAGE_REQ_EXEC_LCK_RESOURCECLOSE);
  1146. message_source_set (&req_exec_lck_resourceclose.source, conn_info);
  1147. memcpy (&req_exec_lck_resourceclose.lockResourceName,
  1148. &req_lib_lck_resourceclose->lockResourceName, sizeof (SaNameT));
  1149. req_exec_lck_resourceclose.resource_handle = req_lib_lck_resourceclose->resourceHandle;
  1150. iovecs[0].iov_base = (char *)&req_exec_lck_resourceclose;
  1151. iovecs[0].iov_len = sizeof (req_exec_lck_resourceclose);
  1152. if (totempg_groups_send_ok_joined (openais_group_handle, iovecs, 1)) {
  1153. assert (totempg_groups_mcast_joined (openais_group_handle, iovecs, 1, TOTEMPG_AGREED) == 0);
  1154. }
  1155. }
  1156. else {
  1157. log_printf (LOG_LEVEL_ERROR, "#### LCK: Could Not Find the Checkpoint to close so Returning Error. ####\n");
  1158. res_lib_lck_resourceclose.header.size = sizeof (struct res_lib_lck_resourceclose);
  1159. res_lib_lck_resourceclose.header.id = MESSAGE_RES_LCK_RESOURCECLOSE;
  1160. res_lib_lck_resourceclose.header.error = SA_AIS_ERR_NOT_EXIST;
  1161. libais_send_response (conn_info,
  1162. &res_lib_lck_resourceclose,
  1163. sizeof (struct res_lib_lck_resourceclose));
  1164. }
  1165. return (0);
  1166. }
  1167. static int message_handler_req_lib_lck_resourcelock (struct conn_info *conn_info, void *message)
  1168. {
  1169. struct req_lib_lck_resourcelock *req_lib_lck_resourcelock = (struct req_lib_lck_resourcelock *)message;
  1170. struct req_exec_lck_resourcelock req_exec_lck_resourcelock;
  1171. struct iovec iovecs[2];
  1172. log_printf (LOG_LEVEL_NOTICE, "LIB request: saLckResourceLock %s\n",
  1173. getSaNameT (&req_lib_lck_resourcelock->lockResourceName));
  1174. req_exec_lck_resourcelock.header.size =
  1175. sizeof (struct req_exec_lck_resourcelock);
  1176. req_exec_lck_resourcelock.header.id =
  1177. SERVICE_ID_MAKE (LCK_SERVICE, MESSAGE_REQ_EXEC_LCK_RESOURCELOCK);
  1178. message_source_set (&req_exec_lck_resourcelock.source, conn_info);
  1179. memcpy (&req_exec_lck_resourcelock.req_lib_lck_resourcelock,
  1180. req_lib_lck_resourcelock,
  1181. sizeof (struct req_lib_lck_resourcelock));
  1182. req_exec_lck_resourcelock.resource_handle = req_lib_lck_resourcelock->resourceHandle;
  1183. req_exec_lck_resourcelock.async_call = 0;
  1184. req_exec_lck_resourcelock.invocation = 0;
  1185. req_exec_lck_resourcelock.fail_with_error = SA_AIS_OK;
  1186. iovecs[0].iov_base = (char *)&req_exec_lck_resourcelock;
  1187. iovecs[0].iov_len = sizeof (req_exec_lck_resourcelock);
  1188. assert (totempg_groups_mcast_joined (openais_group_handle, iovecs, 1, TOTEMPG_AGREED) == 0);
  1189. return (0);
  1190. }
  1191. static int message_handler_req_lib_lck_resourcelockasync (struct conn_info *conn_info, void *message)
  1192. {
  1193. struct req_lib_lck_resourcelock *req_lib_lck_resourcelock = (struct req_lib_lck_resourcelock *)message;
  1194. struct req_exec_lck_resourcelock req_exec_lck_resourcelock;
  1195. struct iovec iovecs[2];
  1196. log_printf (LOG_LEVEL_NOTICE, "LIB request: saLckResourceLockAsync %s\n",
  1197. getSaNameT (&req_lib_lck_resourcelock->lockResourceName));
  1198. req_exec_lck_resourcelock.header.size =
  1199. sizeof (struct req_exec_lck_resourcelock);
  1200. req_exec_lck_resourcelock.header.id =
  1201. SERVICE_ID_MAKE (LCK_SERVICE, MESSAGE_REQ_EXEC_LCK_RESOURCELOCK);
  1202. message_source_set (&req_exec_lck_resourcelock.source, conn_info);
  1203. memcpy (&req_exec_lck_resourcelock.req_lib_lck_resourcelock,
  1204. req_lib_lck_resourcelock,
  1205. sizeof (struct req_lib_lck_resourcelock));
  1206. req_exec_lck_resourcelock.resource_handle = req_lib_lck_resourcelock->resourceHandle;
  1207. req_exec_lck_resourcelock.async_call = 1;
  1208. req_exec_lck_resourcelock.invocation = req_lib_lck_resourcelock->invocation;
  1209. iovecs[0].iov_base = (char *)&req_exec_lck_resourcelock;
  1210. iovecs[0].iov_len = sizeof (req_exec_lck_resourcelock);
  1211. assert (totempg_groups_mcast_joined (openais_group_handle, iovecs, 1, TOTEMPG_AGREED) == 0);
  1212. return (0);
  1213. }
  1214. static int message_handler_req_lib_lck_resourceunlock (struct conn_info *conn_info, void *message)
  1215. {
  1216. struct req_lib_lck_resourceunlock *req_lib_lck_resourceunlock = (struct req_lib_lck_resourceunlock *)message;
  1217. struct req_exec_lck_resourceunlock req_exec_lck_resourceunlock;
  1218. struct iovec iovec;
  1219. log_printf (LOG_LEVEL_NOTICE, "LIB request: saLckResourceUnlock %s\n",
  1220. getSaNameT (&req_lib_lck_resourceunlock->lockResourceName));
  1221. req_exec_lck_resourceunlock.header.size =
  1222. sizeof (struct req_exec_lck_resourceunlock);
  1223. req_exec_lck_resourceunlock.header.id =
  1224. SERVICE_ID_MAKE (LCK_SERVICE, MESSAGE_REQ_EXEC_LCK_RESOURCEUNLOCK);
  1225. message_source_set (&req_exec_lck_resourceunlock.source, conn_info);
  1226. memcpy (&req_exec_lck_resourceunlock.resource_name,
  1227. &req_lib_lck_resourceunlock->lockResourceName,
  1228. sizeof (SaNameT));
  1229. req_exec_lck_resourceunlock.lock_id = req_lib_lck_resourceunlock->lockId;
  1230. req_exec_lck_resourceunlock.async_call = 0;
  1231. req_exec_lck_resourceunlock.invocation = 0;
  1232. iovec.iov_base = (char *)&req_exec_lck_resourceunlock;
  1233. iovec.iov_len = sizeof (req_exec_lck_resourceunlock);
  1234. assert (totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED) == 0);
  1235. return (0);
  1236. }
  1237. static int message_handler_req_lib_lck_resourceunlockasync (struct conn_info *conn_info, void *message)
  1238. {
  1239. struct req_lib_lck_resourceunlock *req_lib_lck_resourceunlock = (struct req_lib_lck_resourceunlock *)message;
  1240. struct req_exec_lck_resourceunlock req_exec_lck_resourceunlock;
  1241. struct iovec iovec;
  1242. log_printf (LOG_LEVEL_NOTICE, "LIB request: saLckResourceUnlockAsync %s\n",
  1243. getSaNameT (&req_lib_lck_resourceunlock->lockResourceName));
  1244. req_exec_lck_resourceunlock.header.size =
  1245. sizeof (struct req_exec_lck_resourceunlock);
  1246. req_exec_lck_resourceunlock.header.id =
  1247. SERVICE_ID_MAKE (LCK_SERVICE, MESSAGE_REQ_EXEC_LCK_RESOURCEUNLOCK);
  1248. message_source_set (&req_exec_lck_resourceunlock.source, conn_info);
  1249. memcpy (&req_exec_lck_resourceunlock.resource_name,
  1250. &req_lib_lck_resourceunlock->lockResourceName,
  1251. sizeof (SaNameT));
  1252. req_exec_lck_resourceunlock.lock_id = req_lib_lck_resourceunlock->lockId;
  1253. req_exec_lck_resourceunlock.invocation = req_lib_lck_resourceunlock->invocation;
  1254. req_exec_lck_resourceunlock.async_call = 1;
  1255. iovec.iov_base = (char *)&req_exec_lck_resourceunlock;
  1256. iovec.iov_len = sizeof (req_exec_lck_resourceunlock);
  1257. assert (totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED) == 0);
  1258. return (0);
  1259. }
  1260. static int message_handler_req_lib_lck_lockpurge (struct conn_info *conn_info, void *message)
  1261. {
  1262. struct req_lib_lck_lockpurge *req_lib_lck_lockpurge = (struct req_lib_lck_lockpurge *)message;
  1263. struct req_exec_lck_lockpurge req_exec_lck_lockpurge;
  1264. struct iovec iovecs[2];
  1265. log_printf (LOG_LEVEL_NOTICE, "LIB request: saLckResourceLockPurge %s\n",
  1266. getSaNameT (&req_lib_lck_lockpurge->lockResourceName));
  1267. req_exec_lck_lockpurge.header.size =
  1268. sizeof (struct req_exec_lck_lockpurge);
  1269. req_exec_lck_lockpurge.header.id =
  1270. SERVICE_ID_MAKE (LCK_SERVICE, MESSAGE_REQ_EXEC_LCK_LOCKPURGE);
  1271. message_source_set (&req_exec_lck_lockpurge.source, conn_info);
  1272. memcpy (&req_exec_lck_lockpurge.req_lib_lck_lockpurge,
  1273. req_lib_lck_lockpurge,
  1274. sizeof (struct req_lib_lck_lockpurge));
  1275. iovecs[0].iov_base = (char *)&req_exec_lck_lockpurge;
  1276. iovecs[0].iov_len = sizeof (req_exec_lck_lockpurge);
  1277. assert (totempg_groups_mcast_joined (openais_group_handle, iovecs, 1, TOTEMPG_AGREED) == 0);
  1278. return (0);
  1279. }