3 * Copyright (c) 2002-2004 MontaVista Software, Inc.
4 * Copyright (c) 2006-2007 Red Hat, Inc.
5 * Copyright (c) 2006 Sun Microsystems, Inc.
9 * Author: Steven Dake (sdake@sdake.com)
11 * This software licensed under BSD license, the text of which follows:
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
16 * - Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 * - Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 * - Neither the name of the MontaVista Software, Inc. nor the names of its
22 * contributors may be used to endorse or promote products derived from this
23 * software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35 * THE POSSIBILITY OF SUCH DAMAGE.
43 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <sys/select.h>
53 #ifdef OPENAIS_SOLARIS
54 #define timersub(a, b, result) \
56 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
57 (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
58 if ((result)->tv_usec < 0) { \
60 (result)->tv_usec += 1000000; \
65 #define SECONDS_TO_EXPIRE 5
68 SaInvocationT open_invocation
= 16;
69 void printSaNameT (SaNameT
*name
)
73 for (i
= 0; i
< name
->length
; i
++) {
74 printf ("%c", name
->value
[i
]);
78 SaVersionT version
= { 'B', 1, 1 };
80 SaNameT defaultCheckpointName
= { 8, "defaults" };
82 SaNameT sectionsCheckpointName
= { 8, "sections" };
84 SaCkptCheckpointCreationAttributesT checkpointCreationAttributes
= {
85 .creationFlags
= SA_CKPT_WR_ALL_REPLICAS
,
86 .checkpointSize
= 100000,
87 .retentionDuration
= 5000000000LL,
89 .maxSectionSize
= 200000,
90 .maxSectionIdSize
= 20
93 SaCkptSectionIdT sectionId1
= {
95 (SaUint8T
*) "section ID #1"
98 SaCkptSectionIdT sectionId2
= {
100 (SaUint8T
*) "section ID #2"
103 SaCkptSectionCreationAttributesT sectionCreationAttributes1
= {
108 SaCkptSectionCreationAttributesT sectionCreationAttributes2
= {
113 char readBuffer1
[1025];
115 char readBuffer2
[1025];
117 char default_read_buffer
[1025];
119 SaCkptIOVectorElementT ReadVectorElements
[] = {
123 (SaUint8T
*) "section ID #1"
126 sizeof (readBuffer1
),
133 (SaUint8T
*) "section ID #2"
136 sizeof (readBuffer2
),
142 SaCkptIOVectorElementT default_read_vector
[] = {
144 SA_CKPT_DEFAULT_SECTION_ID
,
145 default_read_buffer
, /*"written data #1, this should extend past end of old section data", */
146 sizeof(default_read_buffer
), /*sizeof ("data #1, this should extend past end of old section data") + 1, */
153 #define DATASIZE 127000
154 char data1
[DATASIZE
];
155 char data2
[DATASIZE
];
156 char default_write_data
[56];
157 SaCkptIOVectorElementT WriteVectorElements
[] = {
161 (SaUint8T
*) "section ID #1"
163 data1
, /*"written data #1, this should extend past end of old section data", */
164 DATASIZE
, /*sizeof ("data #1, this should extend past end of old section data") + 1, */
171 (SaUint8T
*) "section ID #2",
173 data2
, /*"written data #2, this should extend past end of old section data" */
174 DATASIZE
, /*sizeof ("written data #2, this should extend past end of old section data") + 1, */
180 SaCkptIOVectorElementT default_write_vector
[] = {
182 SA_CKPT_DEFAULT_SECTION_ID
,
183 default_write_data
, /*"written data #1, this should extend past end of old section data", */
184 56, /*sizeof ("data #1, this should extend past end of old section data") + 1, */
190 SaCkptCheckpointHandleT checkpointHandle
;
193 SaInvocationT invocation
,
194 const SaCkptCheckpointHandleT chckpointHandle
,
197 printf ("%s: This is a call back for open for invocation = %d\n",
198 get_test_output (error
, SA_AIS_OK
), (int)invocation
);
200 checkpointHandle
= chckpointHandle
;
204 SaCkptCallbacksT callbacks
= {
210 SaCkptHandleT ckptHandle
;
211 SaCkptCheckpointHandleT checkpointHandle2
;
212 SaCkptCheckpointHandleT checkpointHandleRead
;
213 SaCkptCheckpointDescriptorT checkpointStatus
;
214 SaCkptSectionIterationHandleT sectionIterator
;
215 SaCkptSectionDescriptorT sectionDescriptor
;
216 SaUint32T erroroneousVectorIndex
= 0;
218 struct timeval tv_start
;
219 struct timeval tv_end
;
220 struct timeval tv_elapsed
;
221 SaSelectionObjectT sel_fd
;
225 error
= saCkptInitialize (&ckptHandle
, &callbacks
, &version
);
226 printf ("%s: checkpoint initialize\n",
227 get_test_output (error
, SA_AIS_OK
));
229 error
= saCkptCheckpointOpenAsync (ckptHandle
,
231 &defaultCheckpointName
,
232 &checkpointCreationAttributes
,
233 SA_CKPT_CHECKPOINT_CREATE
|SA_CKPT_CHECKPOINT_READ
|SA_CKPT_CHECKPOINT_WRITE
);
234 printf ("%s: initial asynchronous open of checkpoint\n",
235 get_test_output (error
, SA_AIS_OK
));
237 error
= saCkptSelectionObjectGet (ckptHandle
, &sel_fd
);
239 printf ("%s: Retrieve selection object %llu\n",
240 get_test_output (error
, SA_AIS_OK
), (unsigned long long)sel_fd
);
242 FD_SET (sel_fd
, &read_set
);
243 select (sel_fd
+ 1, &read_set
, 0, 0, 0);
245 error
= saCkptDispatch (ckptHandle
, SA_DISPATCH_ALL
);
247 printf ("%s: Dispatch response for open async of checkpoint\n",
248 get_test_output (error
, SA_AIS_OK
));
250 error
= saCkptCheckpointClose (checkpointHandle
);
252 printf ("%s: Closing checkpoint\n", get_test_output (error
, SA_AIS_OK
));
254 error
= saCkptCheckpointOpen (ckptHandle
,
255 &defaultCheckpointName
,
256 &checkpointCreationAttributes
,
257 SA_CKPT_CHECKPOINT_CREATE
|SA_CKPT_CHECKPOINT_READ
|SA_CKPT_CHECKPOINT_WRITE
,
260 printf ("%s: initial open of checkpoint\n",
261 get_test_output (error
, SA_AIS_OK
));
263 error
= saCkptCheckpointRead (checkpointHandle
,
266 &erroroneousVectorIndex
);
267 printf ("%s: Reading default checkpoint section before update\n",
268 get_test_output (error
, SA_AIS_OK
));
269 printf (" default_read_buffer:'%s'\n", default_read_buffer
);
271 memset (default_read_buffer
, 0, sizeof (default_read_buffer
));
272 memcpy(default_write_data
,
273 "This is an update to the default section date, update#1", 56);
274 error
= saCkptCheckpointWrite (checkpointHandle
,
275 default_write_vector
,
277 &erroroneousVectorIndex
);
279 printf ("%s: Writing default checkpoint section with data '%s' \n",
280 get_test_output (error
, SA_AIS_OK
), default_write_data
);
282 error
= saCkptCheckpointRead (checkpointHandle
,
285 &erroroneousVectorIndex
);
287 printf ("%s: Reading default checkpoint section \n",
288 get_test_output (error
, SA_AIS_OK
));
290 printf (" default_read_buffer:'%s'\n", default_read_buffer
);
292 error
= saCkptCheckpointClose (checkpointHandle
);
294 checkpointCreationAttributes
.maxSections
= 5;
295 error
= saCkptCheckpointOpen (ckptHandle
,
296 §ionsCheckpointName
,
297 &checkpointCreationAttributes
,
298 SA_CKPT_CHECKPOINT_CREATE
|SA_CKPT_CHECKPOINT_READ
|SA_CKPT_CHECKPOINT_WRITE
,
302 printf ("%s: checkpoint create writeable\n",
303 get_test_output (error
, SA_AIS_OK
));
305 error
= saCkptSectionCreate (checkpointHandle
,
306 §ionCreationAttributes1
,
308 strlen ("Initial Data #0") + 1);
310 printf ("%s: checkpoint section create\n",
311 get_test_output (error
, SA_AIS_OK
));
313 gettimeofday (&tv_start
, 0);
314 sectionCreationAttributes1
.expirationTime
=
315 (((unsigned long long)(tv_start
.tv_sec
) + SECONDS_TO_EXPIRE
) *
317 ((unsigned long long)(tv_start
.tv_usec
) * 1000ULL);
319 error
= saCkptSectionExpirationTimeSet (checkpointHandle
,
321 sectionCreationAttributes1
.expirationTime
);
322 printf ("%s: checkpoint section expiration set\n",
323 get_test_output (error
, SA_AIS_OK
));
325 printf ("Please wait, testing expiry of checkpoint sections.\n");
327 error
= saCkptCheckpointRead (checkpointHandle
,
330 &erroroneousVectorIndex
);
332 } while (error
!= SA_AIS_ERR_NOT_EXIST
);
333 gettimeofday (&tv_end
, NULL
);
336 * avoid div by zero errors
338 if (tv_elapsed
.tv_usec
== 0) {
339 tv_elapsed
.tv_usec
= 1;
341 timersub (&tv_end
, &tv_start
, &tv_elapsed
);
342 printf ("Elapsed Time to expiry is %ld & %ld usec (should be about %d seconds)\n",
344 (long) tv_elapsed
.tv_usec
,
347 error
= saCkptCheckpointRetentionDurationSet (checkpointHandle
,
349 printf ("%s: RetentionDurationSet\n",
350 get_test_output (error
, SA_AIS_OK
));
352 error
= saCkptSectionCreate (checkpointHandle
,
353 §ionCreationAttributes2
,
355 strlen ("Initial Data #0") + 1);
357 printf ("%s: Section creation\n",
358 get_test_output (error
, SA_AIS_OK
));
360 error
= saCkptCheckpointUnlink (ckptHandle
, §ionsCheckpointName
);
361 printf ("%s: Unlinking checkpoint\n",
362 get_test_output (error
, SA_AIS_OK
));
364 error
= saCkptCheckpointOpen (ckptHandle
,
365 §ionsCheckpointName
,
366 &checkpointCreationAttributes
,
367 SA_CKPT_CHECKPOINT_CREATE
|SA_CKPT_CHECKPOINT_READ
|SA_CKPT_CHECKPOINT_WRITE
,
370 printf ("%s: Opening unlinked checkpoint\n",
371 get_test_output (error
, SA_AIS_OK
));
373 error
= saCkptCheckpointClose (checkpointHandle
);
374 printf ("%s: Closing checkpoint\n",
375 get_test_output (error
, SA_AIS_OK
));
377 error
= saCkptCheckpointOpen (ckptHandle
,
378 §ionsCheckpointName
,
379 &checkpointCreationAttributes
,
380 SA_CKPT_CHECKPOINT_CREATE
|SA_CKPT_CHECKPOINT_READ
,
382 &checkpointHandleRead
);
384 printf ("%s: Open checkpoint read only\n",
385 get_test_output (error
, SA_AIS_OK
));
388 error
= saCkptCheckpointOpen (ckptHandle
,
389 §ionsCheckpointName
,
390 &checkpointCreationAttributes
,
391 SA_CKPT_CHECKPOINT_CREATE
|SA_CKPT_CHECKPOINT_READ
|SA_CKPT_CHECKPOINT_WRITE
,
394 printf ("%s: open after unlink/close\n",
395 get_test_output (error
, SA_AIS_OK
));
397 error
= saCkptCheckpointRetentionDurationSet (checkpointHandle
,
399 printf ("%s: set checkpoint retention duration\n",
400 get_test_output (error
, SA_AIS_OK
));
402 error
= saCkptCheckpointStatusGet (checkpointHandle
,
404 printf ("%s: Get checkpoint status\n",
405 get_test_output (error
, SA_AIS_OK
));
406 if (error
== SA_AIS_OK
) {
407 printf ("Memory used %d in %d sections.\n", (int)checkpointStatus
.memoryUsed
,
408 (int)checkpointStatus
.numberOfSections
);
411 error
= saCkptSectionCreate (checkpointHandleRead
,
412 §ionCreationAttributes1
,
414 strlen ("Initial Data #0") + 1);
415 printf ("%s: Create checkpoint section on read only checkpoint\n",
416 get_test_output (error
, SA_AIS_ERR_ACCESS
));
418 sectionCreationAttributes1
.expirationTime
= SA_TIME_END
;
420 error
= saCkptSectionCreate (checkpointHandle
,
421 §ionCreationAttributes1
,
423 strlen ("Initial Data #0") + 1);
424 printf ("%s: Create checkpoint section on writeable checkpoint\n",
425 get_test_output (error
, SA_AIS_OK
));
427 error
= saCkptSectionCreate (checkpointHandle
,
428 §ionCreationAttributes1
,
430 strlen ("Initial Data #0") + 1);
431 printf ("%s: Create checkpoint section when one already exists\n",
432 get_test_output (error
, SA_AIS_ERR_EXIST
));
434 error
= saCkptSectionDelete (checkpointHandle
,
436 printf ("%s: deleting section handle\n",
437 get_test_output (error
, SA_AIS_OK
));
439 error
= saCkptSectionCreate (checkpointHandle
,
440 §ionCreationAttributes1
,
442 strlen ("Initial Data #0") + 1);
443 printf ("%s: replacing deleted checkpoint section\n",
444 get_test_output (error
, SA_AIS_OK
));
446 error
= saCkptSectionCreate (checkpointHandle
,
447 §ionCreationAttributes2
,
449 strlen ("Initial Data #2") + 1);
450 printf ("%s: creating section 2 for first time\n",
451 get_test_output (error
, SA_AIS_OK
));
452 error
= saCkptSectionCreate (checkpointHandle
,
453 §ionCreationAttributes2
,
455 strlen ("Initial Data #2") + 1);
456 printf ("%s: creating section 2 for second time\n",
457 get_test_output (error
, SA_AIS_ERR_EXIST
));
459 error
= saCkptSectionExpirationTimeSet (checkpointHandle
,
462 printf ("%s: Setting expiration time for section 2\n",
463 get_test_output (error
, SA_AIS_OK
));
465 error
= saCkptSectionOverwrite (checkpointHandle
,
468 strlen ("Overwrite Data #1") + 1);
469 printf ("%s: overwriting checkpoint section 1\n",
470 get_test_output (error
, SA_AIS_OK
));
473 * Test checkpoint read
475 memset (readBuffer1
, 0, sizeof (readBuffer1
));
476 memset (readBuffer2
, 0, sizeof (readBuffer2
));
478 error
= saCkptCheckpointRead (checkpointHandle
,
481 &erroroneousVectorIndex
);
482 printf ("%s: checkpoint read operation\n",
483 get_test_output (error
, SA_AIS_OK
));
484 printf ("Buffers after checkpoint read\n");
485 printf (" buffer #1: '%s'\n", readBuffer1
);
486 printf (" buffer #2: '%s'\n", readBuffer2
);
488 for (ckptinv
= 0; ckptinv
< 10; ckptinv
++) {
490 * Test checkpoint write
492 error
= saCkptCheckpointWrite (checkpointHandle
,
495 &erroroneousVectorIndex
);
496 if (error
!= SA_AIS_OK
) {
497 printf ("Writing checkpoint loop %d\n", ckptinv
);
498 printf ("saCkptCheckpointWrite result %d (should be 1)\n", error
);
501 printf ("%s: Testing checkpoint writes\n",
502 get_test_output (error
, SA_AIS_OK
));
504 error
= saCkptCheckpointRead (checkpointHandle
,
507 &erroroneousVectorIndex
);
508 // printf ("saCkptCheckpointRead result %d (should be 1)\n", error);
509 // printf ("Buffers after checkpoint write are:\n");
510 // printf (" buffer #1: '%s'\n", readBuffer1);
511 // printf (" buffer #2: '%s'\n", readBuffer2);
513 error
= saCkptCheckpointStatusGet (checkpointHandle
,
515 printf ("%s: get checkpoint status\n",
516 get_test_output (error
, SA_AIS_OK
));
517 if (error
== SA_AIS_OK
) {
518 printf ("Memory used %d in %d sections.\n",
519 (int)checkpointStatus
.memoryUsed
,
520 (int)checkpointStatus
.numberOfSections
);
522 printf ("iterating all sections 5 times\n");
524 * iterate all sections 5 times
526 for (i
= 0; i
< 5; i
++) {
527 error
= saCkptSectionIterationInitialize (checkpointHandle
,
528 SA_CKPT_SECTIONS_ANY
,
531 printf ("%s: initialize section iterator\n",
532 get_test_output (error
, SA_AIS_OK
));
536 * Iterate all sections
539 printf ("Starting iteration\n");
540 error
= saCkptSectionIterationNext (sectionIterator
,
542 if (error
== SA_AIS_ERR_NO_SECTIONS
) {
543 printf ("No more sections to iterate\n");
545 printf ("%s: Get next section in iteration\n",
546 get_test_output (error
, SA_AIS_OK
));
548 if (error
== SA_AIS_OK
) {
549 printf ("Section '%s' expires %llx size %llu state %x update %llx\n",
550 sectionDescriptor
.sectionId
.id
,
551 (unsigned long long)sectionDescriptor
.expirationTime
,
552 (unsigned long long)sectionDescriptor
.sectionSize
,
553 sectionDescriptor
.sectionState
,
554 (unsigned long long)sectionDescriptor
.lastUpdate
);
556 } while (error
== SA_AIS_OK
);
558 error
= saCkptSectionIterationFinalize (sectionIterator
);
559 printf ("%s: Finalize iteration\n",
560 get_test_output (error
, SA_AIS_OK
));
564 error
= saCkptSelectionObjectGet (ckptHandle
, &sel_fd
);
566 error
= saCkptFinalize (ckptHandle
);
567 printf ("%s: Finalize checkpoint\n",
568 get_test_output (error
, SA_AIS_OK
));