4
0

ckpt.c 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856
  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 "../include/ais_types.h"
  47. #include "../include/saCkpt.h"
  48. #include "../include/ipc_ckpt.h"
  49. #include "../include/list.h"
  50. #include "../include/queue.h"
  51. #include "aispoll.h"
  52. #include "mempool.h"
  53. #include "util.h"
  54. #include "parse.h"
  55. #include "main.h"
  56. #include "totempg.h"
  57. #define LOG_SERVICE LOG_SERVICE_CKPT
  58. #include "print.h"
  59. DECLARE_LIST_INIT(checkpointListHead);
  60. DECLARE_LIST_INIT(checkpointIteratorListHead);
  61. struct checkpoint_cleanup {
  62. struct list_head list;
  63. struct saCkptCheckpoint *checkpoint;
  64. };
  65. //TODO static totempg_recovery_plug_handle ckpt_checkpoint_recovery_plug_handle;
  66. static int ckpt_exec_init_fn (void);
  67. static int ckpt_exit_fn (struct conn_info *conn_info);
  68. static int message_handler_req_lib_activatepoll (struct conn_info *, void *message);
  69. static int message_handler_req_exec_ckpt_checkpointopen (void *message, struct in_addr source_addr, int endian_conversion_required);
  70. static int message_handler_req_exec_ckpt_checkpointclose (void *message, struct in_addr source_addr, int endian_conversion_required);
  71. static int message_handler_req_exec_ckpt_checkpointunlink (void *message, struct in_addr source_addr, int endian_conversion_required);
  72. static int message_handler_req_exec_ckpt_checkpointretentiondurationset (void *message, struct in_addr source_addr, int endian_conversion_required);
  73. static int message_handler_req_exec_ckpt_checkpointretentiondurationexpire (void *message, struct in_addr source_addr, int endian_conversion_required);
  74. static int message_handler_req_exec_ckpt_sectioncreate (void *message, struct in_addr source_addr, int endian_conversion_required);
  75. static int message_handler_req_exec_ckpt_sectiondelete (void *message, struct in_addr source_addr, int endian_conversion_required);
  76. static int message_handler_req_exec_ckpt_sectionexpirationtimeset (void *message, struct in_addr source_addr, int endian_conversion_required);
  77. static int message_handler_req_exec_ckpt_sectionwrite (void *message, struct in_addr source_addr, int endian_conversion_required);
  78. static int message_handler_req_exec_ckpt_sectionoverwrite (void *message, struct in_addr source_addr, int endian_conversion_required);
  79. static int message_handler_req_exec_ckpt_sectionread (void *message, struct in_addr source_addr, int endian_conversion_required);
  80. static int message_handler_req_lib_ckpt_init (struct conn_info *conn_info, void *message);
  81. static int message_handler_req_lib_ckpt_checkpointopen (struct conn_info *conn_info, void *message);
  82. static int message_handler_req_lib_ckpt_checkpointopenasync (struct conn_info *conn_info, void *message);
  83. static int message_handler_req_lib_ckpt_checkpointclose (struct conn_info *conn_info, void *message);
  84. static int message_handler_req_lib_ckpt_checkpointunlink (struct conn_info *conn_info, void *message);
  85. static int message_handler_req_lib_ckpt_checkpointretentiondurationset (struct conn_info *conn_info, void *message);
  86. static int message_handler_req_lib_ckpt_activereplicaset (struct conn_info *conn_info, void *message);
  87. static int message_handler_req_lib_ckpt_checkpointstatusget (struct conn_info *conn_info, void *message);
  88. static int message_handler_req_lib_ckpt_sectioncreate (struct conn_info *conn_info, void *message);
  89. static int message_handler_req_lib_ckpt_sectiondelete (struct conn_info *conn_info, void *message);
  90. static int message_handler_req_lib_ckpt_sectionexpirationtimeset (struct conn_info *conn_info, void *message);
  91. static int message_handler_req_lib_ckpt_sectionwrite (struct conn_info *conn_info, void *message);
  92. static int message_handler_req_lib_ckpt_sectionoverwrite (struct conn_info *conn_info, void *message);
  93. static int message_handler_req_lib_ckpt_sectionread (struct conn_info *conn_info, void *message);
  94. static int message_handler_req_lib_ckpt_checkpointsynchronize (struct conn_info *conn_info, void *message);
  95. static int message_handler_req_lib_ckpt_checkpointsynchronizeasync (struct conn_info *conn_info, void *message);
  96. static int message_handler_req_lib_ckpt_sectioniteratorinitialize (struct conn_info *conn_info, void *message);
  97. static int message_handler_req_lib_ckpt_sectioniteratornext (struct conn_info *conn_info, void *message);
  98. static int ckpt_confchg_fn (
  99. enum totempg_configuration_type configuration_type,
  100. struct in_addr *member_list, void *member_list_private,
  101. int member_list_entries,
  102. struct in_addr *left_list, void *left_list_private,
  103. int left_list_entries,
  104. struct in_addr *joined_list, void *joined_list_private,
  105. int joined_list_entries,
  106. struct memb_ring_id *ring_id) {
  107. #ifdef TODO
  108. if (configuration_type == TOTEMPG_CONFIGURATION_REGULAR) {
  109. totempg_recovery_plug_unplug (ckpt_checkpoint_recovery_plug_handle);
  110. }
  111. #endif
  112. return (0);
  113. }
  114. struct libais_handler ckpt_libais_handlers[] =
  115. {
  116. { /* 0 */
  117. .libais_handler_fn = message_handler_req_lib_activatepoll,
  118. .response_size = sizeof (struct res_lib_activatepoll),
  119. .response_id = MESSAGE_RES_LIB_ACTIVATEPOLL,
  120. },
  121. { /* 1 */
  122. .libais_handler_fn = message_handler_req_lib_ckpt_checkpointopen,
  123. .response_size = sizeof (struct res_lib_ckpt_checkpointopen),
  124. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTOPEN,
  125. },
  126. { /* 2 */
  127. .libais_handler_fn = message_handler_req_lib_ckpt_checkpointopenasync,
  128. .response_size = sizeof (struct res_lib_ckpt_checkpointopenasync),
  129. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTOPENASYNC,
  130. },
  131. { /* 3 */
  132. .libais_handler_fn = message_handler_req_lib_ckpt_checkpointclose,
  133. .response_size = sizeof (struct res_lib_ckpt_checkpointclose),
  134. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTCLOSE,
  135. },
  136. { /* 4 */
  137. .libais_handler_fn = message_handler_req_lib_ckpt_checkpointunlink,
  138. .response_size = sizeof (struct res_lib_ckpt_checkpointunlink),
  139. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTUNLINK,
  140. },
  141. { /* 5 */
  142. .libais_handler_fn = message_handler_req_lib_ckpt_checkpointretentiondurationset,
  143. .response_size = sizeof (struct res_lib_ckpt_checkpointretentiondurationset),
  144. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTRETENTIONDURATIONSET,
  145. },
  146. { /* 6 */
  147. .libais_handler_fn = message_handler_req_lib_ckpt_activereplicaset,
  148. .response_size = sizeof (struct res_lib_ckpt_activereplicaset),
  149. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_ACTIVEREPLICASET,
  150. },
  151. { /* 7 */
  152. .libais_handler_fn = message_handler_req_lib_ckpt_checkpointstatusget,
  153. .response_size = sizeof (struct res_lib_ckpt_checkpointstatusget),
  154. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSTATUSGET,
  155. },
  156. { /* 8 */
  157. .libais_handler_fn = message_handler_req_lib_ckpt_sectioncreate,
  158. .response_size = sizeof (struct res_lib_ckpt_sectioncreate),
  159. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONCREATE,
  160. },
  161. { /* 9 */
  162. .libais_handler_fn = message_handler_req_lib_ckpt_sectiondelete,
  163. .response_size = sizeof (struct res_lib_ckpt_sectiondelete),
  164. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONDELETE,
  165. },
  166. { /* 10 */
  167. .libais_handler_fn = message_handler_req_lib_ckpt_sectionexpirationtimeset,
  168. .response_size = sizeof (struct res_lib_ckpt_sectionexpirationtimeset),
  169. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONEXPIRATIONTIMESET,
  170. },
  171. { /* 11 */
  172. .libais_handler_fn = message_handler_req_lib_ckpt_sectionwrite,
  173. .response_size = sizeof (struct res_lib_ckpt_sectionwrite),
  174. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONWRITE,
  175. },
  176. { /* 12 */
  177. .libais_handler_fn = message_handler_req_lib_ckpt_sectionoverwrite,
  178. .response_size = sizeof (struct res_lib_ckpt_sectionoverwrite),
  179. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONOVERWRITE,
  180. },
  181. { /* 13 */
  182. .libais_handler_fn = message_handler_req_lib_ckpt_sectionread,
  183. .response_size = sizeof (struct res_lib_ckpt_sectionread),
  184. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONREAD,
  185. },
  186. { /* 14 */
  187. .libais_handler_fn = message_handler_req_lib_ckpt_checkpointsynchronize,
  188. .response_size = sizeof (struct res_lib_ckpt_checkpointsynchronize),
  189. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSYNCHRONIZE,
  190. },
  191. { /* 15 */
  192. .libais_handler_fn = message_handler_req_lib_ckpt_checkpointsynchronizeasync,
  193. .response_size = sizeof (struct res_lib_ckpt_checkpointsynchronizeasync), // TODO RESPONSE
  194. .response_id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSYNCHRONIZEASYNC,
  195. },
  196. { /* 16 */
  197. .libais_handler_fn = message_handler_req_lib_ckpt_sectioniteratorinitialize,
  198. .response_size = sizeof (struct res_lib_ckpt_sectioniteratorinitialize),
  199. .response_id = MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORINITIALIZE,
  200. },
  201. { /* 17 */
  202. .libais_handler_fn = message_handler_req_lib_ckpt_sectioniteratornext,
  203. .response_size = sizeof (struct res_lib_ckpt_sectioniteratornext),
  204. .response_id = MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORNEXT,
  205. }
  206. };
  207. static int (*ckpt_aisexec_handler_fns[]) (void *msg, struct in_addr source_addr, int endian_conversion_required) = {
  208. message_handler_req_exec_ckpt_checkpointopen,
  209. message_handler_req_exec_ckpt_checkpointclose,
  210. message_handler_req_exec_ckpt_checkpointunlink,
  211. message_handler_req_exec_ckpt_checkpointretentiondurationset,
  212. message_handler_req_exec_ckpt_checkpointretentiondurationexpire,
  213. message_handler_req_exec_ckpt_sectioncreate,
  214. message_handler_req_exec_ckpt_sectiondelete,
  215. message_handler_req_exec_ckpt_sectionexpirationtimeset,
  216. message_handler_req_exec_ckpt_sectionwrite,
  217. message_handler_req_exec_ckpt_sectionoverwrite,
  218. message_handler_req_exec_ckpt_sectionread
  219. };
  220. struct service_handler ckpt_service_handler = {
  221. .libais_handlers = ckpt_libais_handlers,
  222. .libais_handlers_count = sizeof (ckpt_libais_handlers) / sizeof (struct libais_handler),
  223. .aisexec_handler_fns = ckpt_aisexec_handler_fns,
  224. .aisexec_handler_fns_count = sizeof (ckpt_aisexec_handler_fns) / sizeof (int (*)),
  225. .confchg_fn = ckpt_confchg_fn,
  226. .libais_init_fn = message_handler_req_lib_ckpt_init,
  227. .libais_exit_fn = ckpt_exit_fn,
  228. .exec_init_fn = ckpt_exec_init_fn,
  229. .exec_dump_fn = 0
  230. };
  231. static struct memb_ring_id saved_ring_id;
  232. static struct saCkptCheckpoint *ckpt_checkpoint_find_global (SaNameT *name)
  233. {
  234. struct list_head *checkpointList;
  235. struct saCkptCheckpoint *checkpoint;
  236. for (checkpointList = checkpointListHead.next;
  237. checkpointList != &checkpointListHead;
  238. checkpointList = checkpointList->next) {
  239. checkpoint = list_entry (checkpointList,
  240. struct saCkptCheckpoint, list);
  241. if (name_match (name, &checkpoint->name)) {
  242. return (checkpoint);
  243. }
  244. }
  245. return (0);
  246. }
  247. static void ckpt_checkpoint_remove_cleanup (
  248. struct conn_info *conn_info,
  249. struct saCkptCheckpoint *checkpoint)
  250. {
  251. struct list_head *list;
  252. struct checkpoint_cleanup *checkpoint_cleanup;
  253. for (list = conn_info->ais_ci.u.libckpt_ci.checkpoint_list.next;
  254. list != &conn_info->ais_ci.u.libckpt_ci.checkpoint_list;
  255. list = list->next) {
  256. checkpoint_cleanup = list_entry (list,
  257. struct checkpoint_cleanup, list);
  258. if (checkpoint_cleanup->checkpoint == checkpoint) {
  259. list_del (&checkpoint_cleanup->list);
  260. free (checkpoint_cleanup);
  261. return;
  262. }
  263. }
  264. }
  265. static struct saCkptCheckpointSection *ckpt_checkpoint_find_globalSection (
  266. struct saCkptCheckpoint *ckptCheckpoint,
  267. char *id,
  268. int idLen)
  269. {
  270. struct list_head *checkpointSectionList;
  271. struct saCkptCheckpointSection *ckptCheckpointSection;
  272. log_printf (LOG_LEVEL_DEBUG, "Finding checkpoint section id %s %d\n", id, idLen);
  273. for (checkpointSectionList = ckptCheckpoint->checkpointSectionsListHead.next;
  274. checkpointSectionList != &ckptCheckpoint->checkpointSectionsListHead;
  275. checkpointSectionList = checkpointSectionList->next) {
  276. ckptCheckpointSection = list_entry (checkpointSectionList,
  277. struct saCkptCheckpointSection, list);
  278. log_printf (LOG_LEVEL_DEBUG, "Checking section id %*s\n",
  279. (int)ckptCheckpointSection->sectionDescriptor.sectionId.idLen,
  280. ckptCheckpointSection->sectionDescriptor.sectionId.id);
  281. if (ckptCheckpointSection->sectionDescriptor.sectionId.idLen == idLen &&
  282. (memcmp (ckptCheckpointSection->sectionDescriptor.sectionId.id,
  283. id, idLen) == 0)) {
  284. return (ckptCheckpointSection);
  285. }
  286. }
  287. return 0;
  288. }
  289. void checkpoint_section_release (struct saCkptCheckpointSection *section)
  290. {
  291. list_del (&section->list);
  292. free (section->sectionDescriptor.sectionId.id);
  293. free (section->sectionData);
  294. poll_timer_delete (aisexec_poll_handle, section->expiration_timer);
  295. free (section);
  296. }
  297. void checkpoint_release (struct saCkptCheckpoint *checkpoint)
  298. {
  299. struct list_head *list;
  300. struct saCkptCheckpointSection *section;
  301. poll_timer_delete (aisexec_poll_handle, checkpoint->retention_timer);
  302. /*
  303. * Release all checkpoint sections for this checkpoint
  304. */
  305. for (list = checkpoint->checkpointSectionsListHead.next;
  306. list != &checkpoint->checkpointSectionsListHead;) {
  307. section = list_entry (list,
  308. struct saCkptCheckpointSection, list);
  309. list = list->next;
  310. checkpoint_section_release (section);
  311. }
  312. list_del (&checkpoint->list);
  313. free (checkpoint);
  314. }
  315. int ckpt_checkpoint_close (struct saCkptCheckpoint *checkpoint) {
  316. struct req_exec_ckpt_checkpointclose req_exec_ckpt_checkpointclose;
  317. struct iovec iovecs[2];
  318. if (checkpoint->expired == 1) {
  319. return (0);
  320. }
  321. req_exec_ckpt_checkpointclose.header.size =
  322. sizeof (struct req_exec_ckpt_checkpointclose);
  323. req_exec_ckpt_checkpointclose.header.id = MESSAGE_REQ_EXEC_CKPT_CHECKPOINTCLOSE;
  324. memcpy (&req_exec_ckpt_checkpointclose.checkpointName,
  325. &checkpoint->name, sizeof (SaNameT));
  326. iovecs[0].iov_base = (char *)&req_exec_ckpt_checkpointclose;
  327. iovecs[0].iov_len = sizeof (req_exec_ckpt_checkpointclose);
  328. if (totempg_send_ok (sizeof (struct req_exec_ckpt_checkpointclose))) {
  329. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  330. return (0);
  331. }
  332. return (-1);
  333. }
  334. static int ckpt_exec_init_fn (void)
  335. {
  336. // Initialize the saved ring ID.
  337. saved_ring_id.seq = 0;
  338. saved_ring_id.rep.s_addr = this_ip.sin_addr.s_addr;
  339. #ifdef TODO
  340. int res;
  341. res = totempg_recovery_plug_create (&ckpt_checkpoint_recovery_plug_handle);
  342. if (res != 0) {
  343. log_printf(LOG_LEVEL_ERROR,
  344. "Could not create recovery plug for clm service.\n");
  345. return (-1);
  346. }
  347. #endif
  348. return (0);
  349. }
  350. static int ckpt_exit_fn (struct conn_info *conn_info)
  351. {
  352. struct checkpoint_cleanup *checkpoint_cleanup;
  353. struct list_head *list;
  354. if (conn_info->service != SOCKET_SERVICE_CKPT) {
  355. return 0;
  356. }
  357. /*
  358. * close all checkpoints opened on this fd
  359. */
  360. for (list = conn_info->ais_ci.u.libckpt_ci.checkpoint_list.next;
  361. list != &conn_info->ais_ci.u.libckpt_ci.checkpoint_list;) {
  362. checkpoint_cleanup = list_entry (list,
  363. struct checkpoint_cleanup, list);
  364. ckpt_checkpoint_close (checkpoint_cleanup->checkpoint);
  365. list = list->next;
  366. free (checkpoint_cleanup);
  367. }
  368. #ifdef TODO
  369. /* todo close section iterators
  370. */
  371. // TODO what about exit of open checkpoints
  372. if (conn_info->ais_ci.u.libckpt_ci.sectionIterator.sectionIteratorEntries) {
  373. free (conn_info->ais_ci.u.libckpt_ci.sectionIterator.sectionIteratorEntries);
  374. }
  375. list_del (&conn_info->ais_ci.u.libckpt_ci.sectionIterator.list);
  376. #endif
  377. return (0);
  378. }
  379. static int message_handler_req_lib_activatepoll (struct conn_info *conn_info, void *message)
  380. {
  381. struct res_lib_activatepoll res_lib_activatepoll;
  382. res_lib_activatepoll.header.size = sizeof (struct res_lib_activatepoll);
  383. res_lib_activatepoll.header.id = MESSAGE_RES_LIB_ACTIVATEPOLL;
  384. res_lib_activatepoll.header.error = SA_AIS_OK;
  385. libais_send_response (conn_info, &res_lib_activatepoll,
  386. sizeof (struct res_lib_activatepoll));
  387. return (0);
  388. }
  389. static int message_handler_req_exec_ckpt_checkpointopen (void *message, struct in_addr source_addr, int endian_conversion_required)
  390. {
  391. struct req_exec_ckpt_checkpointopen *req_exec_ckpt_checkpointopen = (struct req_exec_ckpt_checkpointopen *)message;
  392. struct req_lib_ckpt_checkpointopen *req_lib_ckpt_checkpointopen = (struct req_lib_ckpt_checkpointopen *)&req_exec_ckpt_checkpointopen->req_lib_ckpt_checkpointopen;
  393. struct res_lib_ckpt_checkpointopen res_lib_ckpt_checkpointopen;
  394. struct saCkptCheckpoint *ckptCheckpoint = 0;
  395. struct saCkptCheckpointSection *ckptCheckpointSection = 0;
  396. struct checkpoint_cleanup *checkpoint_cleanup;
  397. SaErrorT error = SA_AIS_OK;
  398. log_printf (LOG_LEVEL_DEBUG, "Executive request to open checkpoint %p\n", req_exec_ckpt_checkpointopen);
  399. ckptCheckpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_checkpointopen->checkpointName);
  400. /*
  401. * If checkpoint doesn't exist, create one
  402. */
  403. if (ckptCheckpoint == 0) {
  404. ckptCheckpoint = malloc (sizeof (struct saCkptCheckpoint));
  405. if (ckptCheckpoint == 0) {
  406. error = SA_AIS_ERR_NO_MEMORY;
  407. goto error_exit;
  408. }
  409. ckptCheckpointSection = malloc (sizeof (struct saCkptCheckpointSection));
  410. if (ckptCheckpointSection == 0) {
  411. free (ckptCheckpoint);
  412. error = SA_AIS_ERR_NO_MEMORY;
  413. goto error_exit;
  414. }
  415. memcpy (&ckptCheckpoint->name,
  416. &req_lib_ckpt_checkpointopen->checkpointName,
  417. sizeof (SaNameT));
  418. memcpy (&ckptCheckpoint->checkpointCreationAttributes,
  419. &req_lib_ckpt_checkpointopen->checkpointCreationAttributes,
  420. sizeof (SaCkptCheckpointCreationAttributesT));
  421. ckptCheckpoint->unlinked = 0;
  422. list_init (&ckptCheckpoint->list);
  423. list_init (&ckptCheckpoint->checkpointSectionsListHead);
  424. list_add (&ckptCheckpoint->list, &checkpointListHead);
  425. ckptCheckpoint->referenceCount = 0;
  426. ckptCheckpoint->retention_timer = 0;
  427. ckptCheckpoint->expired = 0;
  428. /*
  429. * Add in default checkpoint section
  430. */
  431. list_init (&ckptCheckpointSection->list);
  432. list_add (&ckptCheckpointSection->list, &ckptCheckpoint->checkpointSectionsListHead);
  433. /*
  434. * Default section id
  435. */
  436. ckptCheckpointSection->sectionDescriptor.sectionId.id = 0;
  437. ckptCheckpointSection->sectionDescriptor.sectionId.idLen = 0;
  438. ckptCheckpointSection->sectionDescriptor.sectionSize = 0;
  439. ckptCheckpointSection->sectionDescriptor.expirationTime = SA_TIME_END;
  440. ckptCheckpointSection->sectionDescriptor.sectionState = SA_CKPT_SECTION_VALID;
  441. ckptCheckpointSection->sectionDescriptor.lastUpdate = 0; // current time
  442. ckptCheckpointSection->sectionData = 0;
  443. ckptCheckpointSection->expiration_timer = 0;
  444. }
  445. /*
  446. * If the checkpoint has been unlinked, it is an invalid name
  447. */
  448. if (ckptCheckpoint->unlinked) {
  449. error = SA_AIS_ERR_INVALID_PARAM; /* Is this the correct return ? */
  450. goto error_exit;
  451. }
  452. /*
  453. * Setup connection information and mark checkpoint as referenced
  454. */
  455. log_printf (LOG_LEVEL_DEBUG, "CHECKPOINT opened is %p\n", ckptCheckpoint);
  456. ckptCheckpoint->referenceCount += 1;
  457. /*
  458. * Reset retention duration since this checkpoint was just opened
  459. */
  460. poll_timer_delete (aisexec_poll_handle, ckptCheckpoint->retention_timer);
  461. ckptCheckpoint->retention_timer = 0;
  462. /*
  463. * Send error result to CKPT library
  464. */
  465. error_exit:
  466. /*
  467. * If this node was the source of the message, respond to this node
  468. */
  469. if (req_exec_ckpt_checkpointopen->source.in_addr.s_addr == this_ip.sin_addr.s_addr) {
  470. res_lib_ckpt_checkpointopen.header.size = sizeof (struct res_lib_ckpt_checkpointopen);
  471. res_lib_ckpt_checkpointopen.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTOPEN;
  472. res_lib_ckpt_checkpointopen.header.error = error;
  473. checkpoint_cleanup = malloc (sizeof (struct checkpoint_cleanup));
  474. if (checkpoint_cleanup == 0) {
  475. free (ckptCheckpoint);
  476. error = SA_AIS_ERR_NO_MEMORY;
  477. } else {
  478. checkpoint_cleanup->checkpoint = ckptCheckpoint;
  479. list_add (&checkpoint_cleanup->list,
  480. &req_exec_ckpt_checkpointopen->source.conn_info->ais_ci.u.libckpt_ci.checkpoint_list);
  481. }
  482. libais_send_response (req_exec_ckpt_checkpointopen->source.conn_info, &res_lib_ckpt_checkpointopen,
  483. sizeof (struct res_lib_ckpt_checkpointopen));
  484. }
  485. // return (error == SA_AIS_OK ? 0 : -1);
  486. return (0);
  487. }
  488. unsigned int abstime_to_msec (SaTimeT time)
  489. {
  490. struct timeval tv;
  491. unsigned long long curr_time;
  492. unsigned long long msec_time;
  493. gettimeofday (&tv, NULL);
  494. curr_time = ((((unsigned long long)tv.tv_sec) * ((unsigned long)1000)) +
  495. (((unsigned long long)tv.tv_usec) / ((unsigned long long)1000)));
  496. msec_time = (((unsigned long long)time) / 1000000) -
  497. (unsigned long long)curr_time;
  498. return ((unsigned int)(msec_time));
  499. }
  500. void timer_function_section_expire (void *data)
  501. {
  502. struct saCkptCheckpointSection *section = (struct saCkptCheckpointSection *)data;
  503. if (section->sectionDescriptor.sectionId.id) {
  504. log_printf (LOG_LEVEL_NOTICE, "CKPT: Expiring section %s\n", section->sectionDescriptor.sectionId.id);
  505. }
  506. checkpoint_section_release (section);
  507. }
  508. void timer_function_retention (void *data)
  509. {
  510. struct saCkptCheckpoint *checkpoint = (struct saCkptCheckpoint *)data;
  511. struct req_exec_ckpt_checkpointretentiondurationexpire req_exec_ckpt_checkpointretentiondurationexpire;
  512. struct iovec iovec;
  513. checkpoint->retention_timer = 0;
  514. req_exec_ckpt_checkpointretentiondurationexpire.header.size =
  515. sizeof (struct req_exec_ckpt_checkpointretentiondurationexpire);
  516. req_exec_ckpt_checkpointretentiondurationexpire.header.id = MESSAGE_REQ_EXEC_CKPT_CHECKPOINTRETENTIONDURATIONEXPIRE;
  517. memcpy (&req_exec_ckpt_checkpointretentiondurationexpire.checkpointName,
  518. &checkpoint->name,
  519. sizeof (SaNameT));
  520. iovec.iov_base = (char *)&req_exec_ckpt_checkpointretentiondurationexpire;
  521. iovec.iov_len = sizeof (req_exec_ckpt_checkpointretentiondurationexpire);
  522. assert (totempg_mcast (&iovec, 1, TOTEMPG_AGREED) == 0);
  523. }
  524. extern int message_handler_req_exec_ckpt_checkpointclose (void *message, struct in_addr source_addr, int endian_conversion_required)
  525. {
  526. struct req_exec_ckpt_checkpointclose *req_exec_ckpt_checkpointclose = (struct req_exec_ckpt_checkpointclose *)message;
  527. struct res_lib_ckpt_checkpointclose res_lib_ckpt_checkpointclose;
  528. struct saCkptCheckpoint *checkpoint = 0;
  529. SaAisErrorT error = SA_AIS_OK;
  530. log_printf (LOG_LEVEL_DEBUG, "Got EXEC request to close checkpoint %s\n", getSaNameT (&req_exec_ckpt_checkpointclose->checkpointName));
  531. checkpoint = ckpt_checkpoint_find_global (&req_exec_ckpt_checkpointclose->checkpointName);
  532. if (checkpoint == 0) {
  533. goto error_exit;
  534. }
  535. checkpoint->referenceCount--;
  536. assert (checkpoint->referenceCount >= 0);
  537. log_printf (LOG_LEVEL_DEBUG, "disconnect called, new CKPT ref count is %d\n",
  538. checkpoint->referenceCount);
  539. /*
  540. * If checkpoint has been unlinked and this is the last reference, delete it
  541. */
  542. if (checkpoint->unlinked && checkpoint->referenceCount == 0) {
  543. log_printf (LOG_LEVEL_DEBUG, "Unlinking checkpoint.\n");
  544. checkpoint_release (checkpoint);
  545. } else
  546. if (checkpoint->referenceCount == 0) {
  547. poll_timer_add (aisexec_poll_handle,
  548. checkpoint->checkpointCreationAttributes.retentionDuration / 1000000,
  549. checkpoint,
  550. timer_function_retention,
  551. &checkpoint->retention_timer);
  552. }
  553. error_exit:
  554. if (req_exec_ckpt_checkpointclose->source.in_addr.s_addr == this_ip.sin_addr.s_addr) {
  555. ckpt_checkpoint_remove_cleanup (req_exec_ckpt_checkpointclose->source.conn_info,
  556. checkpoint);
  557. res_lib_ckpt_checkpointclose.header.size = sizeof (struct res_lib_ckpt_checkpointclose);
  558. res_lib_ckpt_checkpointclose.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTCLOSE;
  559. res_lib_ckpt_checkpointclose.header.error = error;
  560. libais_send_response (req_exec_ckpt_checkpointclose->source.conn_info,
  561. &res_lib_ckpt_checkpointclose, sizeof (struct res_lib_ckpt_checkpointclose));
  562. }
  563. return (0);
  564. }
  565. static int message_handler_req_exec_ckpt_checkpointunlink (void *message, struct in_addr source_addr, int endian_conversion_required)
  566. {
  567. struct req_exec_ckpt_checkpointunlink *req_exec_ckpt_checkpointunlink = (struct req_exec_ckpt_checkpointunlink *)message;
  568. struct req_lib_ckpt_checkpointunlink *req_lib_ckpt_checkpointunlink = (struct req_lib_ckpt_checkpointunlink *)&req_exec_ckpt_checkpointunlink->req_lib_ckpt_checkpointunlink;
  569. struct res_lib_ckpt_checkpointunlink res_lib_ckpt_checkpointunlink;
  570. struct saCkptCheckpoint *ckptCheckpoint = 0;
  571. SaErrorT error = SA_AIS_OK;
  572. log_printf (LOG_LEVEL_DEBUG, "Got EXEC request to unlink checkpoint %p\n", req_exec_ckpt_checkpointunlink);
  573. ckptCheckpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_checkpointunlink->checkpointName);
  574. if (ckptCheckpoint == 0) {
  575. error = SA_AIS_ERR_NOT_EXIST;
  576. goto error_exit;
  577. }
  578. if (ckptCheckpoint->unlinked) {
  579. error = SA_AIS_ERR_INVALID_PARAM;
  580. goto error_exit;
  581. }
  582. ckptCheckpoint->unlinked = 1;
  583. /*
  584. * Immediately delete entry if reference count is zero
  585. */
  586. if (ckptCheckpoint->referenceCount == 0) {
  587. /*
  588. * Remove retention timer since this checkpoint was unlinked and is no
  589. * longer referenced
  590. */
  591. checkpoint_release (ckptCheckpoint);
  592. }
  593. error_exit:
  594. /*
  595. * If this node was the source of the message, respond to this node
  596. */
  597. if (req_exec_ckpt_checkpointunlink->source.in_addr.s_addr == this_ip.sin_addr.s_addr) {
  598. res_lib_ckpt_checkpointunlink.header.size = sizeof (struct res_lib_ckpt_checkpointunlink);
  599. res_lib_ckpt_checkpointunlink.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTUNLINK;
  600. res_lib_ckpt_checkpointunlink.header.error = error;
  601. libais_send_response (req_exec_ckpt_checkpointunlink->source.conn_info, &res_lib_ckpt_checkpointunlink,
  602. sizeof (struct res_lib_ckpt_checkpointunlink));
  603. }
  604. return (0);
  605. }
  606. static int message_handler_req_exec_ckpt_checkpointretentiondurationset (void *message, struct in_addr source_addr, int endian_conversion_required)
  607. {
  608. struct req_exec_ckpt_checkpointretentiondurationset *req_exec_ckpt_checkpointretentiondurationset = (struct req_exec_ckpt_checkpointretentiondurationset *)message;
  609. struct res_lib_ckpt_checkpointretentiondurationset res_lib_ckpt_checkpointretentiondurationset;
  610. struct saCkptCheckpoint *checkpoint;
  611. checkpoint = ckpt_checkpoint_find_global (&req_exec_ckpt_checkpointretentiondurationset->checkpointName);
  612. if (checkpoint) {
  613. log_printf (LOG_LEVEL_NOTICE, "CKPT: Setting retention duration for checkpoint %s\n",
  614. getSaNameT (&req_exec_ckpt_checkpointretentiondurationset->checkpointName));
  615. checkpoint->checkpointCreationAttributes.retentionDuration = req_exec_ckpt_checkpointretentiondurationset->retentionDuration;
  616. if (checkpoint->expired == 0 && checkpoint->referenceCount == 0) {
  617. poll_timer_delete (aisexec_poll_handle, checkpoint->retention_timer);
  618. poll_timer_add (aisexec_poll_handle,
  619. checkpoint->checkpointCreationAttributes.retentionDuration / 1000000,
  620. checkpoint,
  621. timer_function_retention,
  622. &checkpoint->retention_timer);
  623. }
  624. }
  625. /*
  626. * Respond to library if this processor sent the duration set request
  627. */
  628. if (req_exec_ckpt_checkpointretentiondurationset->source.in_addr.s_addr == this_ip.sin_addr.s_addr) {
  629. res_lib_ckpt_checkpointretentiondurationset.header.size = sizeof (struct res_lib_ckpt_checkpointretentiondurationset);
  630. res_lib_ckpt_checkpointretentiondurationset.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTRETENTIONDURATIONSET;
  631. res_lib_ckpt_checkpointretentiondurationset.header.error = SA_AIS_OK;
  632. libais_send_response (req_exec_ckpt_checkpointretentiondurationset->source.conn_info,
  633. &res_lib_ckpt_checkpointretentiondurationset,
  634. sizeof (struct res_lib_ckpt_checkpointretentiondurationset));
  635. }
  636. return (0);
  637. }
  638. static int message_handler_req_exec_ckpt_checkpointretentiondurationexpire (void *message, struct in_addr source_addr, int endian_conversion_required)
  639. {
  640. struct req_exec_ckpt_checkpointretentiondurationexpire *req_exec_ckpt_checkpointretentiondurationexpire = (struct req_exec_ckpt_checkpointretentiondurationexpire *)message;
  641. struct req_exec_ckpt_checkpointunlink req_exec_ckpt_checkpointunlink;
  642. struct saCkptCheckpoint *checkpoint;
  643. struct iovec iovecs[2];
  644. checkpoint = ckpt_checkpoint_find_global (&req_exec_ckpt_checkpointretentiondurationexpire->checkpointName);
  645. if (checkpoint && checkpoint->expired == 0) {
  646. log_printf (LOG_LEVEL_NOTICE, "CKPT: Expiring checkpoint %s\n", getSaNameT (&req_exec_ckpt_checkpointretentiondurationexpire->checkpointName));
  647. checkpoint->expired = 1;
  648. req_exec_ckpt_checkpointunlink.header.size =
  649. sizeof (struct req_exec_ckpt_checkpointunlink);
  650. req_exec_ckpt_checkpointunlink.header.id = MESSAGE_REQ_EXEC_CKPT_CHECKPOINTUNLINK;
  651. req_exec_ckpt_checkpointunlink.source.conn_info = 0;
  652. req_exec_ckpt_checkpointunlink.source.in_addr.s_addr = 0;
  653. memcpy (&req_exec_ckpt_checkpointunlink.req_lib_ckpt_checkpointunlink.checkpointName,
  654. &req_exec_ckpt_checkpointretentiondurationexpire->checkpointName,
  655. sizeof (SaNameT));
  656. iovecs[0].iov_base = (char *)&req_exec_ckpt_checkpointunlink;
  657. iovecs[0].iov_len = sizeof (req_exec_ckpt_checkpointunlink);
  658. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  659. }
  660. return (0);
  661. }
  662. static int message_handler_req_exec_ckpt_sectioncreate (void *message, struct in_addr source_addr, int endian_conversion_required) {
  663. struct req_exec_ckpt_sectioncreate *req_exec_ckpt_sectioncreate = (struct req_exec_ckpt_sectioncreate *)message;
  664. struct req_lib_ckpt_sectioncreate *req_lib_ckpt_sectioncreate = (struct req_lib_ckpt_sectioncreate *)&req_exec_ckpt_sectioncreate->req_lib_ckpt_sectioncreate;
  665. struct res_lib_ckpt_sectioncreate res_lib_ckpt_sectioncreate;
  666. struct saCkptCheckpoint *ckptCheckpoint;
  667. struct saCkptCheckpointSection *ckptCheckpointSection;
  668. void *initialData;
  669. void *sectionId;
  670. SaErrorT error = SA_AIS_OK;
  671. log_printf (LOG_LEVEL_DEBUG, "Executive request to create a checkpoint section.\n");
  672. ckptCheckpoint = ckpt_checkpoint_find_global (&req_exec_ckpt_sectioncreate->checkpointName);
  673. if (ckptCheckpoint == 0) {
  674. error = SA_AIS_ERR_LIBRARY; // TODO find the right error for this
  675. goto error_exit;
  676. }
  677. /*
  678. * Determine if user-specified checkpoint ID already exists
  679. */
  680. ckptCheckpointSection = ckpt_checkpoint_find_globalSection (ckptCheckpoint,
  681. ((char *)req_lib_ckpt_sectioncreate) + sizeof (struct req_lib_ckpt_sectioncreate),
  682. req_lib_ckpt_sectioncreate->idLen);
  683. if (ckptCheckpointSection) {
  684. error = SA_AIS_ERR_EXIST;
  685. goto error_exit;
  686. }
  687. /*
  688. * Allocate checkpoint section
  689. */
  690. ckptCheckpointSection = malloc (sizeof (struct saCkptCheckpointSection));
  691. if (ckptCheckpointSection == 0) {
  692. error = SA_AIS_ERR_NO_MEMORY;
  693. goto error_exit;
  694. }
  695. /*
  696. * Allocate checkpoint section data
  697. */
  698. initialData = malloc (req_lib_ckpt_sectioncreate->initialDataSize);
  699. if (initialData == 0) {
  700. free (ckptCheckpointSection);
  701. error = SA_AIS_ERR_NO_MEMORY;
  702. goto error_exit;
  703. }
  704. /*
  705. * Allocate checkpoint section id
  706. */
  707. sectionId = malloc (req_lib_ckpt_sectioncreate->idLen);
  708. if (sectionId == 0) {
  709. free (ckptCheckpointSection);
  710. free (initialData);
  711. error = SA_AIS_ERR_NO_MEMORY;
  712. goto error_exit;
  713. }
  714. /*
  715. * Copy checkpoint section and section ID
  716. */
  717. memcpy (sectionId, ((char *)req_lib_ckpt_sectioncreate) + sizeof (struct req_lib_ckpt_sectioncreate),
  718. req_lib_ckpt_sectioncreate->idLen);
  719. memcpy (initialData,
  720. ((char *)req_lib_ckpt_sectioncreate) +
  721. sizeof (struct req_lib_ckpt_sectioncreate) +
  722. req_lib_ckpt_sectioncreate->idLen,
  723. req_lib_ckpt_sectioncreate->initialDataSize);
  724. /*
  725. * Configure checkpoint section
  726. */
  727. ckptCheckpointSection->sectionDescriptor.sectionId.id = sectionId;
  728. ckptCheckpointSection->sectionDescriptor.sectionId.idLen = req_lib_ckpt_sectioncreate->idLen;
  729. ckptCheckpointSection->sectionDescriptor.sectionSize = req_lib_ckpt_sectioncreate->initialDataSize;
  730. ckptCheckpointSection->sectionDescriptor.expirationTime = req_lib_ckpt_sectioncreate->expirationTime;
  731. ckptCheckpointSection->sectionDescriptor.sectionState = SA_CKPT_SECTION_VALID;
  732. ckptCheckpointSection->sectionDescriptor.lastUpdate = 0; // TODO current time
  733. ckptCheckpointSection->sectionData = initialData;
  734. ckptCheckpointSection->expiration_timer = 0;
  735. if (req_lib_ckpt_sectioncreate->expirationTime != SA_TIME_END) {
  736. poll_timer_add (aisexec_poll_handle,
  737. abstime_to_msec (ckptCheckpointSection->sectionDescriptor.expirationTime),
  738. ckptCheckpointSection,
  739. timer_function_section_expire,
  740. &ckptCheckpointSection->expiration_timer);
  741. }
  742. /*
  743. * Add checkpoint section to checkpoint
  744. */
  745. list_init (&ckptCheckpointSection->list);
  746. list_add (&ckptCheckpointSection->list,
  747. &ckptCheckpoint->checkpointSectionsListHead);
  748. error_exit:
  749. if (req_exec_ckpt_sectioncreate->source.in_addr.s_addr == this_ip.sin_addr.s_addr) {
  750. res_lib_ckpt_sectioncreate.header.size = sizeof (struct res_lib_ckpt_sectioncreate);
  751. res_lib_ckpt_sectioncreate.header.id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONCREATE;
  752. res_lib_ckpt_sectioncreate.header.error = error;
  753. libais_send_response (req_exec_ckpt_sectioncreate->source.conn_info,
  754. &res_lib_ckpt_sectioncreate,
  755. sizeof (struct res_lib_ckpt_sectioncreate));
  756. }
  757. return (0);
  758. }
  759. static int message_handler_req_exec_ckpt_sectiondelete (void *message, struct in_addr source_addr, int endian_conversion_required) {
  760. struct req_exec_ckpt_sectiondelete *req_exec_ckpt_sectiondelete = (struct req_exec_ckpt_sectiondelete *)message;
  761. struct req_lib_ckpt_sectiondelete *req_lib_ckpt_sectiondelete = (struct req_lib_ckpt_sectiondelete *)&req_exec_ckpt_sectiondelete->req_lib_ckpt_sectiondelete;
  762. struct res_lib_ckpt_sectiondelete res_lib_ckpt_sectiondelete;
  763. struct saCkptCheckpoint *ckptCheckpoint;
  764. struct saCkptCheckpointSection *ckptCheckpointSection;
  765. SaErrorT error = SA_AIS_OK;
  766. ckptCheckpoint = ckpt_checkpoint_find_global (&req_exec_ckpt_sectiondelete->checkpointName);
  767. if (ckptCheckpoint == 0) {
  768. error = SA_AIS_ERR_NOT_EXIST;
  769. goto error_exit;
  770. }
  771. /*
  772. * Determine if the user is trying to delete the default section
  773. */
  774. if (req_lib_ckpt_sectiondelete->idLen == 0) {
  775. error = SA_AIS_ERR_INVALID_PARAM;
  776. goto error_exit;
  777. }
  778. /*
  779. * Find checkpoint section to be deleted
  780. */
  781. ckptCheckpointSection = ckpt_checkpoint_find_globalSection (ckptCheckpoint,
  782. ((char *)(req_lib_ckpt_sectiondelete) + sizeof (struct req_lib_ckpt_sectiondelete)),
  783. req_lib_ckpt_sectiondelete->idLen);
  784. if (ckptCheckpointSection == 0) {
  785. error = SA_AIS_ERR_NOT_EXIST;
  786. goto error_exit;
  787. }
  788. /*
  789. * Delete checkpoint section
  790. */
  791. checkpoint_section_release (ckptCheckpointSection);
  792. /*
  793. * return result to CKPT library
  794. */
  795. error_exit:
  796. if (req_exec_ckpt_sectiondelete->source.in_addr.s_addr == this_ip.sin_addr.s_addr) {
  797. res_lib_ckpt_sectiondelete.header.size = sizeof (struct res_lib_ckpt_sectiondelete);
  798. res_lib_ckpt_sectiondelete.header.id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONDELETE;
  799. res_lib_ckpt_sectiondelete.header.error = error;
  800. libais_send_response (req_exec_ckpt_sectiondelete->source.conn_info,
  801. &res_lib_ckpt_sectiondelete,
  802. sizeof (struct res_lib_ckpt_sectiondelete));
  803. }
  804. return (0);
  805. }
  806. static int message_handler_req_exec_ckpt_sectionexpirationtimeset (void *message, struct in_addr source_addr, int endian_conversion_required) {
  807. struct req_exec_ckpt_sectionexpirationtimeset *req_exec_ckpt_sectionexpirationtimeset = (struct req_exec_ckpt_sectionexpirationtimeset *)message;
  808. struct req_lib_ckpt_sectionexpirationtimeset *req_lib_ckpt_sectionexpirationtimeset = (struct req_lib_ckpt_sectionexpirationtimeset *)&req_exec_ckpt_sectionexpirationtimeset->req_lib_ckpt_sectionexpirationtimeset;
  809. struct res_lib_ckpt_sectionexpirationtimeset res_lib_ckpt_sectionexpirationtimeset;
  810. struct saCkptCheckpoint *ckptCheckpoint;
  811. struct saCkptCheckpointSection *ckptCheckpointSection;
  812. SaErrorT error = SA_AIS_OK;
  813. log_printf (LOG_LEVEL_DEBUG, "Executive request to set section expiratoin time\n");
  814. ckptCheckpoint = ckpt_checkpoint_find_global (&req_exec_ckpt_sectionexpirationtimeset->checkpointName);
  815. if (ckptCheckpoint == 0) {
  816. error = SA_AIS_ERR_NOT_EXIST;
  817. goto error_exit;
  818. }
  819. /*
  820. * Determine if the user is trying to set expiration time for the default section
  821. */
  822. if (req_lib_ckpt_sectionexpirationtimeset->idLen == 0) {
  823. error = SA_AIS_ERR_INVALID_PARAM;
  824. goto error_exit;
  825. }
  826. /*
  827. * Find checkpoint section that expiration time should be set for
  828. */
  829. ckptCheckpointSection = ckpt_checkpoint_find_globalSection (ckptCheckpoint,
  830. ((char *)req_lib_ckpt_sectionexpirationtimeset) +
  831. sizeof (struct req_lib_ckpt_sectionexpirationtimeset),
  832. req_lib_ckpt_sectionexpirationtimeset->idLen);
  833. if (ckptCheckpointSection == 0) {
  834. error = SA_AIS_ERR_NOT_EXIST;
  835. goto error_exit;
  836. }
  837. ckptCheckpointSection->sectionDescriptor.expirationTime = req_lib_ckpt_sectionexpirationtimeset->expirationTime;
  838. poll_timer_delete (aisexec_poll_handle, ckptCheckpointSection->expiration_timer);
  839. ckptCheckpointSection->expiration_timer = 0;
  840. if (req_lib_ckpt_sectionexpirationtimeset->expirationTime != SA_TIME_END) {
  841. poll_timer_add (aisexec_poll_handle,
  842. abstime_to_msec (ckptCheckpointSection->sectionDescriptor.expirationTime),
  843. ckptCheckpointSection,
  844. timer_function_section_expire,
  845. &ckptCheckpointSection->expiration_timer);
  846. }
  847. error_exit:
  848. if (req_exec_ckpt_sectionexpirationtimeset->source.in_addr.s_addr == this_ip.sin_addr.s_addr) {
  849. res_lib_ckpt_sectionexpirationtimeset.header.size = sizeof (struct res_lib_ckpt_sectionexpirationtimeset);
  850. res_lib_ckpt_sectionexpirationtimeset.header.id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONEXPIRATIONTIMESET;
  851. res_lib_ckpt_sectionexpirationtimeset.header.error = error;
  852. libais_send_response (req_exec_ckpt_sectionexpirationtimeset->source.conn_info,
  853. &res_lib_ckpt_sectionexpirationtimeset,
  854. sizeof (struct res_lib_ckpt_sectionexpirationtimeset));
  855. }
  856. return (0);
  857. }
  858. static int message_handler_req_exec_ckpt_sectionwrite (void *message, struct in_addr source_addr, int endian_conversion_required) {
  859. struct req_exec_ckpt_sectionwrite *req_exec_ckpt_sectionwrite = (struct req_exec_ckpt_sectionwrite *)message;
  860. struct req_lib_ckpt_sectionwrite *req_lib_ckpt_sectionwrite = (struct req_lib_ckpt_sectionwrite *)&req_exec_ckpt_sectionwrite->req_lib_ckpt_sectionwrite;
  861. struct res_lib_ckpt_sectionwrite res_lib_ckpt_sectionwrite;
  862. struct saCkptCheckpoint *ckptCheckpoint;
  863. struct saCkptCheckpointSection *ckptCheckpointSection;
  864. int sizeRequired;
  865. void *sectionData;
  866. SaErrorT error = SA_AIS_OK;
  867. log_printf (LOG_LEVEL_DEBUG, "Executive request to section write.\n");
  868. ckptCheckpoint = ckpt_checkpoint_find_global (&req_exec_ckpt_sectionwrite->checkpointName);
  869. if (ckptCheckpoint == 0) {
  870. error = SA_AIS_ERR_NOT_EXIST;
  871. goto error_exit;
  872. }
  873. //printf ("writing checkpoint section is %s\n", ((char *)req_lib_ckpt_sectionwrite) + sizeof (struct req_lib_ckpt_sectionwrite));
  874. /*
  875. * Find checkpoint section to be written
  876. */
  877. ckptCheckpointSection = ckpt_checkpoint_find_globalSection (ckptCheckpoint,
  878. ((char *)req_lib_ckpt_sectionwrite) + sizeof (struct req_lib_ckpt_sectionwrite),
  879. req_lib_ckpt_sectionwrite->idLen);
  880. if (ckptCheckpointSection == 0) {
  881. printf ("CANT FIND SECTION '%s'\n",
  882. ((char *)req_lib_ckpt_sectionwrite) + sizeof (struct req_lib_ckpt_sectionwrite));
  883. error = SA_AIS_ERR_NOT_EXIST;
  884. goto error_exit;
  885. }
  886. /*
  887. * If write would extend past end of section data, enlarge section
  888. */
  889. sizeRequired = req_lib_ckpt_sectionwrite->dataOffset + req_lib_ckpt_sectionwrite->dataSize;
  890. if (sizeRequired > ckptCheckpointSection->sectionDescriptor.sectionSize) {
  891. sectionData = realloc (ckptCheckpointSection->sectionData, sizeRequired);
  892. if (sectionData == 0) {
  893. error = SA_AIS_ERR_NO_MEMORY;
  894. goto error_exit;
  895. }
  896. /*
  897. * Install new section data
  898. */
  899. ckptCheckpointSection->sectionData = sectionData;
  900. ckptCheckpointSection->sectionDescriptor.sectionSize = sizeRequired;
  901. }
  902. /*
  903. * Write checkpoint section to section data
  904. */
  905. if (req_lib_ckpt_sectionwrite->dataSize > 0) {
  906. char *sd;
  907. int *val;
  908. val = ckptCheckpointSection->sectionData;
  909. sd = (char *)ckptCheckpointSection->sectionData;
  910. memcpy (&sd[req_lib_ckpt_sectionwrite->dataOffset],
  911. ((char *)req_exec_ckpt_sectionwrite) + sizeof (struct req_exec_ckpt_sectionwrite) +
  912. req_lib_ckpt_sectionwrite->idLen,
  913. req_lib_ckpt_sectionwrite->dataSize);
  914. }
  915. /*
  916. * Write write response to CKPT library
  917. */
  918. error_exit:
  919. if (req_exec_ckpt_sectionwrite->source.in_addr.s_addr == this_ip.sin_addr.s_addr) {
  920. res_lib_ckpt_sectionwrite.header.size = sizeof (struct res_lib_ckpt_sectionwrite);
  921. res_lib_ckpt_sectionwrite.header.id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONWRITE;
  922. res_lib_ckpt_sectionwrite.header.error = error;
  923. libais_send_response (req_exec_ckpt_sectionwrite->source.conn_info,
  924. &res_lib_ckpt_sectionwrite,
  925. sizeof (struct res_lib_ckpt_sectionwrite));
  926. }
  927. return (0);
  928. }
  929. static int message_handler_req_exec_ckpt_sectionoverwrite (void *message, struct in_addr source_addr, int endian_conversion_required) {
  930. struct req_exec_ckpt_sectionoverwrite *req_exec_ckpt_sectionoverwrite = (struct req_exec_ckpt_sectionoverwrite *)message;
  931. struct req_lib_ckpt_sectionoverwrite *req_lib_ckpt_sectionoverwrite = (struct req_lib_ckpt_sectionoverwrite *)&req_exec_ckpt_sectionoverwrite->req_lib_ckpt_sectionoverwrite;
  932. struct res_lib_ckpt_sectionoverwrite res_lib_ckpt_sectionoverwrite;
  933. struct saCkptCheckpoint *ckptCheckpoint;
  934. struct saCkptCheckpointSection *ckptCheckpointSection;
  935. void *sectionData;
  936. SaErrorT error = SA_AIS_OK;
  937. log_printf (LOG_LEVEL_DEBUG, "Executive request to section overwrite.\n");
  938. ckptCheckpoint = ckpt_checkpoint_find_global (&req_exec_ckpt_sectionoverwrite->checkpointName);
  939. if (ckptCheckpoint == 0) {
  940. error = SA_AIS_ERR_NOT_EXIST;
  941. goto error_exit;
  942. }
  943. /*
  944. * Find checkpoint section to be overwritten
  945. */
  946. ckptCheckpointSection = ckpt_checkpoint_find_globalSection (ckptCheckpoint,
  947. ((char *)req_lib_ckpt_sectionoverwrite) +
  948. sizeof (struct req_lib_ckpt_sectionoverwrite),
  949. req_lib_ckpt_sectionoverwrite->idLen);
  950. if (ckptCheckpointSection == 0) {
  951. error = SA_AIS_ERR_NOT_EXIST;
  952. goto error_exit;
  953. }
  954. /*
  955. * Allocate checkpoint section data
  956. */
  957. sectionData = malloc (req_lib_ckpt_sectionoverwrite->dataSize);
  958. if (sectionData == 0) {
  959. error = SA_AIS_ERR_NO_MEMORY;
  960. goto error_exit;
  961. }
  962. memcpy (sectionData,
  963. ((char *)req_lib_ckpt_sectionoverwrite) +
  964. sizeof (struct req_lib_ckpt_sectionoverwrite) +
  965. req_lib_ckpt_sectionoverwrite->idLen,
  966. req_lib_ckpt_sectionoverwrite->dataSize);
  967. /*
  968. * release old checkpoint section data
  969. */
  970. free (ckptCheckpointSection->sectionData);
  971. /*
  972. * Install overwritten checkpoint section data
  973. */
  974. ckptCheckpointSection->sectionDescriptor.sectionSize = req_lib_ckpt_sectionoverwrite->dataSize;
  975. ckptCheckpointSection->sectionDescriptor.sectionState = SA_CKPT_SECTION_VALID;
  976. ckptCheckpointSection->sectionDescriptor.lastUpdate = 0; // TODO current time
  977. ckptCheckpointSection->sectionData = sectionData;
  978. /*
  979. * return result to CKPT library
  980. */
  981. error_exit:
  982. if (req_exec_ckpt_sectionoverwrite->source.in_addr.s_addr == this_ip.sin_addr.s_addr) {
  983. res_lib_ckpt_sectionoverwrite.header.size = sizeof (struct res_lib_ckpt_sectionoverwrite);
  984. res_lib_ckpt_sectionoverwrite.header.id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONOVERWRITE;
  985. res_lib_ckpt_sectionoverwrite.header.error = error;
  986. libais_send_response (req_exec_ckpt_sectionoverwrite->source.conn_info,
  987. &res_lib_ckpt_sectionoverwrite,
  988. sizeof (struct res_lib_ckpt_sectionoverwrite));
  989. }
  990. return (0);
  991. }
  992. static int message_handler_req_exec_ckpt_sectionread (void *message, struct in_addr source_addr, int endian_conversion_required) {
  993. struct req_exec_ckpt_sectionread *req_exec_ckpt_sectionread = (struct req_exec_ckpt_sectionread *)message;
  994. struct req_lib_ckpt_sectionread *req_lib_ckpt_sectionread = (struct req_lib_ckpt_sectionread *)&req_exec_ckpt_sectionread->req_lib_ckpt_sectionread;
  995. struct res_lib_ckpt_sectionread res_lib_ckpt_sectionread;
  996. struct saCkptCheckpoint *ckptCheckpoint;
  997. struct saCkptCheckpointSection *ckptCheckpointSection = 0;
  998. int sectionSize = 0;
  999. SaErrorT error = SA_AIS_OK;
  1000. log_printf (LOG_LEVEL_DEBUG, "Executive request for section read.\n");
  1001. ckptCheckpoint = ckpt_checkpoint_find_global (&req_exec_ckpt_sectionread->checkpointName);
  1002. if (ckptCheckpoint == 0) {
  1003. error = SA_AIS_ERR_LIBRARY; // TODO find the right error for this
  1004. goto error_exit;
  1005. }
  1006. /*
  1007. * Find checkpoint section to be read
  1008. */
  1009. ckptCheckpointSection = ckpt_checkpoint_find_globalSection (ckptCheckpoint,
  1010. ((char *)req_lib_ckpt_sectionread) +
  1011. sizeof (struct req_lib_ckpt_sectionread),
  1012. req_lib_ckpt_sectionread->idLen);
  1013. if (ckptCheckpointSection == 0) {
  1014. error = SA_AIS_ERR_NOT_EXIST;
  1015. goto error_exit;
  1016. }
  1017. /*
  1018. * Determine the section size
  1019. */
  1020. sectionSize = ckptCheckpointSection->sectionDescriptor.sectionSize -
  1021. req_lib_ckpt_sectionread->dataOffset;
  1022. /*
  1023. * If the library has less space available then can be sent from the
  1024. * section, reduce bytes sent to library to max requested
  1025. */
  1026. if (sectionSize > req_lib_ckpt_sectionread->dataSize) {
  1027. sectionSize = req_lib_ckpt_sectionread->dataSize;
  1028. }
  1029. /*
  1030. * If dataOffset is past end of data, return INVALID PARAM
  1031. */
  1032. if (req_lib_ckpt_sectionread->dataOffset > sectionSize) {
  1033. sectionSize = 0;
  1034. error = SA_AIS_ERR_INVALID_PARAM;
  1035. goto error_exit;
  1036. }
  1037. /*
  1038. * Write read response to CKPT library
  1039. */
  1040. error_exit:
  1041. if (req_exec_ckpt_sectionread->source.in_addr.s_addr == this_ip.sin_addr.s_addr) {
  1042. res_lib_ckpt_sectionread.header.size = sizeof (struct res_lib_ckpt_sectionread) + sectionSize;
  1043. res_lib_ckpt_sectionread.header.id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONREAD;
  1044. res_lib_ckpt_sectionread.header.error = error;
  1045. libais_send_response (req_exec_ckpt_sectionread->source.conn_info,
  1046. &res_lib_ckpt_sectionread,
  1047. sizeof (struct res_lib_ckpt_sectionread));
  1048. /*
  1049. * Write checkpoint to CKPT library section if section has data
  1050. */
  1051. if (sectionSize) {
  1052. char *sd;
  1053. sd = (char *)ckptCheckpointSection->sectionData;
  1054. libais_send_response (req_exec_ckpt_sectionread->source.conn_info,
  1055. &sd[req_lib_ckpt_sectionread->dataOffset],
  1056. sectionSize);
  1057. }
  1058. }
  1059. return (0);
  1060. }
  1061. static int message_handler_req_lib_ckpt_init (struct conn_info *conn_info, void *message)
  1062. {
  1063. struct res_lib_init res_lib_init;
  1064. SaErrorT error = SA_AIS_ERR_ACCESS;
  1065. log_printf (LOG_LEVEL_DEBUG, "Got request to initialize CKPT checkpoint.\n");
  1066. if (conn_info->authenticated) {
  1067. conn_info->service = SOCKET_SERVICE_CKPT;
  1068. list_init (&conn_info->ais_ci.u.libckpt_ci.sectionIterator.list);
  1069. conn_info->ais_ci.u.libckpt_ci.sectionIterator.sectionIteratorEntries = 0;
  1070. conn_info->ais_ci.u.libckpt_ci.sectionIterator.iteratorCount = 0;
  1071. conn_info->ais_ci.u.libckpt_ci.sectionIterator.iteratorPos = 0;
  1072. list_add (&conn_info->ais_ci.u.libckpt_ci.sectionIterator.list,
  1073. &checkpointIteratorListHead);
  1074. list_init (&conn_info->ais_ci.u.libckpt_ci.checkpoint_list);
  1075. error = SA_AIS_OK;
  1076. }
  1077. res_lib_init.header.size = sizeof (struct res_lib_init);
  1078. res_lib_init.header.id = MESSAGE_RES_INIT;
  1079. res_lib_init.header.error = error;
  1080. libais_send_response (conn_info, &res_lib_init, sizeof (res_lib_init));
  1081. if (conn_info->authenticated) {
  1082. return (0);
  1083. }
  1084. return (-1);
  1085. }
  1086. static int message_handler_req_lib_ckpt_checkpointopen (struct conn_info *conn_info, void *message)
  1087. {
  1088. struct req_lib_ckpt_checkpointopen *req_lib_ckpt_checkpointopen = (struct req_lib_ckpt_checkpointopen *)message;
  1089. struct req_exec_ckpt_checkpointopen req_exec_ckpt_checkpointopen;
  1090. struct iovec iovecs[2];
  1091. log_printf (LOG_LEVEL_DEBUG, "Library request to open checkpoint.\n");
  1092. req_exec_ckpt_checkpointopen.header.size =
  1093. sizeof (struct req_exec_ckpt_checkpointopen);
  1094. req_exec_ckpt_checkpointopen.header.id = MESSAGE_REQ_EXEC_CKPT_CHECKPOINTOPEN;
  1095. req_exec_ckpt_checkpointopen.source.conn_info = conn_info;
  1096. req_exec_ckpt_checkpointopen.source.in_addr.s_addr = this_ip.sin_addr.s_addr;
  1097. memcpy (&req_exec_ckpt_checkpointopen.req_lib_ckpt_checkpointopen,
  1098. req_lib_ckpt_checkpointopen,
  1099. sizeof (struct req_lib_ckpt_checkpointopen));
  1100. iovecs[0].iov_base = (char *)&req_exec_ckpt_checkpointopen;
  1101. iovecs[0].iov_len = sizeof (req_exec_ckpt_checkpointopen);
  1102. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  1103. return (0);
  1104. }
  1105. static int message_handler_req_lib_ckpt_checkpointopenasync (struct conn_info *conn_info, void *message)
  1106. {
  1107. return (0);
  1108. }
  1109. static int message_handler_req_lib_ckpt_checkpointclose (struct conn_info *conn_info, void *message) {
  1110. struct req_lib_ckpt_checkpointclose *req_lib_ckpt_checkpointclose = (struct req_lib_ckpt_checkpointclose *)message;
  1111. struct req_exec_ckpt_checkpointclose req_exec_ckpt_checkpointclose;
  1112. struct saCkptCheckpoint *checkpoint;
  1113. struct iovec iovecs[2];
  1114. checkpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_checkpointclose->checkpointName);
  1115. if (checkpoint->expired == 1) {
  1116. return (0);
  1117. }
  1118. req_exec_ckpt_checkpointclose.header.size =
  1119. sizeof (struct req_exec_ckpt_checkpointclose);
  1120. req_exec_ckpt_checkpointclose.header.id = MESSAGE_REQ_EXEC_CKPT_CHECKPOINTCLOSE;
  1121. req_exec_ckpt_checkpointclose.source.conn_info = conn_info;
  1122. req_exec_ckpt_checkpointclose.source.in_addr.s_addr = this_ip.sin_addr.s_addr;
  1123. memcpy (&req_exec_ckpt_checkpointclose.checkpointName,
  1124. &checkpoint->name, sizeof (SaNameT));
  1125. iovecs[0].iov_base = (char *)&req_exec_ckpt_checkpointclose;
  1126. iovecs[0].iov_len = sizeof (req_exec_ckpt_checkpointclose);
  1127. if (totempg_send_ok (sizeof (struct req_exec_ckpt_checkpointclose))) {
  1128. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  1129. }
  1130. return (0);
  1131. }
  1132. static int message_handler_req_lib_ckpt_checkpointunlink (struct conn_info *conn_info, void *message)
  1133. {
  1134. struct req_lib_ckpt_checkpointunlink *req_lib_ckpt_checkpointunlink = (struct req_lib_ckpt_checkpointunlink *)message;
  1135. struct req_exec_ckpt_checkpointunlink req_exec_ckpt_checkpointunlink;
  1136. struct iovec iovecs[2];
  1137. req_exec_ckpt_checkpointunlink.header.size =
  1138. sizeof (struct req_exec_ckpt_checkpointunlink);
  1139. req_exec_ckpt_checkpointunlink.header.id = MESSAGE_REQ_EXEC_CKPT_CHECKPOINTUNLINK;
  1140. req_exec_ckpt_checkpointunlink.source.conn_info = conn_info;
  1141. req_exec_ckpt_checkpointunlink.source.in_addr.s_addr = this_ip.sin_addr.s_addr;
  1142. memcpy (&req_exec_ckpt_checkpointunlink.req_lib_ckpt_checkpointunlink,
  1143. req_lib_ckpt_checkpointunlink,
  1144. sizeof (struct req_lib_ckpt_checkpointunlink));
  1145. iovecs[0].iov_base = (char *)&req_exec_ckpt_checkpointunlink;
  1146. iovecs[0].iov_len = sizeof (req_exec_ckpt_checkpointunlink);
  1147. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  1148. return (0);
  1149. }
  1150. static int message_handler_req_lib_ckpt_checkpointretentiondurationset (struct conn_info *conn_info, void *message)
  1151. {
  1152. struct req_lib_ckpt_checkpointretentiondurationset *req_lib_ckpt_checkpointretentiondurationset = (struct req_lib_ckpt_checkpointretentiondurationset *)message;
  1153. struct req_exec_ckpt_checkpointretentiondurationset req_exec_ckpt_checkpointretentiondurationset;
  1154. struct iovec iovecs[2];
  1155. log_printf (LOG_LEVEL_DEBUG, "DURATION SET FROM API fd %d\n", conn_info->fd);
  1156. req_exec_ckpt_checkpointretentiondurationset.header.id = MESSAGE_REQ_EXEC_CKPT_CHECKPOINTRETENTIONDURATIONSET;
  1157. req_exec_ckpt_checkpointretentiondurationset.header.size = sizeof (struct req_exec_ckpt_checkpointretentiondurationset);
  1158. req_exec_ckpt_checkpointretentiondurationset.source.conn_info = conn_info;
  1159. req_exec_ckpt_checkpointretentiondurationset.source.in_addr.s_addr = this_ip.sin_addr.s_addr;
  1160. memcpy (&req_exec_ckpt_checkpointretentiondurationset.checkpointName,
  1161. &req_lib_ckpt_checkpointretentiondurationset->checkpointName,
  1162. sizeof (SaNameT));
  1163. req_exec_ckpt_checkpointretentiondurationset.retentionDuration = req_lib_ckpt_checkpointretentiondurationset->retentionDuration;
  1164. iovecs[0].iov_base = (char *)&req_exec_ckpt_checkpointretentiondurationset;
  1165. iovecs[0].iov_len = sizeof (req_exec_ckpt_checkpointretentiondurationset);
  1166. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  1167. return (0);
  1168. }
  1169. static int message_handler_req_lib_ckpt_activereplicaset (struct conn_info *conn_info, void *message)
  1170. {
  1171. return (0);
  1172. }
  1173. static int message_handler_req_lib_ckpt_checkpointstatusget (struct conn_info *conn_info, void *message)
  1174. {
  1175. struct req_lib_ckpt_checkpointstatusget *req_lib_ckpt_checkpointstatusget = (struct req_lib_ckpt_checkpointstatusget *)message;
  1176. struct res_lib_ckpt_checkpointstatusget res_lib_ckpt_checkpointstatusget;
  1177. struct saCkptCheckpoint *checkpoint;
  1178. int memoryUsed = 0;
  1179. int numberOfSections = 0;
  1180. struct list_head *checkpointSectionList;
  1181. struct saCkptCheckpointSection *checkpointSection;
  1182. log_printf (LOG_LEVEL_DEBUG, "in status get\n");
  1183. /*
  1184. * Count memory used by checkpoint sections
  1185. */
  1186. checkpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_checkpointstatusget->checkpointName);
  1187. for (checkpointSectionList = checkpoint->checkpointSectionsListHead.next;
  1188. checkpointSectionList != &checkpoint->checkpointSectionsListHead;
  1189. checkpointSectionList = checkpointSectionList->next) {
  1190. checkpointSection = list_entry (checkpointSectionList,
  1191. struct saCkptCheckpointSection, list);
  1192. memoryUsed += checkpointSection->sectionDescriptor.sectionSize;
  1193. numberOfSections += 1;
  1194. }
  1195. /*
  1196. * Build checkpoint status get response
  1197. */
  1198. res_lib_ckpt_checkpointstatusget.header.size = sizeof (struct res_lib_ckpt_checkpointstatusget);
  1199. res_lib_ckpt_checkpointstatusget.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSTATUSGET;
  1200. res_lib_ckpt_checkpointstatusget.header.error = SA_AIS_OK;
  1201. memcpy (&res_lib_ckpt_checkpointstatusget.checkpointDescriptor.checkpointCreationAttributes,
  1202. &checkpoint->checkpointCreationAttributes,
  1203. sizeof (SaCkptCheckpointCreationAttributesT));
  1204. res_lib_ckpt_checkpointstatusget.checkpointDescriptor.numberOfSections = numberOfSections;
  1205. res_lib_ckpt_checkpointstatusget.checkpointDescriptor.memoryUsed = memoryUsed;
  1206. log_printf (LOG_LEVEL_DEBUG, "before sending message\n");
  1207. libais_send_response (conn_info, &res_lib_ckpt_checkpointstatusget,
  1208. sizeof (struct res_lib_ckpt_checkpointstatusget));
  1209. return (0);
  1210. }
  1211. static int message_handler_req_lib_ckpt_sectioncreate (struct conn_info *conn_info, void *message)
  1212. {
  1213. struct req_lib_ckpt_sectioncreate *req_lib_ckpt_sectioncreate = (struct req_lib_ckpt_sectioncreate *)message;
  1214. struct req_exec_ckpt_sectioncreate req_exec_ckpt_sectioncreate;
  1215. struct iovec iovecs[2];
  1216. struct saCkptCheckpoint *checkpoint;
  1217. log_printf (LOG_LEVEL_DEBUG, "Section create from API fd %d\n", conn_info->fd);
  1218. checkpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_sectioncreate->checkpointName);
  1219. /*
  1220. * checkpoint opened is writeable mode so send message to cluster
  1221. */
  1222. req_exec_ckpt_sectioncreate.header.id = MESSAGE_REQ_EXEC_CKPT_SECTIONCREATE;
  1223. req_exec_ckpt_sectioncreate.header.size = sizeof (struct req_exec_ckpt_sectioncreate);
  1224. memcpy (&req_exec_ckpt_sectioncreate.req_lib_ckpt_sectioncreate,
  1225. req_lib_ckpt_sectioncreate,
  1226. sizeof (struct req_lib_ckpt_sectioncreate));
  1227. memcpy (&req_exec_ckpt_sectioncreate.checkpointName,
  1228. &req_lib_ckpt_sectioncreate->checkpointName,
  1229. sizeof (SaNameT));
  1230. req_exec_ckpt_sectioncreate.source.conn_info = conn_info;
  1231. req_exec_ckpt_sectioncreate.source.in_addr.s_addr = this_ip.sin_addr.s_addr;
  1232. iovecs[0].iov_base = (char *)&req_exec_ckpt_sectioncreate;
  1233. iovecs[0].iov_len = sizeof (req_exec_ckpt_sectioncreate);
  1234. /*
  1235. * Send section name and initial data in message
  1236. */
  1237. iovecs[1].iov_base = ((char *)req_lib_ckpt_sectioncreate) + sizeof (struct req_lib_ckpt_sectioncreate);
  1238. iovecs[1].iov_len = req_lib_ckpt_sectioncreate->header.size - sizeof (struct req_lib_ckpt_sectioncreate);
  1239. #ifdef DEBUG
  1240. printf ("LIBRARY SECTIONCREATE string is %s len is %d\n", (unsigned char *)iovecs[1].iov_base,
  1241. iovecs[1].iov_len);
  1242. printf ("|\n");
  1243. { int i;
  1244. char *abc = iovecs[1].iov_base;
  1245. for (i = 0; i < 14;i++) {
  1246. printf ("%c ", abc[i]);
  1247. }
  1248. }
  1249. printf ("|\n");
  1250. #endif
  1251. if (iovecs[1].iov_len > 0) {
  1252. log_printf (LOG_LEVEL_DEBUG, "IOV_BASE is %p\n", iovecs[1].iov_base);
  1253. assert (totempg_mcast (iovecs, 2, TOTEMPG_AGREED) == 0);
  1254. } else {
  1255. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  1256. }
  1257. return (0);
  1258. }
  1259. static int message_handler_req_lib_ckpt_sectiondelete (struct conn_info *conn_info, void *message)
  1260. {
  1261. struct req_lib_ckpt_sectiondelete *req_lib_ckpt_sectiondelete = (struct req_lib_ckpt_sectiondelete *)message;
  1262. struct req_exec_ckpt_sectiondelete req_exec_ckpt_sectiondelete;
  1263. struct iovec iovecs[2];
  1264. log_printf (LOG_LEVEL_DEBUG, "section delete from API fd %d\n", conn_info->fd);
  1265. req_exec_ckpt_sectiondelete.header.id = MESSAGE_REQ_EXEC_CKPT_SECTIONDELETE;
  1266. req_exec_ckpt_sectiondelete.header.size = sizeof (struct req_exec_ckpt_sectiondelete);
  1267. memcpy (&req_exec_ckpt_sectiondelete.checkpointName,
  1268. &req_lib_ckpt_sectiondelete->checkpointName,
  1269. sizeof (SaNameT));
  1270. memcpy (&req_exec_ckpt_sectiondelete.req_lib_ckpt_sectiondelete,
  1271. req_lib_ckpt_sectiondelete,
  1272. sizeof (struct req_lib_ckpt_sectiondelete));
  1273. req_exec_ckpt_sectiondelete.source.conn_info = conn_info;
  1274. req_exec_ckpt_sectiondelete.source.in_addr.s_addr = this_ip.sin_addr.s_addr;
  1275. iovecs[0].iov_base = (char *)&req_exec_ckpt_sectiondelete;
  1276. iovecs[0].iov_len = sizeof (req_exec_ckpt_sectiondelete);
  1277. /*
  1278. * Send section name
  1279. */
  1280. iovecs[1].iov_base = ((char *)req_lib_ckpt_sectiondelete) + sizeof (struct req_lib_ckpt_sectiondelete);
  1281. iovecs[1].iov_len = req_lib_ckpt_sectiondelete->header.size - sizeof (struct req_lib_ckpt_sectiondelete);
  1282. if (iovecs[1].iov_len > 0) {
  1283. assert (totempg_mcast (iovecs, 2, TOTEMPG_AGREED) == 0);
  1284. } else {
  1285. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  1286. }
  1287. return (0);
  1288. }
  1289. static int message_handler_req_lib_ckpt_sectionexpirationtimeset (struct conn_info *conn_info, void *message)
  1290. {
  1291. struct req_lib_ckpt_sectionexpirationtimeset *req_lib_ckpt_sectionexpirationtimeset = (struct req_lib_ckpt_sectionexpirationtimeset *)message;
  1292. struct req_exec_ckpt_sectionexpirationtimeset req_exec_ckpt_sectionexpirationtimeset;
  1293. struct iovec iovecs[2];
  1294. log_printf (LOG_LEVEL_DEBUG, "section expiration time set fd=%d\n", conn_info->fd);
  1295. req_exec_ckpt_sectionexpirationtimeset.header.id = MESSAGE_REQ_EXEC_CKPT_SECTIONEXPIRATIONTIMESET;
  1296. req_exec_ckpt_sectionexpirationtimeset.header.size = sizeof (struct req_exec_ckpt_sectionexpirationtimeset);
  1297. memcpy (&req_exec_ckpt_sectionexpirationtimeset.checkpointName,
  1298. &req_lib_ckpt_sectionexpirationtimeset->checkpointName,
  1299. sizeof (SaNameT));
  1300. memcpy (&req_exec_ckpt_sectionexpirationtimeset.req_lib_ckpt_sectionexpirationtimeset,
  1301. req_lib_ckpt_sectionexpirationtimeset,
  1302. sizeof (struct req_lib_ckpt_sectionexpirationtimeset));
  1303. req_exec_ckpt_sectionexpirationtimeset.source.conn_info = conn_info;
  1304. req_exec_ckpt_sectionexpirationtimeset.source.in_addr.s_addr = this_ip.sin_addr.s_addr;
  1305. iovecs[0].iov_base = (char *)&req_exec_ckpt_sectionexpirationtimeset;
  1306. iovecs[0].iov_len = sizeof (req_exec_ckpt_sectionexpirationtimeset);
  1307. /*
  1308. * Send section name
  1309. */
  1310. iovecs[1].iov_base = ((char *)req_lib_ckpt_sectionexpirationtimeset) + sizeof (struct req_lib_ckpt_sectionexpirationtimeset);
  1311. iovecs[1].iov_len = req_lib_ckpt_sectionexpirationtimeset->header.size - sizeof (struct req_lib_ckpt_sectionexpirationtimeset);
  1312. if (iovecs[1].iov_len > 0) {
  1313. log_printf (LOG_LEVEL_DEBUG, "IOV_BASE is %p\n", iovecs[1].iov_base);
  1314. assert (totempg_mcast (iovecs, 2, TOTEMPG_AGREED) == 0);
  1315. } else {
  1316. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  1317. }
  1318. return (0);
  1319. }
  1320. int write_inv = 0;
  1321. static int message_handler_req_lib_ckpt_sectionwrite (struct conn_info *conn_info, void *message)
  1322. {
  1323. struct req_lib_ckpt_sectionwrite *req_lib_ckpt_sectionwrite = (struct req_lib_ckpt_sectionwrite *)message;
  1324. struct req_exec_ckpt_sectionwrite req_exec_ckpt_sectionwrite;
  1325. struct iovec iovecs[2];
  1326. struct saCkptCheckpoint *checkpoint;
  1327. log_printf (LOG_LEVEL_DEBUG, "Section write from API fd %d\n", conn_info->fd);
  1328. checkpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_sectionwrite->checkpointName);
  1329. /*
  1330. * checkpoint opened is writeable mode so send message to cluster
  1331. */
  1332. req_exec_ckpt_sectionwrite.header.id = MESSAGE_REQ_EXEC_CKPT_SECTIONWRITE;
  1333. req_exec_ckpt_sectionwrite.header.size = sizeof (struct req_exec_ckpt_sectionwrite);
  1334. memcpy (&req_exec_ckpt_sectionwrite.req_lib_ckpt_sectionwrite,
  1335. req_lib_ckpt_sectionwrite,
  1336. sizeof (struct req_lib_ckpt_sectionwrite));
  1337. memcpy (&req_exec_ckpt_sectionwrite.checkpointName,
  1338. &req_lib_ckpt_sectionwrite->checkpointName,
  1339. sizeof (SaNameT));
  1340. req_exec_ckpt_sectionwrite.source.conn_info = conn_info;
  1341. req_exec_ckpt_sectionwrite.source.in_addr.s_addr = this_ip.sin_addr.s_addr;
  1342. iovecs[0].iov_base = (char *)&req_exec_ckpt_sectionwrite;
  1343. iovecs[0].iov_len = sizeof (req_exec_ckpt_sectionwrite);
  1344. /*
  1345. * Send section name and data to write in message
  1346. */
  1347. iovecs[1].iov_base = ((char *)req_lib_ckpt_sectionwrite) + sizeof (struct req_lib_ckpt_sectionwrite);
  1348. iovecs[1].iov_len = req_lib_ckpt_sectionwrite->header.size - sizeof (struct req_lib_ckpt_sectionwrite);
  1349. //printf ("LIB writing checkpoint section is %s\n", ((char *)req_lib_ckpt_sectionwrite) + sizeof (struct req_lib_ckpt_sectionwrite));
  1350. if (iovecs[1].iov_len > 0) {
  1351. assert (totempg_mcast (iovecs, 2, TOTEMPG_AGREED) == 0);
  1352. } else {
  1353. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  1354. }
  1355. return (0);
  1356. }
  1357. static int message_handler_req_lib_ckpt_sectionoverwrite (struct conn_info *conn_info, void *message)
  1358. {
  1359. struct req_lib_ckpt_sectionoverwrite *req_lib_ckpt_sectionoverwrite = (struct req_lib_ckpt_sectionoverwrite *)message;
  1360. struct req_exec_ckpt_sectionoverwrite req_exec_ckpt_sectionoverwrite;
  1361. struct iovec iovecs[2];
  1362. struct saCkptCheckpoint *checkpoint;
  1363. log_printf (LOG_LEVEL_DEBUG, "Section overwrite from API fd %d\n", conn_info->fd);
  1364. checkpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_sectionoverwrite->checkpointName);
  1365. /*
  1366. * checkpoint opened is writeable mode so send message to cluster
  1367. */
  1368. req_exec_ckpt_sectionoverwrite.header.id = MESSAGE_REQ_EXEC_CKPT_SECTIONOVERWRITE;
  1369. req_exec_ckpt_sectionoverwrite.header.size = sizeof (struct req_exec_ckpt_sectionoverwrite);
  1370. memcpy (&req_exec_ckpt_sectionoverwrite.req_lib_ckpt_sectionoverwrite,
  1371. req_lib_ckpt_sectionoverwrite,
  1372. sizeof (struct req_lib_ckpt_sectionoverwrite));
  1373. memcpy (&req_exec_ckpt_sectionoverwrite.checkpointName,
  1374. &req_lib_ckpt_sectionoverwrite->checkpointName,
  1375. sizeof (SaNameT));
  1376. req_exec_ckpt_sectionoverwrite.source.conn_info = conn_info;
  1377. req_exec_ckpt_sectionoverwrite.source.in_addr.s_addr = this_ip.sin_addr.s_addr;
  1378. iovecs[0].iov_base = (char *)&req_exec_ckpt_sectionoverwrite;
  1379. iovecs[0].iov_len = sizeof (req_exec_ckpt_sectionoverwrite);
  1380. /*
  1381. * Send section name and data to overwrite in message
  1382. */
  1383. iovecs[1].iov_base = ((char *)req_lib_ckpt_sectionoverwrite) + sizeof (struct req_lib_ckpt_sectionoverwrite);
  1384. iovecs[1].iov_len = req_lib_ckpt_sectionoverwrite->header.size - sizeof (struct req_lib_ckpt_sectionoverwrite);
  1385. if (iovecs[1].iov_len > 0) {
  1386. assert (totempg_mcast (iovecs, 2, TOTEMPG_AGREED) == 0);
  1387. } else {
  1388. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  1389. }
  1390. return (0);
  1391. }
  1392. static int message_handler_req_lib_ckpt_sectionread (struct conn_info *conn_info, void *message)
  1393. {
  1394. struct req_lib_ckpt_sectionread *req_lib_ckpt_sectionread = (struct req_lib_ckpt_sectionread *)message;
  1395. struct req_exec_ckpt_sectionread req_exec_ckpt_sectionread;
  1396. struct iovec iovecs[2];
  1397. struct saCkptCheckpoint *checkpoint;
  1398. log_printf (LOG_LEVEL_DEBUG, "Section overwrite from API fd %d\n", conn_info->fd);
  1399. checkpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_sectionread->checkpointName);
  1400. /*
  1401. * checkpoint opened is writeable mode so send message to cluster
  1402. */
  1403. req_exec_ckpt_sectionread.header.id = MESSAGE_REQ_EXEC_CKPT_SECTIONREAD;
  1404. req_exec_ckpt_sectionread.header.size = sizeof (struct req_exec_ckpt_sectionread);
  1405. memcpy (&req_exec_ckpt_sectionread.req_lib_ckpt_sectionread,
  1406. req_lib_ckpt_sectionread,
  1407. sizeof (struct req_lib_ckpt_sectionread));
  1408. memcpy (&req_exec_ckpt_sectionread.checkpointName,
  1409. &req_lib_ckpt_sectionread->checkpointName,
  1410. sizeof (SaNameT));
  1411. req_exec_ckpt_sectionread.source.conn_info = conn_info;
  1412. req_exec_ckpt_sectionread.source.in_addr.s_addr = this_ip.sin_addr.s_addr;
  1413. iovecs[0].iov_base = (char *)&req_exec_ckpt_sectionread;
  1414. iovecs[0].iov_len = sizeof (req_exec_ckpt_sectionread);
  1415. /*
  1416. * Send section name and data to overwrite in message
  1417. */
  1418. iovecs[1].iov_base = ((char *)req_lib_ckpt_sectionread) + sizeof (struct req_lib_ckpt_sectionread);
  1419. iovecs[1].iov_len = req_lib_ckpt_sectionread->header.size - sizeof (struct req_lib_ckpt_sectionread);
  1420. if (iovecs[1].iov_len > 0) {
  1421. assert (totempg_mcast (iovecs, 2, TOTEMPG_AGREED) == 0);
  1422. } else {
  1423. assert (totempg_mcast (iovecs, 1, TOTEMPG_AGREED) == 0);
  1424. }
  1425. return (0);
  1426. }
  1427. static int message_handler_req_lib_ckpt_checkpointsynchronize (struct conn_info *conn_info, void *message)
  1428. {
  1429. return (0);
  1430. }
  1431. static int message_handler_req_lib_ckpt_checkpointsynchronizeasync (struct conn_info *conn_info, void *message)
  1432. {
  1433. return (0);
  1434. }
  1435. static int message_handler_req_lib_ckpt_sectioniteratorinitialize (struct conn_info *conn_info, void *message)
  1436. {
  1437. struct req_lib_ckpt_sectioniteratorinitialize *req_lib_ckpt_sectioniteratorinitialize = (struct req_lib_ckpt_sectioniteratorinitialize *)message;
  1438. struct res_lib_ckpt_sectioniteratorinitialize res_lib_ckpt_sectioniteratorinitialize;
  1439. struct saCkptCheckpoint *ckptCheckpoint;
  1440. struct saCkptCheckpointSection *ckptCheckpointSection;
  1441. struct saCkptSectionIteratorEntry *ckptSectionIteratorEntries;
  1442. struct saCkptSectionIterator *ckptSectionIterator;
  1443. struct list_head *checkpointSectionList;
  1444. int addEntry = 0;
  1445. int iteratorEntries = 0;
  1446. SaErrorT error = SA_AIS_OK;
  1447. log_printf (LOG_LEVEL_DEBUG, "section iterator initialize\n");
  1448. ckptSectionIterator = &conn_info->ais_ci.u.libckpt_ci.sectionIterator;
  1449. ckptCheckpoint = ckpt_checkpoint_find_global (&req_lib_ckpt_sectioniteratorinitialize->checkpointName);
  1450. if (ckptCheckpoint == 0) {
  1451. error = SA_AIS_ERR_NOT_EXIST;
  1452. goto error_exit;
  1453. }
  1454. /*
  1455. * Iterate list of checkpoint sections
  1456. */
  1457. for (checkpointSectionList = ckptCheckpoint->checkpointSectionsListHead.next;
  1458. checkpointSectionList != &ckptCheckpoint->checkpointSectionsListHead;
  1459. checkpointSectionList = checkpointSectionList->next) {
  1460. ckptCheckpointSection = list_entry (checkpointSectionList,
  1461. struct saCkptCheckpointSection, list);
  1462. addEntry = 1;
  1463. /*
  1464. * Item should be added to iterator list
  1465. */
  1466. if (addEntry) {
  1467. iteratorEntries += 1;
  1468. ckptSectionIteratorEntries =
  1469. realloc (ckptSectionIterator->sectionIteratorEntries,
  1470. sizeof (struct saCkptSectionIteratorEntry) * iteratorEntries);
  1471. if (ckptSectionIteratorEntries == 0) {
  1472. if (ckptSectionIterator->sectionIteratorEntries) {
  1473. free (ckptSectionIterator->sectionIteratorEntries);
  1474. }
  1475. error = SA_AIS_ERR_NO_MEMORY;
  1476. goto error_exit;
  1477. }
  1478. ckptSectionIteratorEntries[iteratorEntries - 1].active = 1;
  1479. ckptSectionIteratorEntries[iteratorEntries - 1].checkpointSection = ckptCheckpointSection;
  1480. ckptSectionIterator->sectionIteratorEntries = ckptSectionIteratorEntries;
  1481. }
  1482. }
  1483. ckptSectionIterator->iteratorCount = iteratorEntries;
  1484. error_exit:
  1485. res_lib_ckpt_sectioniteratorinitialize.header.size = sizeof (struct res_lib_ckpt_sectioniteratorinitialize);
  1486. res_lib_ckpt_sectioniteratorinitialize.header.id = MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORINITIALIZE;
  1487. res_lib_ckpt_sectioniteratorinitialize.header.error = error;
  1488. libais_send_response (conn_info, &res_lib_ckpt_sectioniteratorinitialize,
  1489. sizeof (struct res_lib_ckpt_sectioniteratorinitialize));
  1490. return (0);
  1491. }
  1492. static int message_handler_req_lib_ckpt_sectioniteratornext (struct conn_info *conn_info, void *message)
  1493. {
  1494. struct req_lib_ckpt_sectioniteratornext *req_lib_ckpt_sectioniteratornext = (struct req_lib_ckpt_sectioniteratornext *)message;
  1495. struct res_lib_ckpt_sectioniteratornext res_lib_ckpt_sectioniteratornext;
  1496. struct saCkptSectionIterator *ckptSectionIterator;
  1497. SaErrorT error = SA_AIS_OK;
  1498. int sectionIdSize = 0;
  1499. int iteratorPos = 0;
  1500. req_lib_ckpt_sectioniteratornext = 0; /* this variable not used */
  1501. log_printf (LOG_LEVEL_DEBUG, "section iterator next\n");
  1502. ckptSectionIterator = &conn_info->ais_ci.u.libckpt_ci.sectionIterator;
  1503. /*
  1504. * Find active iterator entry
  1505. */
  1506. for (;;) {
  1507. /*
  1508. * No more sections in iterator
  1509. */
  1510. if (ckptSectionIterator->iteratorPos + 1 >= ckptSectionIterator->iteratorCount) {
  1511. error = SA_AIS_ERR_NOT_EXIST;
  1512. goto error_exit;
  1513. }
  1514. /*
  1515. * active iterator entry
  1516. */
  1517. if (ckptSectionIterator->sectionIteratorEntries[ckptSectionIterator->iteratorPos].active == 1) {
  1518. break;
  1519. }
  1520. ckptSectionIterator->iteratorPos += 1;
  1521. }
  1522. /*
  1523. * Prepare response to API
  1524. */
  1525. iteratorPos = ckptSectionIterator->iteratorPos;
  1526. sectionIdSize = ckptSectionIterator->sectionIteratorEntries[iteratorPos].checkpointSection->sectionDescriptor.sectionId.idLen;
  1527. memcpy (&res_lib_ckpt_sectioniteratornext.sectionDescriptor,
  1528. &ckptSectionIterator->sectionIteratorEntries[iteratorPos].checkpointSection->sectionDescriptor,
  1529. sizeof (SaCkptSectionDescriptorT));
  1530. /*
  1531. * Get to next iterator entry
  1532. */
  1533. ckptSectionIterator->iteratorPos += 1;
  1534. error_exit:
  1535. res_lib_ckpt_sectioniteratornext.header.size = sizeof (struct res_lib_ckpt_sectioniteratornext) + sectionIdSize;
  1536. res_lib_ckpt_sectioniteratornext.header.id = MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORNEXT;
  1537. res_lib_ckpt_sectioniteratornext.header.error = error;
  1538. libais_send_response (conn_info, &res_lib_ckpt_sectioniteratornext,
  1539. sizeof (struct res_lib_ckpt_sectioniteratornext));
  1540. libais_send_response (conn_info,
  1541. ckptSectionIterator->sectionIteratorEntries[iteratorPos].checkpointSection->sectionDescriptor.sectionId.id,
  1542. sectionIdSize);
  1543. return (0);
  1544. }