ckpt.c 39 KB

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