lck.c 47 KB

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