ckpt.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420
  1. /*
  2. * Copyright (c) 2002-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 <stdio.h>
  35. #include <string.h>
  36. #include <stdlib.h>
  37. #include <unistd.h>
  38. #include <errno.h>
  39. #include <pthread.h>
  40. #include <sys/types.h>
  41. #include <sys/socket.h>
  42. #include <sys/select.h>
  43. #include <sys/un.h>
  44. #include "../include/list.h"
  45. #include "../include/ais_types.h"
  46. #include "../include/ais_ckpt.h"
  47. #include "../include/ais_msg.h"
  48. #include "util.h"
  49. struct message_overlay {
  50. struct message_header header;
  51. char data[4096];
  52. };
  53. /*
  54. * Data structure for instance data
  55. */
  56. struct ckptInstance {
  57. int fd;
  58. struct queue inq;
  59. SaCkptCallbacksT callbacks;
  60. int finalize;
  61. pthread_mutex_t mutex;
  62. };
  63. struct ckptCheckpointInstance {
  64. int fd;
  65. SaNameT checkpointName;
  66. SaUint32T maxSectionIdSize;
  67. pthread_mutex_t mutex;
  68. };
  69. struct ckptSectionIteratorInstance {
  70. int fd;
  71. struct list_head sectionIdListHead;
  72. SaUint32T maxSectionIdSize;
  73. pthread_mutex_t mutex;
  74. };
  75. void ckptHandleInstanceDestructor (void *instance);
  76. void checkpointHandleInstanceDestructor (void *instance);
  77. void ckptSectionIteratorHandleInstanceDestructor (void *instance);
  78. /*
  79. * All CKPT instances in this database
  80. */
  81. static struct saHandleDatabase ckptHandleDatabase = {
  82. handleCount: 0,
  83. handles: 0,
  84. mutex: PTHREAD_MUTEX_INITIALIZER,
  85. handleInstanceDestructor: ckptHandleInstanceDestructor
  86. };
  87. /*
  88. * All Checkpoint instances in this database
  89. */
  90. static struct saHandleDatabase checkpointHandleDatabase = {
  91. handleCount: 0,
  92. handles: 0,
  93. mutex: PTHREAD_MUTEX_INITIALIZER,
  94. handleInstanceDestructor: checkpointHandleInstanceDestructor
  95. };
  96. /*
  97. * All section iterators in this database
  98. */
  99. static struct saHandleDatabase ckptSectionIteratorHandleDatabase = {
  100. handleCount: 0,
  101. handles: 0,
  102. mutex: PTHREAD_MUTEX_INITIALIZER,
  103. handleInstanceDestructor: ckptSectionIteratorHandleInstanceDestructor
  104. };
  105. /*
  106. * Versions supported
  107. */
  108. static SaVersionT ckptVersionsSupported[] = {
  109. { 'A', 1, 1 },
  110. { 'a', 1, 1 }
  111. };
  112. static struct saVersionDatabase ckptVersionDatabase = {
  113. sizeof (ckptVersionsSupported) / sizeof (SaVersionT),
  114. ckptVersionsSupported
  115. };
  116. /*
  117. * Implementation
  118. */
  119. void ckptHandleInstanceDestructor (void *instance)
  120. {
  121. struct ckptInstance *ckptInstance = (struct ckptInstance *)instance;
  122. if (ckptInstance->fd != -1) {
  123. shutdown (ckptInstance->fd, 0);
  124. close (ckptInstance->fd);
  125. }
  126. if (ckptInstance->inq.items) {
  127. free (ckptInstance->inq.items);
  128. }
  129. }
  130. void checkpointHandleInstanceDestructor (void *instance)
  131. {
  132. struct ckptCheckpointInstance *ckptCheckpointInstance = (struct ckptCheckpointInstance *)instance;
  133. if (ckptCheckpointInstance->fd != -1) {
  134. shutdown (ckptCheckpointInstance->fd, 0);
  135. close (ckptCheckpointInstance->fd);
  136. }
  137. }
  138. void ckptSectionIteratorHandleInstanceDestructor (void *instance)
  139. {
  140. struct ckptSectionIteratorInstance *ckptSectionIteratorInstance = (struct ckptSectionIteratorInstance *)instance;
  141. if (ckptSectionIteratorInstance->fd != -1) {
  142. shutdown (ckptSectionIteratorInstance->fd, 0);
  143. close (ckptSectionIteratorInstance->fd);
  144. }
  145. }
  146. SaErrorT
  147. saCkptInitialize (
  148. SaCkptHandleT *ckptHandle,
  149. const SaCkptCallbacksT *callbacks,
  150. const SaVersionT *version)
  151. {
  152. struct ckptInstance *ckptInstance;
  153. SaErrorT error = SA_OK;
  154. error = saVersionVerify (&ckptVersionDatabase, version);
  155. if (error != SA_OK) {
  156. goto error_no_destroy;
  157. }
  158. error = saHandleCreate (&ckptHandleDatabase, sizeof (struct ckptInstance),
  159. ckptHandle);
  160. if (error != SA_OK) {
  161. goto error_no_destroy;
  162. }
  163. error = saHandleInstanceGet (&ckptHandleDatabase, *ckptHandle,
  164. (void *)&ckptInstance);
  165. if (error != SA_OK) {
  166. goto error_destroy;
  167. }
  168. ckptInstance->fd = -1;
  169. /*
  170. * An inq is needed to store async messages while waiting for a
  171. * sync response
  172. */
  173. error = saQueueInit (&ckptInstance->inq, 512, sizeof (void *));
  174. if (error != SA_OK) {
  175. goto error_put_destroy;
  176. }
  177. error = saServiceConnect (&ckptInstance->fd, MESSAGE_REQ_CKPT_CHECKPOINT_INIT);
  178. if (error != SA_OK) {
  179. goto error_put_destroy;
  180. }
  181. memcpy (&ckptInstance->callbacks, callbacks, sizeof (SaCkptCallbacksT));
  182. pthread_mutex_init (&ckptInstance->mutex, NULL);
  183. saHandleInstancePut (&ckptHandleDatabase, *ckptHandle);
  184. return (SA_OK);
  185. error_put_destroy:
  186. saHandleInstancePut (&ckptHandleDatabase, *ckptHandle);
  187. error_destroy:
  188. saHandleDestroy (&ckptHandleDatabase, *ckptHandle);
  189. error_no_destroy:
  190. return (error);
  191. }
  192. SaErrorT
  193. saCkptSelectionObjectGet (
  194. const SaCkptHandleT *ckptHandle,
  195. SaSelectionObjectT *selectionObject)
  196. {
  197. struct ckptInstance *ckptInstance;
  198. SaErrorT error;
  199. error = saHandleInstanceGet (&ckptHandleDatabase, *ckptHandle, (void *)&ckptInstance);
  200. if (error != SA_OK) {
  201. return (error);
  202. }
  203. *selectionObject = ckptInstance->fd;
  204. saHandleInstancePut (&ckptHandleDatabase, *ckptHandle);
  205. return (SA_OK);
  206. }
  207. #ifdef COMPILE_OUT
  208. SaErrorT
  209. saCkptDispatch (
  210. const SaCkptHandleT *ckptHandle,
  211. SaDispatchFlagsT dispatchFlags)
  212. {
  213. fd_set read_fds;
  214. SaErrorT error;
  215. int dispatch_avail;
  216. struct timeval *timeout = 0;
  217. struct ckptInstance *ckptInstance;
  218. struct message_header **queue_msg;
  219. struct message_header *msg;
  220. int empty;
  221. int ignore_dispatch = 0;
  222. int cont = 1; /* always continue do loop except when set to 0 */
  223. error = saHandleInstanceGet (&ckptHandleDatabase, *ckptHandle, (void *)&ckptInstance);
  224. if (error != SA_OK) {
  225. return (error);
  226. }
  227. /*
  228. * Timeout instantly for SA_DISPATCH_ALL
  229. */
  230. if (dispatchFlags & SA_DISPATCH_ALL) {
  231. timeout = &zerousec;
  232. }
  233. do {
  234. /*
  235. * Read data directly from socket
  236. */
  237. FD_ZERO (&read_fds);
  238. FD_SET (ckptInstance->fd, &read_fds);
  239. error = saSelectRetry (ckptInstance->fd + 1, &read_fds, 0, 0, timeout);
  240. if (error != SA_OK) {
  241. goto error_exit;
  242. }
  243. dispatch_avail = FD_ISSET (ckptInstance->fd, &read_fds);
  244. if (dispatch_avail == 0 && dispatchFlags == SA_DISPATCH_ALL) {
  245. break; /* exit do while cont is 1 loop */
  246. } else
  247. if (dispatch_avail == 0) {
  248. continue; /* next select */
  249. }
  250. saQueueIsEmpty(&ckptInstance->inq, &empty);
  251. if (empty == 0) {
  252. /*
  253. * Queue is not empty, read data from queue
  254. */
  255. saQueueItemGet (&ckptInstance->inq, (void **)&queue_msg);
  256. msg = *queue_msg;
  257. memcpy (&ckptInstance->message, msg, msg->size);
  258. saQueueItemRemove (&ckptInstance->inq);
  259. } else {
  260. /*
  261. * Queue empty, read response from socket
  262. */
  263. error = saRecvRetry (ckptInstance->fd, &ckptInstance->message.header, sizeof (struct message_header), MSG_WAITALL | MSG_NOSIGNAL);
  264. if (error != SA_OK) {
  265. goto error_exit;
  266. }
  267. if (ckptInstance->message.header.size > sizeof (struct message_header)) {
  268. error = saRecvRetry (ckptInstance->fd, &ckptInstance->message.data,
  269. ckptInstance->message.header.size - sizeof (struct message_header),
  270. MSG_WAITALL | MSG_NOSIGNAL);
  271. if (error != SA_OK) {
  272. goto error_exit;
  273. }
  274. }
  275. }
  276. /*
  277. * Dispatch incoming response
  278. */
  279. switch (ckptInstance->message.header.id) {
  280. #ifdef COMPILE_OUT
  281. case MESSAGE_RES_CKPT_CHECKPOINT_ACTIVATEPOLL:
  282. /*
  283. * This is a do nothing message which the node executive sends
  284. * to activate the file handle in poll when the library has
  285. * queued a message into amfHandle->inq
  286. * The dispatch is ignored for the following two cases:
  287. * 1) setting of timeout to zero for the DISPATCH_ALL case
  288. * 2) expiration of the do loop for the DISPATCH_ONE case
  289. */
  290. ignore_dispatch = 1;
  291. break;
  292. case MESSAGE_RES_CKPT_CHECKPOINT_HEALTHCHECKCALLBACK:
  293. res_amf_healthcheckcallback = (struct res_amf_healthcheckcallback *)&ckptInstance->message;
  294. amfInstance->callbacks.saAmfHealthcheckCallback (
  295. res_amf_healthcheckcallback->invocation,
  296. &res_amf_healthcheckcallback->compName,
  297. res_amf_healthcheckcallback->checkType);
  298. break;
  299. case MESSAGE_RES_CKPT_CHECKPOINT_READINESSSTATESETCALLBACK:
  300. res_amf_readinessstatesetcallback = (struct res_amf_readinessstatesetcallback *)&ckptInstance->message;
  301. amfInstance->callbacks.saAmfReadinessStateSetCallback (
  302. res_amf_readinessstatesetcallback->invocation,
  303. &res_amf_readinessstatesetcallback->compName,
  304. res_amf_readinessstatesetcallback->readinessState);
  305. break;
  306. case MESSAGE_RES_CKPT_CHECKPOINT_CSISETCALLBACK:
  307. res_amf_csisetcallback = (struct res_amf_csisetcallback *)&ckptInstance->message;
  308. amfInstance->callbacks.saAmfCSISetCallback (
  309. res_amf_csisetcallback->invocation,
  310. &res_amf_csisetcallback->compName,
  311. &res_amf_csisetcallback->csiName,
  312. res_amf_csisetcallback->csiFlags,
  313. &res_amf_csisetcallback->haState,
  314. &res_amf_csisetcallback->activeCompName,
  315. res_amf_csisetcallback->transitionDescriptor);
  316. break;
  317. case MESSAGE_RES_CKPT_CHECKPOINT_CSIREMOVECALLBACK:
  318. res_amf_csiremovecallback = (struct res_amf_csiremovecallback *)&ckptInstance->message;
  319. amfInstance->callbacks.saAmfCSIRemoveCallback (
  320. res_amf_csiremovecallback->invocation,
  321. &res_amf_csiremovecallback->compName,
  322. &res_amf_csiremovecallback->csiName,
  323. &res_amf_csiremovecallback->csiFlags);
  324. break;
  325. case MESSAGE_RES_CKPT_CHECKPOINT_PROTECTIONGROUPTRACKCALLBACK:
  326. res_amf_protectiongrouptrackcallback = (struct res_amf_protectiongrouptrackcallback *)&ckptInstance->message;
  327. memcpy (res_amf_protectiongrouptrackcallback->notificationBufferAddress,
  328. res_amf_protectiongrouptrackcallback->notificationBuffer,
  329. res_amf_protectiongrouptrackcallback->numberOfItems * sizeof (SaAmfProtectionGroupNotificationT));
  330. amfInstance->callbacks.saAmfProtectionGroupTrackCallback(
  331. &res_amf_protectiongrouptrackcallback->csiName,
  332. res_amf_protectiongrouptrackcallback->notificationBufferAddress,
  333. res_amf_protectiongrouptrackcallback->numberOfItems,
  334. res_amf_protectiongrouptrackcallback->numberOfMembers,
  335. res_amf_protectiongrouptrackcallback->error);
  336. break;
  337. #endif
  338. default:
  339. // TODO
  340. break;
  341. }
  342. /*
  343. * Determine if more messages should be processed
  344. */
  345. switch (dispatchFlags) {
  346. case SA_DISPATCH_ONE:
  347. if (ignore_dispatch) {
  348. ignore_dispatch = 0;
  349. } else {
  350. cont = 0;
  351. }
  352. break;
  353. case SA_DISPATCH_ALL:
  354. if (ignore_dispatch) {
  355. ignore_dispatch = 0;
  356. }
  357. break;
  358. case SA_DISPATCH_BLOCKING:
  359. break;
  360. }
  361. } while (cont);
  362. error_exit:
  363. return (error);
  364. }
  365. #endif
  366. SaErrorT
  367. saCkptFinalize (
  368. const SaCkptHandleT *ckptHandle)
  369. {
  370. struct ckptInstance *ckptInstance;
  371. SaErrorT error;
  372. error = saHandleInstanceGet (&ckptHandleDatabase, *ckptHandle,
  373. (void *)&ckptInstance);
  374. if (error != SA_OK) {
  375. return (error);
  376. }
  377. pthread_mutex_lock (&ckptInstance->mutex);
  378. /*
  379. * Another thread has already started finalizing
  380. */
  381. if (ckptInstance->finalize) {
  382. pthread_mutex_unlock (&ckptInstance->mutex);
  383. saHandleInstancePut (&ckptHandleDatabase, *ckptHandle);
  384. return (SA_ERR_BAD_HANDLE);
  385. }
  386. ckptInstance->finalize = 1;
  387. saActivatePoll (ckptInstance->fd);
  388. pthread_mutex_unlock (&ckptInstance->mutex);
  389. saHandleInstancePut (&ckptHandleDatabase, *ckptHandle);
  390. saHandleDestroy (&ckptHandleDatabase, *ckptHandle);
  391. return (SA_OK);
  392. }
  393. SaErrorT
  394. saCkptCheckpointOpen (
  395. const SaNameT *checkpointName,
  396. const SaCkptCheckpointCreationAttributesT *checkpointCreationAttributes,
  397. SaCkptCheckpointOpenFlagsT checkpointOpenFlags,
  398. SaTimeT timeout,
  399. SaCkptCheckpointHandleT *checkpointHandle)
  400. {
  401. SaErrorT error;
  402. struct ckptCheckpointInstance *ckptCheckpointInstance;
  403. struct req_lib_ckpt_checkpointopen req_lib_ckpt_checkpointopen;
  404. struct res_lib_ckpt_checkpointopen res_lib_ckpt_checkpointopen;
  405. error = saHandleCreate (&checkpointHandleDatabase,
  406. sizeof (struct ckptCheckpointInstance), checkpointHandle);
  407. if (error != SA_OK) {
  408. goto error_no_destroy;
  409. }
  410. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  411. (void *)&ckptCheckpointInstance);
  412. if (error != SA_OK) {
  413. goto error_destroy;
  414. }
  415. ckptCheckpointInstance->fd = -1;
  416. ckptCheckpointInstance->maxSectionIdSize =
  417. checkpointCreationAttributes->maxSectionIdSize;
  418. error = saServiceConnect (&ckptCheckpointInstance->fd, MESSAGE_REQ_CKPT_CHECKPOINT_INIT);
  419. if (error != SA_OK) {
  420. goto error_put_destroy;
  421. }
  422. req_lib_ckpt_checkpointopen.header.magic = MESSAGE_MAGIC;
  423. req_lib_ckpt_checkpointopen.header.size = sizeof (struct req_lib_ckpt_checkpointopen);
  424. req_lib_ckpt_checkpointopen.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_CHECKPOINTOPEN;
  425. memcpy (&req_lib_ckpt_checkpointopen.checkpointName, checkpointName, sizeof (SaNameT));
  426. memcpy (&ckptCheckpointInstance->checkpointName, checkpointName, sizeof (SaNameT));
  427. memcpy (&req_lib_ckpt_checkpointopen.checkpointCreationAttributes,
  428. checkpointCreationAttributes,
  429. sizeof (SaCkptCheckpointCreationAttributesT));
  430. req_lib_ckpt_checkpointopen.checkpointOpenFlags = checkpointOpenFlags;
  431. error = saSendRetry (ckptCheckpointInstance->fd, &req_lib_ckpt_checkpointopen,
  432. sizeof (struct req_lib_ckpt_checkpointopen), MSG_NOSIGNAL);
  433. if (error != SA_OK) {
  434. goto error_put_destroy;
  435. }
  436. error = saRecvRetry (ckptCheckpointInstance->fd, &res_lib_ckpt_checkpointopen,
  437. sizeof (struct res_lib_ckpt_checkpointopen), MSG_WAITALL | MSG_NOSIGNAL);
  438. if (error != SA_OK) {
  439. goto error_put_destroy;
  440. }
  441. if (res_lib_ckpt_checkpointopen.error != SA_OK) {
  442. error = res_lib_ckpt_checkpointopen.error;
  443. goto error_put_destroy;
  444. }
  445. pthread_mutex_init (&ckptCheckpointInstance->mutex, NULL);
  446. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  447. return (error);
  448. error_put_destroy:
  449. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  450. error_destroy:
  451. saHandleDestroy (&checkpointHandleDatabase, *checkpointHandle);
  452. error_no_destroy:
  453. return (error);
  454. }
  455. SaErrorT
  456. saCkptCheckpointOpenAsync (
  457. const SaCkptHandleT *ckptHandle,
  458. SaInvocationT invocation,
  459. const SaNameT *checkpointName,
  460. const SaCkptCheckpointCreationAttributesT *checkpointCreationAttributes,
  461. SaCkptCheckpointOpenFlagsT checkpointOpenFlags)
  462. {
  463. struct ckptInstance *ckptInstance;
  464. SaErrorT error;
  465. struct req_lib_ckpt_checkpointopenasync req_lib_ckpt_checkpointopenasync;
  466. error = saHandleInstanceGet (&ckptHandleDatabase, *ckptHandle, (void *)&ckptInstance);
  467. if (error != SA_OK) {
  468. return (error);
  469. }
  470. req_lib_ckpt_checkpointopenasync.header.magic = MESSAGE_MAGIC;
  471. req_lib_ckpt_checkpointopenasync.header.size = sizeof (struct req_lib_ckpt_checkpointopenasync);
  472. req_lib_ckpt_checkpointopenasync.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_CHECKPOINTOPENASYNC;
  473. req_lib_ckpt_checkpointopenasync.invocation = invocation;
  474. memcpy (&req_lib_ckpt_checkpointopenasync.checkpointName, checkpointName, sizeof (SaNameT));
  475. memcpy (&req_lib_ckpt_checkpointopenasync.checkpointCreationAttributes,
  476. checkpointCreationAttributes,
  477. sizeof (SaCkptCheckpointCreationAttributesT));
  478. req_lib_ckpt_checkpointopenasync.checkpointOpenFlags = checkpointOpenFlags;
  479. pthread_mutex_lock (&ckptInstance->mutex);
  480. error = saSendRetry (ckptInstance->fd, &req_lib_ckpt_checkpointopenasync,
  481. sizeof (struct req_lib_ckpt_checkpointopenasync), MSG_NOSIGNAL);
  482. pthread_mutex_unlock (&ckptInstance->mutex);
  483. saHandleInstancePut (&ckptHandleDatabase, *ckptHandle);
  484. return (error);
  485. }
  486. SaErrorT
  487. saCkptCheckpointClose (
  488. const SaCkptCheckpointHandleT *checkpointHandle)
  489. {
  490. SaErrorT error;
  491. struct ckptCheckpointInstance *ckptCheckpointInstance;
  492. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  493. (void *)&ckptCheckpointInstance);
  494. if (error != SA_OK) {
  495. goto error_exit;
  496. }
  497. saHandleDestroy (&checkpointHandleDatabase, *checkpointHandle);
  498. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  499. error_exit:
  500. return (error);
  501. }
  502. SaErrorT
  503. saCkptCheckpointUnlink (
  504. const SaNameT *checkpointName)
  505. {
  506. SaErrorT error;
  507. struct req_lib_ckpt_checkpointunlink req_lib_ckpt_checkpointunlink;
  508. struct res_lib_ckpt_checkpointunlink res_lib_ckpt_checkpointunlink;
  509. int fd;
  510. error = saServiceConnect (&fd, MESSAGE_REQ_CKPT_CHECKPOINT_INIT);
  511. if (error != SA_OK) {
  512. goto exit_noclose;
  513. }
  514. req_lib_ckpt_checkpointunlink.header.magic = MESSAGE_MAGIC;
  515. req_lib_ckpt_checkpointunlink.header.size = sizeof (struct req_lib_ckpt_checkpointunlink);
  516. req_lib_ckpt_checkpointunlink.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_CHECKPOINTUNLINK;
  517. memcpy (&req_lib_ckpt_checkpointunlink.checkpointName, checkpointName, sizeof (SaNameT));
  518. error = saSendRetry (fd, &req_lib_ckpt_checkpointunlink, sizeof (struct req_lib_ckpt_checkpointunlink), MSG_NOSIGNAL);
  519. if (error != SA_OK) {
  520. goto exit_close;
  521. }
  522. error = saRecvQueue (fd, &res_lib_ckpt_checkpointunlink,
  523. 0, MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTUNLINK);
  524. exit_close:
  525. close (fd);
  526. return (error == SA_OK ? res_lib_ckpt_checkpointunlink.error : error);
  527. exit_noclose:
  528. return (error);
  529. }
  530. SaErrorT
  531. saCkptCheckpointRetentionDurationSet (
  532. const SaCkptCheckpointHandleT *checkpointHandle,
  533. SaTimeT retentionDuration)
  534. {
  535. SaErrorT error;
  536. struct ckptCheckpointInstance *ckptCheckpointInstance;
  537. struct req_lib_ckpt_checkpointretentiondurationset req_lib_ckpt_checkpointretentiondurationset;
  538. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  539. (void *)&ckptCheckpointInstance);
  540. if (error != SA_OK) {
  541. goto error_exit;
  542. }
  543. req_lib_ckpt_checkpointretentiondurationset.header.magic = MESSAGE_MAGIC;
  544. req_lib_ckpt_checkpointretentiondurationset.header.size = sizeof (struct req_lib_ckpt_checkpointretentiondurationset);
  545. req_lib_ckpt_checkpointretentiondurationset.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_CHECKPOINTRETENTIONDURATIONSET;
  546. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  547. error = saSendRetry (ckptCheckpointInstance->fd, &req_lib_ckpt_checkpointretentiondurationset, sizeof (struct req_lib_ckpt_checkpointretentiondurationset), MSG_NOSIGNAL);
  548. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  549. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  550. error_exit:
  551. return (error);
  552. }
  553. SaErrorT
  554. saCkptActiveCheckpointSet (
  555. const SaCkptCheckpointHandleT *checkpointHandle)
  556. {
  557. SaErrorT error;
  558. struct ckptCheckpointInstance *ckptCheckpointInstance;
  559. struct req_lib_ckpt_activecheckpointset req_lib_ckpt_activecheckpointset;
  560. struct res_lib_ckpt_activecheckpointset res_lib_ckpt_activecheckpointset;
  561. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  562. (void *)&ckptCheckpointInstance);
  563. if (error != SA_OK) {
  564. goto error_exit;
  565. }
  566. req_lib_ckpt_activecheckpointset.header.magic = MESSAGE_MAGIC;
  567. req_lib_ckpt_activecheckpointset.header.size = sizeof (struct req_lib_ckpt_activecheckpointset);
  568. req_lib_ckpt_activecheckpointset.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_ACTIVECHECKPOINTSET;
  569. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  570. error = saSendRetry (ckptCheckpointInstance->fd, &req_lib_ckpt_activecheckpointset,
  571. sizeof (struct req_lib_ckpt_activecheckpointset), MSG_NOSIGNAL);
  572. if (error != SA_OK) {
  573. goto error_exit;
  574. }
  575. error = saRecvQueue (ckptCheckpointInstance->fd,
  576. &res_lib_ckpt_activecheckpointset, 0,
  577. MESSAGE_RES_CKPT_CHECKPOINT_ACTIVECHECKPOINTSET);
  578. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  579. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  580. error_exit:
  581. return (error == SA_OK ? res_lib_ckpt_activecheckpointset.error : error);
  582. }
  583. SaErrorT
  584. saCkptCheckpointStatusGet (
  585. const SaCkptCheckpointHandleT *checkpointHandle,
  586. SaCkptCheckpointStatusT *checkpointStatus)
  587. {
  588. SaErrorT error;
  589. struct ckptCheckpointInstance *ckptCheckpointInstance;
  590. struct req_lib_ckpt_checkpointstatusget req_lib_ckpt_checkpointstatusget;
  591. struct res_lib_ckpt_checkpointstatusget res_lib_ckpt_checkpointstatusget;
  592. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  593. (void *)&ckptCheckpointInstance);
  594. if (error != SA_OK) {
  595. return (error);
  596. }
  597. req_lib_ckpt_checkpointstatusget.header.magic = MESSAGE_MAGIC;
  598. req_lib_ckpt_checkpointstatusget.header.size = sizeof (struct req_lib_ckpt_checkpointstatusget);
  599. req_lib_ckpt_checkpointstatusget.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_CHECKPOINTSTATUSGET;
  600. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  601. error = saSendRetry (ckptCheckpointInstance->fd, &req_lib_ckpt_checkpointstatusget,
  602. sizeof (struct req_lib_ckpt_checkpointstatusget), MSG_NOSIGNAL);
  603. if (error != SA_OK) {
  604. goto error_exit;
  605. }
  606. error = saRecvQueue (ckptCheckpointInstance->fd, &res_lib_ckpt_checkpointstatusget,
  607. 0, MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSTATUSGET);
  608. if (error != SA_OK) {
  609. goto error_exit;
  610. }
  611. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  612. memcpy (checkpointStatus,
  613. &res_lib_ckpt_checkpointstatusget.checkpointStatus,
  614. sizeof (SaCkptCheckpointStatusT));
  615. error_exit:
  616. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  617. return (error);
  618. }
  619. SaErrorT
  620. saCkptSectionCreate (
  621. const SaCkptCheckpointHandleT *checkpointHandle,
  622. SaCkptSectionCreationAttributesT *sectionCreationAttributes,
  623. const void *initialData,
  624. SaUint32T initialDataSize)
  625. {
  626. SaErrorT error;
  627. struct ckptCheckpointInstance *ckptCheckpointInstance;
  628. struct req_lib_ckpt_sectioncreate req_lib_ckpt_sectioncreate;
  629. struct res_lib_ckpt_sectioncreate res_lib_ckpt_sectioncreate;
  630. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  631. (void *)&ckptCheckpointInstance);
  632. if (error != SA_OK) {
  633. return (error);
  634. }
  635. req_lib_ckpt_sectioncreate.header.magic = MESSAGE_MAGIC;
  636. req_lib_ckpt_sectioncreate.header.size =
  637. sizeof (struct req_lib_ckpt_sectioncreate) +
  638. sectionCreationAttributes->sectionId->idLen +
  639. initialDataSize;
  640. req_lib_ckpt_sectioncreate.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_SECTIONCREATE;
  641. req_lib_ckpt_sectioncreate.idLen = sectionCreationAttributes->sectionId->idLen;
  642. req_lib_ckpt_sectioncreate.expirationTime = sectionCreationAttributes->expirationTime;
  643. req_lib_ckpt_sectioncreate.initialDataSize = initialDataSize;
  644. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  645. error = saSendRetry (ckptCheckpointInstance->fd, &req_lib_ckpt_sectioncreate,
  646. sizeof (struct req_lib_ckpt_sectioncreate), MSG_NOSIGNAL);
  647. if (error != SA_OK) {
  648. goto error_exit;
  649. }
  650. /*
  651. * Write section identifier to server
  652. */
  653. error = saSendRetry (ckptCheckpointInstance->fd, sectionCreationAttributes->sectionId->id,
  654. sectionCreationAttributes->sectionId->idLen, MSG_NOSIGNAL);
  655. if (error != SA_OK) {
  656. goto error_exit;
  657. }
  658. error = saSendRetry (ckptCheckpointInstance->fd, initialData,
  659. initialDataSize, MSG_NOSIGNAL);
  660. if (error != SA_OK) {
  661. goto error_exit;
  662. }
  663. error = saRecvQueue (ckptCheckpointInstance->fd,
  664. &res_lib_ckpt_sectioncreate, 0,
  665. MESSAGE_RES_CKPT_CHECKPOINT_SECTIONCREATE);
  666. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  667. error_exit:
  668. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  669. return (error == SA_OK ? res_lib_ckpt_sectioncreate.error : error);
  670. }
  671. SaErrorT
  672. saCkptSectionDelete (
  673. const SaCkptCheckpointHandleT *checkpointHandle,
  674. const SaCkptSectionIdT *sectionId)
  675. {
  676. SaErrorT error;
  677. struct ckptCheckpointInstance *ckptCheckpointInstance;
  678. struct req_lib_ckpt_sectiondelete req_lib_ckpt_sectiondelete;
  679. struct res_lib_ckpt_sectiondelete res_lib_ckpt_sectiondelete;
  680. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  681. (void *)&ckptCheckpointInstance);
  682. if (error != SA_OK) {
  683. return (error);
  684. }
  685. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  686. req_lib_ckpt_sectiondelete.header.magic = MESSAGE_MAGIC;
  687. req_lib_ckpt_sectiondelete.header.size = sizeof (struct req_lib_ckpt_sectiondelete) + sectionId->idLen;
  688. req_lib_ckpt_sectiondelete.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_SECTIONDELETE;
  689. req_lib_ckpt_sectiondelete.idLen = sectionId->idLen;
  690. error = saSendRetry (ckptCheckpointInstance->fd, &req_lib_ckpt_sectiondelete,
  691. sizeof (struct req_lib_ckpt_sectiondelete), MSG_NOSIGNAL);
  692. if (error != SA_OK) {
  693. goto error_exit;
  694. }
  695. /*
  696. * Write section identifier to server
  697. */
  698. error = saSendRetry (ckptCheckpointInstance->fd, sectionId->id,
  699. sectionId->idLen, MSG_NOSIGNAL);
  700. if (error != SA_OK) {
  701. goto error_exit;
  702. }
  703. error = saRecvQueue (ckptCheckpointInstance->fd,
  704. &res_lib_ckpt_sectiondelete, 0,
  705. MESSAGE_RES_CKPT_CHECKPOINT_SECTIONDELETE);
  706. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  707. error_exit:
  708. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  709. return (error == SA_OK ? res_lib_ckpt_sectiondelete.error : error);
  710. }
  711. SaErrorT
  712. saCkptSectionExpirationTimeSet (
  713. const SaCkptCheckpointHandleT *checkpointHandle,
  714. const SaCkptSectionIdT *sectionId,
  715. SaTimeT expirationTime)
  716. {
  717. SaErrorT error;
  718. struct ckptCheckpointInstance *ckptCheckpointInstance;
  719. struct req_lib_ckpt_sectionexpirationtimeset req_lib_ckpt_sectionexpirationtimeset;
  720. struct res_lib_ckpt_sectionexpirationtimeset res_lib_ckpt_sectionexpirationtimeset;
  721. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  722. (void *)&ckptCheckpointInstance);
  723. if (error != SA_OK) {
  724. goto error_exit;
  725. }
  726. req_lib_ckpt_sectionexpirationtimeset.header.magic = MESSAGE_MAGIC;
  727. req_lib_ckpt_sectionexpirationtimeset.header.size = sizeof (struct req_lib_ckpt_sectionexpirationtimeset) + sectionId->idLen;
  728. req_lib_ckpt_sectionexpirationtimeset.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_SECTIONEXPIRATIONTIMESET;
  729. req_lib_ckpt_sectionexpirationtimeset.idLen = sectionId->idLen;
  730. req_lib_ckpt_sectionexpirationtimeset.expirationTime = expirationTime;
  731. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  732. error = saSendRetry (ckptCheckpointInstance->fd, &req_lib_ckpt_sectionexpirationtimeset,
  733. sizeof (struct req_lib_ckpt_sectionexpirationtimeset), MSG_NOSIGNAL);
  734. if (error != SA_OK) {
  735. goto error_exit;
  736. }
  737. /*
  738. * Write section identifier to server
  739. */
  740. if (sectionId->idLen) {
  741. error = saSendRetry (ckptCheckpointInstance->fd, sectionId->id,
  742. sectionId->idLen, MSG_NOSIGNAL);
  743. if (error != SA_OK) {
  744. goto error_exit;
  745. }
  746. }
  747. error = saRecvQueue (ckptCheckpointInstance->fd,
  748. &res_lib_ckpt_sectionexpirationtimeset,
  749. 0, MESSAGE_RES_CKPT_CHECKPOINT_SECTIONEXPIRATIONTIMESET);
  750. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  751. error_exit:
  752. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  753. return (error == SA_OK ? res_lib_ckpt_sectionexpirationtimeset.error : error);
  754. }
  755. SaErrorT
  756. saCkptSectionIteratorInitialize (
  757. const SaCkptCheckpointHandleT *checkpointHandle,
  758. SaCkptSectionsChosenT sectionsChosen,
  759. SaTimeT expirationTime,
  760. SaCkptSectionIteratorT *sectionIterator)
  761. {
  762. SaErrorT error;
  763. struct ckptCheckpointInstance *ckptCheckpointInstance;
  764. struct ckptSectionIteratorInstance *ckptSectionIteratorInstance;
  765. struct req_lib_ckpt_sectioniteratorinitialize req_lib_ckpt_sectioniteratorinitialize;
  766. struct res_lib_ckpt_sectioniteratorinitialize res_lib_ckpt_sectioniteratorinitialize;
  767. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  768. (void *)&ckptCheckpointInstance);
  769. if (error != SA_OK) {
  770. goto error_no_destroy;
  771. }
  772. error = saHandleCreate (&ckptSectionIteratorHandleDatabase,
  773. sizeof (struct ckptSectionIteratorInstance), sectionIterator);
  774. if (error != SA_OK) {
  775. goto error_put_checkpoint_db;
  776. }
  777. error = saHandleInstanceGet (&ckptSectionIteratorHandleDatabase,
  778. *sectionIterator,
  779. (void *)&ckptSectionIteratorInstance);
  780. if (error != SA_OK) {
  781. goto error_destroy;
  782. }
  783. ckptSectionIteratorInstance->fd = -1;
  784. pthread_mutex_init (&ckptSectionIteratorInstance->mutex, NULL);
  785. /*
  786. * Setup section id list for iterator next
  787. */
  788. list_init (&ckptSectionIteratorInstance->sectionIdListHead);
  789. ckptSectionIteratorInstance->maxSectionIdSize =
  790. ckptCheckpointInstance->maxSectionIdSize;
  791. error = saServiceConnect (&ckptSectionIteratorInstance->fd,
  792. MESSAGE_REQ_CKPT_SECTIONITERATOR_INIT);
  793. if (error != SA_OK) {
  794. goto error_put_destroy;
  795. }
  796. req_lib_ckpt_sectioniteratorinitialize.header.magic = MESSAGE_MAGIC;
  797. req_lib_ckpt_sectioniteratorinitialize.header.size = sizeof (struct req_lib_ckpt_sectioniteratorinitialize);
  798. req_lib_ckpt_sectioniteratorinitialize.header.id = MESSAGE_REQ_CKPT_SECTIONITERATOR_SECTIONITERATORINITIALIZE;
  799. req_lib_ckpt_sectioniteratorinitialize.sectionsChosen = sectionsChosen;
  800. req_lib_ckpt_sectioniteratorinitialize.expirationTime = expirationTime;
  801. memcpy (&req_lib_ckpt_sectioniteratorinitialize.checkpointName,
  802. &ckptCheckpointInstance->checkpointName, sizeof (SaNameT));
  803. pthread_mutex_lock (&ckptSectionIteratorInstance->mutex);
  804. error = saSendRetry (ckptSectionIteratorInstance->fd,
  805. &req_lib_ckpt_sectioniteratorinitialize,
  806. sizeof (struct req_lib_ckpt_sectioniteratorinitialize),
  807. MSG_NOSIGNAL);
  808. if (error != SA_OK) {
  809. goto error_put_destroy;
  810. }
  811. error = saRecvQueue (ckptSectionIteratorInstance->fd,
  812. &res_lib_ckpt_sectioniteratorinitialize, 0,
  813. MESSAGE_RES_CKPT_SECTIONITERATOR_SECTIONITERATORINITIALIZE);
  814. pthread_mutex_unlock (&ckptSectionIteratorInstance->mutex);
  815. saHandleInstancePut (&ckptSectionIteratorHandleDatabase, *sectionIterator);
  816. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  817. return (error == SA_OK ? res_lib_ckpt_sectioniteratorinitialize.error : error);
  818. error_put_destroy:
  819. saHandleInstancePut (&ckptSectionIteratorHandleDatabase, *sectionIterator);
  820. error_destroy:
  821. saHandleDestroy (&ckptSectionIteratorHandleDatabase, *sectionIterator);
  822. error_put_checkpoint_db:
  823. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  824. error_no_destroy:
  825. return (error);
  826. }
  827. struct iteratorSectionIdListEntry {
  828. struct list_head list;
  829. char data[0];
  830. };
  831. SaErrorT
  832. saCkptSectionIteratorNext (
  833. SaCkptSectionIteratorT *sectionIterator,
  834. SaCkptSectionDescriptorT *sectionDescriptor)
  835. {
  836. SaErrorT error;
  837. struct ckptSectionIteratorInstance *ckptSectionIteratorInstance;
  838. struct req_lib_ckpt_sectioniteratornext req_lib_ckpt_sectioniteratornext;
  839. struct res_lib_ckpt_sectioniteratornext res_lib_ckpt_sectioniteratornext;
  840. struct iteratorSectionIdListEntry *iteratorSectionIdListEntry;
  841. error = saHandleInstanceGet (&ckptSectionIteratorHandleDatabase,
  842. *sectionIterator, (void *)&ckptSectionIteratorInstance);
  843. if (error != SA_OK) {
  844. goto error_exit;
  845. }
  846. /*
  847. * Allocate section id storage area
  848. */
  849. iteratorSectionIdListEntry = malloc (sizeof (struct list_head) +
  850. ckptSectionIteratorInstance->maxSectionIdSize);
  851. if (iteratorSectionIdListEntry == 0) {
  852. error = SA_ERR_NO_MEMORY;
  853. goto error_put_nounlock;
  854. }
  855. req_lib_ckpt_sectioniteratornext.header.magic = MESSAGE_MAGIC;
  856. req_lib_ckpt_sectioniteratornext.header.size = sizeof (struct req_lib_ckpt_sectioniteratornext);
  857. req_lib_ckpt_sectioniteratornext.header.id = MESSAGE_REQ_CKPT_SECTIONITERATOR_SECTIONITERATORNEXT;
  858. pthread_mutex_lock (&ckptSectionIteratorInstance->mutex);
  859. error = saSendRetry (ckptSectionIteratorInstance->fd,
  860. &req_lib_ckpt_sectioniteratornext,
  861. sizeof (struct req_lib_ckpt_sectioniteratornext), MSG_NOSIGNAL);
  862. if (error != SA_OK) {
  863. goto error_put;
  864. }
  865. error = saRecvRetry (ckptSectionIteratorInstance->fd, &res_lib_ckpt_sectioniteratornext,
  866. sizeof (struct res_lib_ckpt_sectioniteratornext), MSG_WAITALL | MSG_NOSIGNAL);
  867. if (error != SA_OK) {
  868. goto error_put;
  869. }
  870. memcpy (sectionDescriptor,
  871. &res_lib_ckpt_sectioniteratornext.sectionDescriptor,
  872. sizeof (SaCkptSectionDescriptorT));
  873. sectionDescriptor->sectionId.id = &iteratorSectionIdListEntry->data[0];
  874. if ((res_lib_ckpt_sectioniteratornext.header.size - sizeof (struct res_lib_ckpt_sectioniteratornext)) > 0) {
  875. error = saRecvRetry (ckptSectionIteratorInstance->fd,
  876. sectionDescriptor->sectionId.id,
  877. res_lib_ckpt_sectioniteratornext.header.size -
  878. sizeof (struct res_lib_ckpt_sectioniteratornext),
  879. MSG_WAITALL | MSG_NOSIGNAL);
  880. }
  881. /*
  882. * Add to persistent memory list for this sectioniterator
  883. */
  884. if (error == SA_OK && res_lib_ckpt_sectioniteratornext.error == SA_OK) {
  885. list_init (&iteratorSectionIdListEntry->list);
  886. list_add (&iteratorSectionIdListEntry->list, &ckptSectionIteratorInstance->sectionIdListHead);
  887. }
  888. error_put:
  889. pthread_mutex_unlock (&ckptSectionIteratorInstance->mutex);
  890. error_put_nounlock:
  891. saHandleInstancePut (&ckptSectionIteratorHandleDatabase, *sectionIterator);
  892. error_exit:
  893. return (error == SA_OK ? res_lib_ckpt_sectioniteratornext.error : error);
  894. }
  895. SaErrorT
  896. saCkptSectionIteratorFinalize (
  897. SaCkptSectionIteratorT *sectionIterator)
  898. {
  899. SaErrorT error;
  900. struct ckptSectionIteratorInstance *ckptSectionIteratorInstance;
  901. struct iteratorSectionIdListEntry *iteratorSectionIdListEntry;
  902. struct list_head *sectionIdIteratorList;
  903. struct list_head *sectionIdIteratorListNext;
  904. error = saHandleInstanceGet (&ckptSectionIteratorHandleDatabase,
  905. *sectionIterator, (void *)&ckptSectionIteratorInstance);
  906. if (error != SA_OK) {
  907. goto error_noput;
  908. }
  909. /*
  910. * iterate list of section ids for this iterator to free the allocated memory
  911. * be careful to cache next pointer because free removes memory from use
  912. */
  913. for (sectionIdIteratorList = ckptSectionIteratorInstance->sectionIdListHead.next,
  914. sectionIdIteratorListNext = sectionIdIteratorList->next;
  915. sectionIdIteratorList != &ckptSectionIteratorInstance->sectionIdListHead;
  916. sectionIdIteratorList = sectionIdIteratorListNext,
  917. sectionIdIteratorListNext = sectionIdIteratorList->next) {
  918. iteratorSectionIdListEntry = list_entry (sectionIdIteratorList,
  919. struct iteratorSectionIdListEntry, list);
  920. free (iteratorSectionIdListEntry);
  921. }
  922. saHandleInstancePut (&ckptSectionIteratorHandleDatabase, *sectionIterator);
  923. saHandleDestroy (&ckptSectionIteratorHandleDatabase, *sectionIterator);
  924. error_noput:
  925. return (error);
  926. }
  927. SaErrorT
  928. saCkptCheckpointWrite (
  929. const SaCkptCheckpointHandleT *checkpointHandle,
  930. const SaCkptIOVectorElementT *ioVector,
  931. SaUint32T numberOfElements,
  932. SaUint32T *erroneousVectorIndex)
  933. {
  934. SaErrorT error = SA_OK;
  935. struct ckptCheckpointInstance *ckptCheckpointInstance;
  936. struct req_lib_ckpt_sectionwrite req_lib_ckpt_sectionwrite;
  937. struct res_lib_ckpt_sectionwrite res_lib_ckpt_sectionwrite;
  938. int i;
  939. struct iovec iov[3];
  940. int iov_len = 0;
  941. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  942. (void *)&ckptCheckpointInstance);
  943. if (error != SA_OK) {
  944. return (error);
  945. }
  946. req_lib_ckpt_sectionwrite.header.magic = MESSAGE_MAGIC;
  947. req_lib_ckpt_sectionwrite.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_SECTIONWRITE;
  948. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  949. for (i = 0; i < numberOfElements; i++) {
  950. req_lib_ckpt_sectionwrite.header.size = sizeof (struct req_lib_ckpt_sectionwrite) + ioVector[i].sectionId.idLen + ioVector[i].dataSize;
  951. req_lib_ckpt_sectionwrite.dataOffset = ioVector[i].dataOffset;
  952. req_lib_ckpt_sectionwrite.dataSize = ioVector[i].dataSize;
  953. req_lib_ckpt_sectionwrite.idLen = ioVector[i].sectionId.idLen;
  954. iov_len = 0;
  955. // TODO check for zero length stuff
  956. iov[0].iov_base = &req_lib_ckpt_sectionwrite;
  957. iov[0].iov_len = sizeof (struct req_lib_ckpt_sectionwrite);
  958. iov[1].iov_base = ioVector[i].sectionId.id;
  959. iov[1].iov_len = ioVector[i].sectionId.idLen;
  960. iov[2].iov_base = ioVector[i].dataBuffer;
  961. iov[2].iov_len = ioVector[i].dataSize;
  962. error = saSendMsgRetry (ckptCheckpointInstance->fd,
  963. iov,
  964. 3);
  965. if (error != SA_OK) {
  966. goto error_exit;
  967. }
  968. /*
  969. * Receive response
  970. */
  971. error = saRecvRetry (ckptCheckpointInstance->fd, &res_lib_ckpt_sectionwrite,
  972. sizeof (struct res_lib_ckpt_sectionwrite), MSG_WAITALL | MSG_NOSIGNAL);
  973. if (error != SA_OK) {
  974. goto error_exit;
  975. }
  976. /*
  977. * If error, report back erroneous index
  978. */
  979. if (res_lib_ckpt_sectionwrite.error != SA_OK) {
  980. if (erroneousVectorIndex) {
  981. *erroneousVectorIndex = i;
  982. }
  983. goto error_exit;
  984. }
  985. }
  986. error_exit:
  987. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  988. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  989. return (error == SA_OK ? res_lib_ckpt_sectionwrite.error : error);
  990. }
  991. SaErrorT
  992. saCkptSectionOverwrite (
  993. const SaCkptCheckpointHandleT *checkpointHandle,
  994. const SaCkptSectionIdT *sectionId,
  995. SaUint8T *dataBuffer,
  996. SaSizeT dataSize)
  997. {
  998. SaErrorT error;
  999. struct ckptCheckpointInstance *ckptCheckpointInstance;
  1000. struct req_lib_ckpt_sectionoverwrite req_lib_ckpt_sectionoverwrite;
  1001. struct res_lib_ckpt_sectionoverwrite res_lib_ckpt_sectionoverwrite;
  1002. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  1003. (void *)&ckptCheckpointInstance);
  1004. if (error != SA_OK) {
  1005. return (error);
  1006. }
  1007. req_lib_ckpt_sectionoverwrite.header.magic = MESSAGE_MAGIC;
  1008. req_lib_ckpt_sectionoverwrite.header.size = sizeof (struct req_lib_ckpt_sectionoverwrite) + sectionId->idLen + dataSize;
  1009. req_lib_ckpt_sectionoverwrite.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_SECTIONOVERWRITE;
  1010. req_lib_ckpt_sectionoverwrite.idLen = sectionId->idLen;
  1011. req_lib_ckpt_sectionoverwrite.dataSize = dataSize;
  1012. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  1013. error = saSendRetry (ckptCheckpointInstance->fd, &req_lib_ckpt_sectionoverwrite,
  1014. sizeof (struct req_lib_ckpt_sectionoverwrite), MSG_NOSIGNAL);
  1015. if (error != SA_OK) {
  1016. goto error_exit;
  1017. }
  1018. if (sectionId->idLen) {
  1019. error = saSendRetry (ckptCheckpointInstance->fd, sectionId->id,
  1020. sectionId->idLen, MSG_NOSIGNAL);
  1021. if (error != SA_OK) {
  1022. goto error_exit;
  1023. }
  1024. }
  1025. error = saSendRetry (ckptCheckpointInstance->fd, dataBuffer, dataSize, MSG_NOSIGNAL);
  1026. if (error != SA_OK) {
  1027. goto error_exit;
  1028. }
  1029. error = saRecvQueue (ckptCheckpointInstance->fd,
  1030. &res_lib_ckpt_sectionoverwrite, 0, MESSAGE_RES_CKPT_CHECKPOINT_SECTIONOVERWRITE);
  1031. error_exit:
  1032. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  1033. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  1034. return (error == SA_OK ? res_lib_ckpt_sectionoverwrite.error : error);
  1035. }
  1036. SaErrorT
  1037. saCkptCheckpointRead (
  1038. const SaCkptCheckpointHandleT *checkpointHandle,
  1039. SaCkptIOVectorElementT *ioVector,
  1040. SaUint32T numberOfElements,
  1041. SaUint32T *erroneousVectorIndex)
  1042. {
  1043. SaErrorT error = SA_OK;
  1044. struct ckptCheckpointInstance *ckptCheckpointInstance;
  1045. struct req_lib_ckpt_sectionread req_lib_ckpt_sectionread;
  1046. struct res_lib_ckpt_sectionread res_lib_ckpt_sectionread;
  1047. int dataLength;
  1048. int i;
  1049. struct iovec iov[3];
  1050. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  1051. (void *)&ckptCheckpointInstance);
  1052. if (error != SA_OK) {
  1053. return (error);
  1054. }
  1055. req_lib_ckpt_sectionread.header.magic = MESSAGE_MAGIC;
  1056. req_lib_ckpt_sectionread.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_SECTIONREAD;
  1057. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  1058. for (i = 0; i < numberOfElements; i++) {
  1059. req_lib_ckpt_sectionread.header.size = sizeof (struct req_lib_ckpt_sectionread) +
  1060. ioVector[i].sectionId.idLen;
  1061. req_lib_ckpt_sectionread.idLen = ioVector[i].sectionId.idLen;
  1062. req_lib_ckpt_sectionread.dataOffset = ioVector[i].dataOffset;
  1063. req_lib_ckpt_sectionread.dataSize = ioVector[i].dataSize;
  1064. iov[0].iov_base = &req_lib_ckpt_sectionread;
  1065. iov[0].iov_len = sizeof (struct req_lib_ckpt_sectionread);
  1066. iov[1].iov_base = ioVector[i].sectionId.id;
  1067. iov[1].iov_len = ioVector[i].sectionId.idLen;
  1068. error = saSendMsgRetry (ckptCheckpointInstance->fd,
  1069. iov,
  1070. 2);
  1071. /*
  1072. * Receive response header
  1073. */
  1074. error = saRecvRetry (ckptCheckpointInstance->fd, &res_lib_ckpt_sectionread,
  1075. sizeof (struct res_lib_ckpt_sectionread), MSG_WAITALL | MSG_NOSIGNAL);
  1076. if (error != SA_OK) {
  1077. goto error_exit;
  1078. }
  1079. dataLength = res_lib_ckpt_sectionread.header.size - sizeof (struct res_lib_ckpt_sectionread);
  1080. /*
  1081. * Receive checkpoint section data
  1082. */
  1083. if (dataLength > 0) {
  1084. error = saRecvRetry (ckptCheckpointInstance->fd, ioVector[i].dataBuffer,
  1085. dataLength, MSG_WAITALL | MSG_NOSIGNAL);
  1086. if (error != SA_OK) {
  1087. goto error_exit;
  1088. }
  1089. }
  1090. if (res_lib_ckpt_sectionread.error != SA_OK) {
  1091. if (erroneousVectorIndex) {
  1092. *erroneousVectorIndex = i;
  1093. }
  1094. goto error_exit;
  1095. }
  1096. /*
  1097. * Report back bytes of data read
  1098. */
  1099. ioVector[i].readSize = res_lib_ckpt_sectionread.dataRead;
  1100. }
  1101. error_exit:
  1102. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  1103. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  1104. return (error == SA_OK ? res_lib_ckpt_sectionread.error : error);
  1105. }
  1106. SaErrorT
  1107. saCkptCheckpointSynchronize (
  1108. const SaCkptCheckpointHandleT *checkpointHandle,
  1109. SaTimeT timeout)
  1110. {
  1111. SaErrorT error;
  1112. struct ckptCheckpointInstance *ckptCheckpointInstance;
  1113. struct req_lib_ckpt_checkpointsynchronize req_lib_ckpt_checkpointsynchronize;
  1114. struct res_lib_ckpt_checkpointsynchronize res_lib_ckpt_checkpointsynchronize;
  1115. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  1116. (void *)&ckptCheckpointInstance);
  1117. if (error != SA_OK) {
  1118. return (error);
  1119. }
  1120. req_lib_ckpt_checkpointsynchronize.header.magic = MESSAGE_MAGIC;
  1121. req_lib_ckpt_checkpointsynchronize.header.size = sizeof (struct req_lib_ckpt_checkpointsynchronize);
  1122. req_lib_ckpt_checkpointsynchronize.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_CHECKPOINTSYNCHRONIZE;
  1123. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  1124. error = saSendRetry (ckptCheckpointInstance->fd, &req_lib_ckpt_checkpointsynchronize,
  1125. sizeof (struct req_lib_ckpt_checkpointsynchronize), MSG_NOSIGNAL);
  1126. if (error != SA_OK) {
  1127. goto error_exit;
  1128. }
  1129. error = saRecvQueue (ckptCheckpointInstance->fd, &res_lib_ckpt_checkpointsynchronize,
  1130. 0, MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSYNCHRONIZE);
  1131. error_exit:
  1132. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  1133. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  1134. return (error == SA_OK ? res_lib_ckpt_checkpointsynchronize.error : error);
  1135. }
  1136. SaErrorT
  1137. saCkptCheckpointSynchronizeAsync (
  1138. const SaCkptHandleT *ckptHandle,
  1139. SaInvocationT invocation,
  1140. const SaCkptCheckpointHandleT *checkpointHandle)
  1141. {
  1142. struct ckptInstance *ckptInstance;
  1143. struct ckptCheckpointInstance *ckptCheckpointInstance;
  1144. SaErrorT error;
  1145. struct req_lib_ckpt_checkpointsynchronizeasync req_lib_ckpt_checkpointsynchronizeasync;
  1146. error = saHandleInstanceGet (&checkpointHandleDatabase, *checkpointHandle,
  1147. (void *)&ckptCheckpointInstance);
  1148. if (error != SA_OK) {
  1149. return (error);
  1150. }
  1151. req_lib_ckpt_checkpointsynchronizeasync.header.magic = MESSAGE_MAGIC;
  1152. req_lib_ckpt_checkpointsynchronizeasync.header.size = sizeof (struct req_lib_ckpt_checkpointsynchronizeasync);
  1153. req_lib_ckpt_checkpointsynchronizeasync.header.id = MESSAGE_REQ_CKPT_CHECKPOINT_CHECKPOINTOPENASYNC;
  1154. req_lib_ckpt_checkpointsynchronizeasync.invocation = invocation;
  1155. pthread_mutex_lock (&ckptCheckpointInstance->mutex);
  1156. pthread_mutex_lock (&ckptInstance->mutex);
  1157. error = saSendRetry (ckptInstance->fd, &req_lib_ckpt_checkpointsynchronizeasync,
  1158. sizeof (struct req_lib_ckpt_checkpointsynchronizeasync), MSG_NOSIGNAL);
  1159. pthread_mutex_unlock (&ckptInstance->mutex);
  1160. pthread_mutex_unlock (&ckptCheckpointInstance->mutex);
  1161. saHandleInstancePut (&checkpointHandleDatabase, *checkpointHandle);
  1162. return (error);
  1163. }