lck.c 47 KB

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