mirror of
https://git.proxmox.com/git/mirror_corosync
synced 2025-08-14 19:21:58 +00:00
Support for store user data in SAM
Ability to in-memory storing of user data which survives between instances of process. Also ability needed ability for bi-directional communication between child and parent is added. git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2769 fd59a12c-fef9-0310-b244-a6a79926bd2f
This commit is contained in:
parent
2a12dafffb
commit
da6fce352b
@ -160,6 +160,49 @@ cs_error_t sam_hc_send (void);
|
||||
*/
|
||||
cs_error_t sam_hc_callback_register (sam_hc_callback_t cb);
|
||||
|
||||
/*
|
||||
* Return size of stored data.
|
||||
* @param size Pointer to variable, where stored data size is returned. If
|
||||
* nothing or NULL is stored, then 0 is returned.
|
||||
* @return
|
||||
* - CS_OK in case no problem appeared
|
||||
* - CS_ERR_BAD_HANDLE in case you call this function before sam_init or after
|
||||
* sam_finalize
|
||||
* - CS_ERR_INVALID_PARAM if size parameter is NULL
|
||||
*/
|
||||
cs_error_t sam_data_getsize (size_t *size);
|
||||
|
||||
/*
|
||||
* Return stored data.
|
||||
* @param data Pointer to place, where to store data
|
||||
* @param size Allocated size of data
|
||||
* @return
|
||||
* - CS_OK if no problem appeared
|
||||
* - CS_ERR_BAD_HANDLE if you call this function before sam_init or after sam_finalize
|
||||
* - CS_ERR_INVALID_PARAM if data is NULL or size is less then currently saved user data length
|
||||
*/
|
||||
cs_error_t sam_data_restore (
|
||||
void *data,
|
||||
size_t size);
|
||||
|
||||
/*
|
||||
* Store user data. Such stored data survives restart of child.
|
||||
* @param data Data to store. You can use NULL to delete data
|
||||
* @param size Size of data to store.
|
||||
* @return
|
||||
* - CS_OK in case no problem appeared
|
||||
* - CS_ERR_BAD_HANDLE if you call this function before sam_init or
|
||||
* after sam_finalize
|
||||
* - CS_ERR_NO_MEMORY if data is too large and malloc/realloc was not
|
||||
* sucesfull
|
||||
* - CS_ERR_LIBRARY if some internal error appeared (communication with parent
|
||||
* process)
|
||||
*/
|
||||
cs_error_t sam_data_store (
|
||||
const void *data,
|
||||
size_t size);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1 +1 @@
|
||||
4.1.0
|
||||
4.2.0
|
||||
|
352
lib/sam.c
352
lib/sam.c
@ -38,6 +38,7 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -70,7 +71,13 @@ enum sam_internal_status_t {
|
||||
enum sam_command_t {
|
||||
SAM_COMMAND_START,
|
||||
SAM_COMMAND_STOP,
|
||||
SAM_COMMAND_HB
|
||||
SAM_COMMAND_HB,
|
||||
SAM_COMMAND_DATA_STORE,
|
||||
};
|
||||
|
||||
enum sam_reply_t {
|
||||
SAM_REPLY_OK,
|
||||
SAM_REPLY_ERROR,
|
||||
};
|
||||
|
||||
enum sam_parent_action_t {
|
||||
@ -85,14 +92,20 @@ static struct {
|
||||
sam_recovery_policy_t recovery_policy;
|
||||
enum sam_internal_status_t internal_status;
|
||||
unsigned int instance_id;
|
||||
int parent_fd;
|
||||
int child_fd_out;
|
||||
int child_fd_in;
|
||||
int term_send;
|
||||
int warn_signal;
|
||||
int am_i_child;
|
||||
|
||||
sam_hc_callback_t hc_callback;
|
||||
pthread_t cb_thread;
|
||||
int cb_rpipe_fd, cb_wpipe_fd;
|
||||
int cb_registered;
|
||||
|
||||
void *user_data;
|
||||
size_t user_data_size;
|
||||
size_t user_data_allocated;
|
||||
} sam_internal_data;
|
||||
|
||||
cs_error_t sam_initialize (
|
||||
@ -115,6 +128,12 @@ cs_error_t sam_initialize (
|
||||
|
||||
sam_internal_data.warn_signal = SIGTERM;
|
||||
|
||||
sam_internal_data.am_i_child = 0;
|
||||
|
||||
sam_internal_data.user_data = NULL;
|
||||
sam_internal_data.user_data_size = 0;
|
||||
sam_internal_data.user_data_allocated = 0;
|
||||
|
||||
return (CS_OK);
|
||||
}
|
||||
|
||||
@ -132,7 +151,8 @@ static size_t sam_safe_write (
|
||||
bytes_write = 0;
|
||||
|
||||
do {
|
||||
tmp_bytes_write = write (d, (const char *)buf + bytes_write, nbyte - bytes_write);
|
||||
tmp_bytes_write = write (d, (const char *)buf + bytes_write,
|
||||
(nbyte - bytes_write > SSIZE_MAX) ? SSIZE_MAX : nbyte - bytes_write);
|
||||
|
||||
if (tmp_bytes_write == -1) {
|
||||
if (!(errno == EAGAIN || errno == EINTR))
|
||||
@ -142,7 +162,176 @@ static size_t sam_safe_write (
|
||||
}
|
||||
} while (bytes_write != nbyte);
|
||||
|
||||
return bytes_write;
|
||||
return (bytes_write);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper on top of read(2) function. It handles EAGAIN and EINTR states and reads whole buffer if possible.
|
||||
*/
|
||||
static size_t sam_safe_read (
|
||||
int d,
|
||||
void *buf,
|
||||
size_t nbyte)
|
||||
{
|
||||
ssize_t bytes_read;
|
||||
ssize_t tmp_bytes_read;
|
||||
|
||||
bytes_read = 0;
|
||||
|
||||
do {
|
||||
tmp_bytes_read = read (d, (char *)buf + bytes_read,
|
||||
(nbyte - bytes_read > SSIZE_MAX) ? SSIZE_MAX : nbyte - bytes_read);
|
||||
|
||||
if (tmp_bytes_read == -1) {
|
||||
if (!(errno == EAGAIN || errno == EINTR))
|
||||
return -1;
|
||||
} else {
|
||||
bytes_read += tmp_bytes_read;
|
||||
}
|
||||
|
||||
} while (bytes_read != nbyte && tmp_bytes_read != 0);
|
||||
|
||||
return (bytes_read);
|
||||
}
|
||||
|
||||
cs_error_t sam_data_getsize (size_t *size)
|
||||
{
|
||||
if (size == NULL) {
|
||||
return (CS_ERR_INVALID_PARAM);
|
||||
}
|
||||
|
||||
if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_INITIALIZED &&
|
||||
sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED &&
|
||||
sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED) {
|
||||
|
||||
return (CS_ERR_BAD_HANDLE);
|
||||
}
|
||||
|
||||
*size = sam_internal_data.user_data_size;
|
||||
|
||||
return (CS_OK);
|
||||
}
|
||||
|
||||
cs_error_t sam_data_restore (
|
||||
void *data,
|
||||
size_t size)
|
||||
{
|
||||
if (data == NULL) {
|
||||
return (CS_ERR_INVALID_PARAM);
|
||||
}
|
||||
|
||||
if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_INITIALIZED &&
|
||||
sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED &&
|
||||
sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED) {
|
||||
|
||||
return (CS_ERR_BAD_HANDLE);
|
||||
}
|
||||
|
||||
if (sam_internal_data.user_data_size == 0) {
|
||||
return (CS_OK);
|
||||
}
|
||||
|
||||
if (size < sam_internal_data.user_data_size) {
|
||||
return (CS_ERR_INVALID_PARAM);
|
||||
}
|
||||
|
||||
memcpy (data, sam_internal_data.user_data, sam_internal_data.user_data_size);
|
||||
|
||||
return (CS_OK);
|
||||
}
|
||||
|
||||
cs_error_t sam_data_store (
|
||||
const void *data,
|
||||
size_t size)
|
||||
{
|
||||
cs_error_t err;
|
||||
char command;
|
||||
char *new_data;
|
||||
char reply;
|
||||
|
||||
if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_INITIALIZED &&
|
||||
sam_internal_data.internal_status != SAM_INTERNAL_STATUS_REGISTERED &&
|
||||
sam_internal_data.internal_status != SAM_INTERNAL_STATUS_STARTED) {
|
||||
|
||||
return (CS_ERR_BAD_HANDLE);
|
||||
}
|
||||
|
||||
if (sam_internal_data.user_data_allocated < size) {
|
||||
if ((new_data = realloc (sam_internal_data.user_data, size)) == NULL) {
|
||||
return (CS_ERR_NO_MEMORY);
|
||||
}
|
||||
|
||||
sam_internal_data.user_data_allocated = size;
|
||||
} else {
|
||||
new_data = sam_internal_data.user_data;
|
||||
}
|
||||
|
||||
if (data == NULL) {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
if (sam_internal_data.am_i_child) {
|
||||
/*
|
||||
* We are child so we must send data to parent
|
||||
*/
|
||||
command = SAM_COMMAND_DATA_STORE;
|
||||
if (sam_safe_write (sam_internal_data.child_fd_out, &command, sizeof (command)) != sizeof (command)) {
|
||||
return (CS_ERR_LIBRARY);
|
||||
}
|
||||
|
||||
if (sam_safe_write (sam_internal_data.child_fd_out, &size, sizeof (size)) != sizeof (size)) {
|
||||
return (CS_ERR_LIBRARY);
|
||||
}
|
||||
|
||||
if (data != NULL && sam_safe_write (sam_internal_data.child_fd_out, data, size) != size) {
|
||||
return (CS_ERR_LIBRARY);
|
||||
}
|
||||
|
||||
/*
|
||||
* And wait for reply
|
||||
*/
|
||||
if (sam_safe_read (sam_internal_data.child_fd_in, &reply, sizeof (reply)) != sizeof (reply)) {
|
||||
return (CS_ERR_LIBRARY);
|
||||
}
|
||||
|
||||
switch (reply) {
|
||||
case SAM_REPLY_ERROR:
|
||||
/*
|
||||
* Read error and return that
|
||||
*/
|
||||
if (sam_safe_read (sam_internal_data.child_fd_in, &err, sizeof (err)) != sizeof (err)) {
|
||||
return (CS_ERR_LIBRARY);
|
||||
}
|
||||
|
||||
return (err);
|
||||
break;
|
||||
case SAM_REPLY_OK:
|
||||
/*
|
||||
* Everything correct
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
return (CS_ERR_LIBRARY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We are parent or we received OK reply from parent -> do required action
|
||||
*/
|
||||
if (data == NULL) {
|
||||
free (sam_internal_data.user_data);
|
||||
sam_internal_data.user_data = NULL;
|
||||
sam_internal_data.user_data_allocated = 0;
|
||||
sam_internal_data.user_data_size = 0;
|
||||
} else {
|
||||
sam_internal_data.user_data = new_data;
|
||||
sam_internal_data.user_data_size = size;
|
||||
|
||||
memcpy (sam_internal_data.user_data, data, size);
|
||||
}
|
||||
|
||||
return (CS_OK);
|
||||
}
|
||||
|
||||
cs_error_t sam_start (void)
|
||||
@ -155,11 +344,11 @@ cs_error_t sam_start (void)
|
||||
|
||||
command = SAM_COMMAND_START;
|
||||
|
||||
if (sam_safe_write (sam_internal_data.parent_fd, &command, 1) == -1)
|
||||
if (sam_safe_write (sam_internal_data.child_fd_out, &command, sizeof (command)) != sizeof (command))
|
||||
return (CS_ERR_LIBRARY);
|
||||
|
||||
if (sam_internal_data.hc_callback)
|
||||
if (sam_safe_write (sam_internal_data.cb_wpipe_fd, &command, 1) == -1)
|
||||
if (sam_safe_write (sam_internal_data.cb_wpipe_fd, &command, sizeof (command)) != sizeof (command))
|
||||
return (CS_ERR_LIBRARY);
|
||||
|
||||
sam_internal_data.internal_status = SAM_INTERNAL_STATUS_STARTED;
|
||||
@ -177,11 +366,11 @@ cs_error_t sam_stop (void)
|
||||
|
||||
command = SAM_COMMAND_STOP;
|
||||
|
||||
if (sam_safe_write (sam_internal_data.parent_fd, &command, 1) == -1)
|
||||
if (sam_safe_write (sam_internal_data.child_fd_out, &command, sizeof (command)) != sizeof (command))
|
||||
return (CS_ERR_LIBRARY);
|
||||
|
||||
if (sam_internal_data.hc_callback)
|
||||
if (sam_safe_write (sam_internal_data.cb_wpipe_fd, &command, 1) == -1)
|
||||
if (sam_safe_write (sam_internal_data.cb_wpipe_fd, &command, sizeof (command)) != sizeof (command))
|
||||
return (CS_ERR_LIBRARY);
|
||||
|
||||
sam_internal_data.internal_status = SAM_INTERNAL_STATUS_REGISTERED;
|
||||
@ -199,7 +388,7 @@ cs_error_t sam_hc_send (void)
|
||||
|
||||
command = SAM_COMMAND_HB;
|
||||
|
||||
if (sam_safe_write (sam_internal_data.parent_fd, &command, 1) == -1)
|
||||
if (sam_safe_write (sam_internal_data.child_fd_out, &command, sizeof (command)) != sizeof (command))
|
||||
return (CS_ERR_LIBRARY);
|
||||
|
||||
return (CS_OK);
|
||||
@ -223,6 +412,8 @@ cs_error_t sam_finalize (void)
|
||||
|
||||
sam_internal_data.internal_status = SAM_INTERNAL_STATUS_FINALIZED;
|
||||
|
||||
free (sam_internal_data.user_data);
|
||||
|
||||
exit_error:
|
||||
return (CS_OK);
|
||||
}
|
||||
@ -241,7 +432,69 @@ cs_error_t sam_warn_signal_set (int warn_signal)
|
||||
return (CS_OK);
|
||||
}
|
||||
|
||||
static enum sam_parent_action_t sam_parent_handler (int pipe_fd, pid_t child_pid)
|
||||
static cs_error_t sam_parent_data_store (
|
||||
int parent_fd_in,
|
||||
int parent_fd_out)
|
||||
{
|
||||
char reply;
|
||||
char *user_data;
|
||||
ssize_t size;
|
||||
cs_error_t err;
|
||||
|
||||
err = CS_OK;
|
||||
user_data = NULL;
|
||||
|
||||
if (sam_safe_read (parent_fd_in, &size, sizeof (size)) != sizeof (size)) {
|
||||
err = CS_ERR_LIBRARY;
|
||||
goto error_reply;
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
user_data = malloc (size);
|
||||
if (user_data == NULL) {
|
||||
err = CS_ERR_NO_MEMORY;
|
||||
goto error_reply;
|
||||
}
|
||||
|
||||
if (sam_safe_read (parent_fd_in, user_data, size) != size) {
|
||||
err = CS_ERR_LIBRARY;
|
||||
goto free_error_reply;
|
||||
}
|
||||
}
|
||||
|
||||
err = sam_data_store (user_data, size);
|
||||
if (err != CS_OK) {
|
||||
goto free_error_reply;
|
||||
}
|
||||
|
||||
reply = SAM_REPLY_OK;
|
||||
if (sam_safe_write (parent_fd_out, &reply, sizeof (reply)) != sizeof (reply)) {
|
||||
err = CS_ERR_LIBRARY;
|
||||
goto free_error_reply;
|
||||
}
|
||||
|
||||
free (user_data);
|
||||
|
||||
return (CS_OK);
|
||||
|
||||
free_error_reply:
|
||||
free (user_data);
|
||||
error_reply:
|
||||
reply = SAM_REPLY_ERROR;
|
||||
if (sam_safe_write (parent_fd_out, &reply, sizeof (reply)) != sizeof (reply)) {
|
||||
return (CS_ERR_LIBRARY);
|
||||
}
|
||||
if (sam_safe_write (parent_fd_out, &err, sizeof (err)) != sizeof (err)) {
|
||||
return (CS_ERR_LIBRARY);
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static enum sam_parent_action_t sam_parent_handler (
|
||||
int parent_fd_in,
|
||||
int parent_fd_out,
|
||||
pid_t child_pid)
|
||||
{
|
||||
int poll_error;
|
||||
int action;
|
||||
@ -256,7 +509,7 @@ static enum sam_parent_action_t sam_parent_handler (int pipe_fd, pid_t child_pid
|
||||
action = SAM_PARENT_ACTION_CONTINUE;
|
||||
|
||||
while (action == SAM_PARENT_ACTION_CONTINUE) {
|
||||
pfds.fd = pipe_fd;
|
||||
pfds.fd = parent_fd_in;
|
||||
pfds.events = POLLIN;
|
||||
pfds.revents = 0;
|
||||
|
||||
@ -309,7 +562,7 @@ static enum sam_parent_action_t sam_parent_handler (int pipe_fd, pid_t child_pid
|
||||
/*
|
||||
* We have EOF or command in pipe
|
||||
*/
|
||||
bytes_read = read (pipe_fd, &command, 1);
|
||||
bytes_read = sam_safe_read (parent_fd_in, &command, 1);
|
||||
|
||||
if (bytes_read == 0) {
|
||||
/*
|
||||
@ -324,37 +577,33 @@ static enum sam_parent_action_t sam_parent_handler (int pipe_fd, pid_t child_pid
|
||||
}
|
||||
|
||||
if (bytes_read == -1) {
|
||||
/*
|
||||
* Something really bad happened in read side
|
||||
*/
|
||||
if (errno == EAGAIN || errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
action = SAM_PARENT_ACTION_ERROR;
|
||||
goto action_exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have read command -> take status
|
||||
* We have read command
|
||||
*/
|
||||
switch (status) {
|
||||
case 0:
|
||||
/*
|
||||
* Not started yet
|
||||
*/
|
||||
if (command == SAM_COMMAND_START)
|
||||
switch (command) {
|
||||
case SAM_COMMAND_START:
|
||||
if (status == 0) {
|
||||
/*
|
||||
* Not started yet
|
||||
*/
|
||||
status = 1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/*
|
||||
* Started
|
||||
*/
|
||||
if (command == SAM_COMMAND_STOP)
|
||||
}
|
||||
break;
|
||||
case SAM_COMMAND_STOP:
|
||||
if (status == 1) {
|
||||
/*
|
||||
* Started
|
||||
*/
|
||||
status = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case SAM_COMMAND_DATA_STORE:
|
||||
sam_parent_data_store (parent_fd_in, parent_fd_out);
|
||||
break;
|
||||
}
|
||||
} /* select_error > 0 */
|
||||
} /* action == SAM_PARENT_ACTION_CONTINUE */
|
||||
@ -369,7 +618,7 @@ cs_error_t sam_register (
|
||||
cs_error_t error;
|
||||
pid_t pid;
|
||||
int pipe_error;
|
||||
int pipe_fd[2];
|
||||
int pipe_fd_out[2], pipe_fd_in[2];
|
||||
enum sam_parent_action_t action;
|
||||
int child_status;
|
||||
|
||||
@ -380,12 +629,15 @@ cs_error_t sam_register (
|
||||
error = CS_OK;
|
||||
|
||||
while (1) {
|
||||
pipe_error = pipe (pipe_fd);
|
||||
if ((pipe_error = pipe (pipe_fd_out)) != 0) {
|
||||
error = CS_ERR_LIBRARY;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if ((pipe_error = pipe (pipe_fd_in)) != 0) {
|
||||
close (pipe_fd_out[0]);
|
||||
close (pipe_fd_out[1]);
|
||||
|
||||
if (pipe_error != 0) {
|
||||
/*
|
||||
* Pipe creation error
|
||||
*/
|
||||
error = CS_ERR_LIBRARY;
|
||||
goto error_exit;
|
||||
}
|
||||
@ -410,12 +662,16 @@ cs_error_t sam_register (
|
||||
/*
|
||||
* Child process
|
||||
*/
|
||||
close (pipe_fd[0]);
|
||||
close (pipe_fd_out[0]);
|
||||
close (pipe_fd_in[1]);
|
||||
|
||||
sam_internal_data.child_fd_out = pipe_fd_out[1];
|
||||
sam_internal_data.child_fd_in = pipe_fd_in[0];
|
||||
|
||||
sam_internal_data.parent_fd = pipe_fd[1];
|
||||
if (instance_id)
|
||||
*instance_id = sam_internal_data.instance_id;
|
||||
|
||||
sam_internal_data.am_i_child = 1;
|
||||
sam_internal_data.internal_status = SAM_INTERNAL_STATUS_REGISTERED;
|
||||
|
||||
goto error_exit;
|
||||
@ -423,11 +679,13 @@ cs_error_t sam_register (
|
||||
/*
|
||||
* Parent process
|
||||
*/
|
||||
close (pipe_fd[1]);
|
||||
close (pipe_fd_out[1]);
|
||||
close (pipe_fd_in[0]);
|
||||
|
||||
action = sam_parent_handler (pipe_fd[0], pid);
|
||||
action = sam_parent_handler (pipe_fd_out[0], pipe_fd_in[1], pid);
|
||||
|
||||
close (pipe_fd[0]);
|
||||
close (pipe_fd_out[0]);
|
||||
close (pipe_fd_in[1]);
|
||||
|
||||
if (action == SAM_PARENT_ACTION_ERROR) {
|
||||
error = CS_ERR_LIBRARY;
|
||||
@ -498,7 +756,7 @@ static void *hc_callback_thread (void *unused_param)
|
||||
}
|
||||
|
||||
if (poll_error > 0) {
|
||||
bytes_readed = read (sam_internal_data.cb_rpipe_fd, &command, 1);
|
||||
bytes_readed = sam_safe_read (sam_internal_data.cb_rpipe_fd, &command, 1);
|
||||
|
||||
if (bytes_readed > 0) {
|
||||
if (status == 0 && command == SAM_COMMAND_START)
|
||||
|
@ -100,6 +100,9 @@ dist_man_MANS = \
|
||||
votequorum_qdisk_unregister.3 \
|
||||
votequorum_setexpected.3 \
|
||||
votequorum_setvotes.3 \
|
||||
sam_data_getsize.3 \
|
||||
sam_data_restore.3 \
|
||||
sam_data_store.3 \
|
||||
sam_finalize.3 \
|
||||
sam_hc_callback_register.3 \
|
||||
sam_hc_send.3 \
|
||||
|
68
man/sam_data_getsize.3
Normal file
68
man/sam_data_getsize.3
Normal file
@ -0,0 +1,68 @@
|
||||
.\"/*
|
||||
.\" * Copyright (c) 2010 Red Hat, Inc.
|
||||
.\" *
|
||||
.\" * All rights reserved.
|
||||
.\" *
|
||||
.\" * Author: Jan Friesse (jfriesse@redhat.com)
|
||||
.\" *
|
||||
.\" * This software licensed under BSD license, the text of which follows:
|
||||
.\" *
|
||||
.\" * Redistribution and use in source and binary forms, with or without
|
||||
.\" * modification, are permitted provided that the following conditions are met:
|
||||
.\" *
|
||||
.\" * - Redistributions of source code must retain the above copyright notice,
|
||||
.\" * this list of conditions and the following disclaimer.
|
||||
.\" * - Redistributions in binary form must reproduce the above copyright notice,
|
||||
.\" * this list of conditions and the following disclaimer in the documentation
|
||||
.\" * and/or other materials provided with the distribution.
|
||||
.\" * - Neither the name of the Red Hat, Inc. nor the names of its
|
||||
.\" * contributors may be used to endorse or promote products derived from this
|
||||
.\" * software without specific prior written permission.
|
||||
.\" *
|
||||
.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
.\" * THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\" */
|
||||
.TH "SAM_DATA_GETSIZE" 3 "04/15/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
|
||||
|
||||
.SH NAME
|
||||
.P
|
||||
sam_data_getsize \- Return size of stored data in bytes
|
||||
|
||||
.SH SYNOPSIS
|
||||
.P
|
||||
\fB#include <corosync/sam.h>\fR
|
||||
|
||||
.P
|
||||
\fBcs_error_t sam_data_getsize (size_t *\fIsize\fB);\fR
|
||||
|
||||
.SH DESCRIPTION
|
||||
.P
|
||||
The \fBsam_data_getsize\fR function is used to return size of stored
|
||||
data. Size is returned in bytes. If user data is NULL, zero is returned.
|
||||
Function is intended to be used before \fBsam_data_restore(3)\fR call to
|
||||
properly allocate buffer for restored data.
|
||||
|
||||
.SH RETURN VALUE
|
||||
.P
|
||||
This call return CS_OK value if successful, otherwise and error is returned.
|
||||
|
||||
.SH ERRORS
|
||||
.TP
|
||||
CS_ERR_BAD_HANDLE
|
||||
component was not initialized by calling \fBsam_initialize(3)\fR or it was finalized.
|
||||
.TP
|
||||
CS_ERR_INVALID_PARAM
|
||||
size parameter is NULL
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR sam_data_store (3),
|
||||
.BR sam_data_restore (3)
|
77
man/sam_data_restore.3
Normal file
77
man/sam_data_restore.3
Normal file
@ -0,0 +1,77 @@
|
||||
.\"/*
|
||||
.\" * Copyright (c) 2010 Red Hat, Inc.
|
||||
.\" *
|
||||
.\" * All rights reserved.
|
||||
.\" *
|
||||
.\" * Author: Jan Friesse (jfriesse@redhat.com)
|
||||
.\" *
|
||||
.\" * This software licensed under BSD license, the text of which follows:
|
||||
.\" *
|
||||
.\" * Redistribution and use in source and binary forms, with or without
|
||||
.\" * modification, are permitted provided that the following conditions are met:
|
||||
.\" *
|
||||
.\" * - Redistributions of source code must retain the above copyright notice,
|
||||
.\" * this list of conditions and the following disclaimer.
|
||||
.\" * - Redistributions in binary form must reproduce the above copyright notice,
|
||||
.\" * this list of conditions and the following disclaimer in the documentation
|
||||
.\" * and/or other materials provided with the distribution.
|
||||
.\" * - Neither the name of the Red Hat, Inc. nor the names of its
|
||||
.\" * contributors may be used to endorse or promote products derived from this
|
||||
.\" * software without specific prior written permission.
|
||||
.\" *
|
||||
.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
.\" * THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\" */
|
||||
.TH "SAM_DATA_RESTORE" 3 "04/15/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
|
||||
|
||||
.SH NAME
|
||||
.P
|
||||
sam_data_restore \- Restore previously saved user data
|
||||
|
||||
.SH SYNOPSIS
|
||||
.P
|
||||
\fB#include <corosync/sam.h>\fR
|
||||
|
||||
.P
|
||||
\fBcs_error_t sam_data_restore (void *\fIdata\fB, size_t \fIsize\fB);\fR
|
||||
|
||||
.SH DESCRIPTION
|
||||
.P
|
||||
The \fBsam_data_restore\fR function is used to restore data, previously
|
||||
saved by calling \fBsam_data_store(3)\fR. Such data survives between instances.
|
||||
|
||||
.P
|
||||
The \fIdata\fR parameter is pointer to memory initialized by caller. Stored data
|
||||
are copied there. This also means, that caller is responsible for freeing memory.
|
||||
|
||||
.P
|
||||
The \fIsize\fR parameter is length of \fIdata\fR. This one must be at least same
|
||||
length as previously stored data otherwise error is returned. Parameter can
|
||||
be larger but only stored data size bytes are changed.
|
||||
|
||||
Use \fBsam_data_getsize(3)\fR to find out length of stored data.
|
||||
|
||||
.SH RETURN VALUE
|
||||
.P
|
||||
This call return CS_OK value if successful, otherwise and error is returned.
|
||||
|
||||
.SH ERRORS
|
||||
.TP
|
||||
CS_ERR_BAD_HANDLE
|
||||
component was not initialized by calling \fBsam_initialize(3)\fR or it was finalized.
|
||||
.TP
|
||||
CS_ERR_INVALID_PARAM
|
||||
data parameter is NULL or size is less then currently stored data length
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR sam_data_getsize (3),
|
||||
.BR sam_data_store (3)
|
83
man/sam_data_store.3
Normal file
83
man/sam_data_store.3
Normal file
@ -0,0 +1,83 @@
|
||||
.\"/*
|
||||
.\" * Copyright (c) 2010 Red Hat, Inc.
|
||||
.\" *
|
||||
.\" * All rights reserved.
|
||||
.\" *
|
||||
.\" * Author: Jan Friesse (jfriesse@redhat.com)
|
||||
.\" *
|
||||
.\" * This software licensed under BSD license, the text of which follows:
|
||||
.\" *
|
||||
.\" * Redistribution and use in source and binary forms, with or without
|
||||
.\" * modification, are permitted provided that the following conditions are met:
|
||||
.\" *
|
||||
.\" * - Redistributions of source code must retain the above copyright notice,
|
||||
.\" * this list of conditions and the following disclaimer.
|
||||
.\" * - Redistributions in binary form must reproduce the above copyright notice,
|
||||
.\" * this list of conditions and the following disclaimer in the documentation
|
||||
.\" * and/or other materials provided with the distribution.
|
||||
.\" * - Neither the name of the Red Hat, Inc. nor the names of its
|
||||
.\" * contributors may be used to endorse or promote products derived from this
|
||||
.\" * software without specific prior written permission.
|
||||
.\" *
|
||||
.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
.\" * THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\" */
|
||||
.TH "SAM_DATA_STORE" 3 "04/15/2010" "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
|
||||
|
||||
.SH NAME
|
||||
.P
|
||||
sam_data_store \- Store user data
|
||||
|
||||
.SH SYNOPSIS
|
||||
.P
|
||||
\fB#include <corosync/sam.h>\fR
|
||||
|
||||
.P
|
||||
\fBcs_error_t sam_data_store (const void *\fIdata\fB, size_t \fIsize\fB);\fR
|
||||
|
||||
.SH DESCRIPTION
|
||||
.P
|
||||
The \fBsam_data_store\fR function is used to store data, which survives between
|
||||
instances.
|
||||
|
||||
.P
|
||||
The \fIdata\fR parameter is pointer to memory with data to store. Data
|
||||
are stored in newly allocated memory inside library, so caller can safely remove
|
||||
them after call of function.
|
||||
|
||||
You can use NULL as parameter to remove and free previously saved data. In this
|
||||
case \fIsize\fR argument is ignored.
|
||||
|
||||
.P
|
||||
The \fIsize\fR parameter is length of \fIdata\fR.
|
||||
|
||||
Use \fBsam_data_getsize(3)\fR to find out length of stored data and \fBsam_data_restore(3)\fR
|
||||
to restore stored data.
|
||||
|
||||
.SH RETURN VALUE
|
||||
.P
|
||||
This call return CS_OK value if successful, otherwise and error is returned.
|
||||
|
||||
.SH ERRORS
|
||||
.TP
|
||||
CS_ERR_BAD_HANDLE
|
||||
component was not initialized by calling \fBsam_initialize(3)\fR or it was finalized.
|
||||
.TP
|
||||
CS_ERR_NO_MEMORY
|
||||
internal malloc/realloc failed because data are too large
|
||||
.TP
|
||||
CS_ERR_LIBRARY
|
||||
some internal error appeared (mostly because communication with parent process failed)
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR sam_data_getsize (3),
|
||||
.BR sam_data_restore (3)
|
@ -115,9 +115,19 @@ or add timers to the active process to signal a healthcheck operation is
|
||||
successful. To use event driven healthchecking,
|
||||
the \fBsam_hc_callback_register(3)\fR function should be executed.
|
||||
|
||||
.SH Storing user data
|
||||
.P
|
||||
Sometimes there is need to store some data, which survives between instances.
|
||||
One can in such case use files, databases, ... or much simpler in memory solution
|
||||
presented by \fBsam_data_store(3)\fR, \fBsam_data_restore(3)\fR and \fBsam_data_getsize(3)\fR
|
||||
functions.
|
||||
|
||||
.SH BUGS
|
||||
.SH "SEE ALSO"
|
||||
.BR sam_initialize (3),
|
||||
.BR sam_data_getsize (3),
|
||||
.BR sam_data_restore (3),
|
||||
.BR sam_data_store (3),
|
||||
.BR sam_finalize (3),
|
||||
.BR sam_start (3),
|
||||
.BR sam_stop (3),
|
||||
|
331
test/testsam.c
331
test/testsam.c
@ -46,10 +46,11 @@
|
||||
#include <corosync/corotypes.h>
|
||||
#include <corosync/sam.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
static int test2_sig_delivered = 0;
|
||||
static int test4_hc_cb_count = 0;
|
||||
static int test5_hc_cb_count = 0;
|
||||
|
||||
/*
|
||||
* First test will just register SAM, with policy restart. First instance will
|
||||
@ -273,11 +274,262 @@ static int test3 (void) {
|
||||
|
||||
}
|
||||
|
||||
static int test4_hc_cb (void)
|
||||
/*
|
||||
* Test sam_data_store, sam_data_restore and sam_data_getsize
|
||||
*/
|
||||
static int test4 (void)
|
||||
{
|
||||
printf ("%s %d\n", __FUNCTION__, ++test4_hc_cb_count);
|
||||
size_t size;
|
||||
cs_error_t err;
|
||||
int i;
|
||||
unsigned int instance_id;
|
||||
char saved_data[128];
|
||||
char saved_data2[128];
|
||||
|
||||
if (test4_hc_cb_count > 10)
|
||||
printf ("%s: sam_data_getsize 1\n", __FUNCTION__);
|
||||
err = sam_data_getsize (&size);
|
||||
if (err != CS_ERR_BAD_HANDLE) {
|
||||
fprintf (stderr, "Test should return CS_ERR_BAD_HANDLE. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_getsize 2\n", __FUNCTION__);
|
||||
err = sam_data_getsize (NULL);
|
||||
if (err != CS_ERR_INVALID_PARAM) {
|
||||
fprintf (stderr, "Test should return CS_ERR_INVALID_PARAM. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_store 1\n", __FUNCTION__);
|
||||
err = sam_data_store (NULL, 0);
|
||||
if (err != CS_ERR_BAD_HANDLE) {
|
||||
fprintf (stderr, "Test should return CS_ERR_BAD_HANDLE. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_restore 1\n", __FUNCTION__);
|
||||
err = sam_data_restore (saved_data, sizeof (saved_data));
|
||||
if (err != CS_ERR_BAD_HANDLE) {
|
||||
fprintf (stderr, "Test should return CS_ERR_BAD_HANDLE. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_initialize\n", __FUNCTION__);
|
||||
err = sam_initialize (0, SAM_RECOVERY_POLICY_RESTART);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Can't initialize SAM API. Error %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_getsize 3\n", __FUNCTION__);
|
||||
err = sam_data_getsize (&size);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_ERR_BAD_HANDLE. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
if (size != 0) {
|
||||
fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_restore 2\n", __FUNCTION__);
|
||||
err = sam_data_restore (NULL, sizeof (saved_data));
|
||||
if (err != CS_ERR_INVALID_PARAM) {
|
||||
fprintf (stderr, "Test should return CS_ERR_INVALID_PARAM. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store some real data
|
||||
*/
|
||||
for (i = 0; i < sizeof (saved_data); i++) {
|
||||
saved_data[i] = (char)(i + 5);
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_store 2\n", __FUNCTION__);
|
||||
err = sam_data_store (saved_data, sizeof (saved_data));
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_getsize 4\n", __FUNCTION__);
|
||||
err = sam_data_getsize (&size);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
if (size != sizeof (saved_data)) {
|
||||
fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_restore 3\n", __FUNCTION__);
|
||||
err = sam_data_restore (saved_data2, sizeof (saved_data2) - 1);
|
||||
if (err != CS_ERR_INVALID_PARAM) {
|
||||
fprintf (stderr, "Test should return CS_ERR_INVALID_PARAM. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_restore 4\n", __FUNCTION__);
|
||||
err = sam_data_restore (saved_data2, sizeof (saved_data2));
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (memcmp (saved_data, saved_data2, sizeof (saved_data2)) != 0) {
|
||||
fprintf (stderr, "Retored data are not same\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset (saved_data2, 0, sizeof (saved_data2));
|
||||
|
||||
printf ("%s: sam_data_store 3\n", __FUNCTION__);
|
||||
err = sam_data_store (NULL, 1);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_getsize 5\n", __FUNCTION__);
|
||||
err = sam_data_getsize (&size);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
if (size != 0) {
|
||||
fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: sam_data_store 4\n", __FUNCTION__);
|
||||
err = sam_data_store (saved_data, sizeof (saved_data));
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s: register\n", __FUNCTION__);
|
||||
err = sam_register (&instance_id);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Can't register. Error %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (instance_id == 1) {
|
||||
printf ("%s iid %d: sam_start\n", __FUNCTION__, instance_id);
|
||||
err = sam_start ();
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Can't start hc. Error %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s iid %d: sam_data_getsize 6\n", __FUNCTION__, instance_id);
|
||||
err = sam_data_getsize (&size);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
if (size != sizeof (saved_data2)) {
|
||||
fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s iid %d: sam_data_restore 5\n", __FUNCTION__, instance_id);
|
||||
err = sam_data_restore (saved_data2, sizeof (saved_data2));
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (memcmp (saved_data, saved_data2, sizeof (saved_data2)) != 0) {
|
||||
fprintf (stderr, "Retored data are not same\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof (saved_data); i++) {
|
||||
saved_data[i] = (char)(i - 5);
|
||||
}
|
||||
|
||||
printf ("%s iid %d: sam_data_store 5\n", __FUNCTION__, instance_id);
|
||||
err = sam_data_store (saved_data, sizeof (saved_data) - 7);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (instance_id == 2) {
|
||||
printf ("%s iid %d: sam_start\n", __FUNCTION__, instance_id);
|
||||
err = sam_start ();
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Can't start hc. Error %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s iid %d: sam_data_getsize 7\n", __FUNCTION__, instance_id);
|
||||
err = sam_data_getsize (&size);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
if (size != sizeof (saved_data2) - 7) {
|
||||
fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s iid %d: sam_data_restore 6\n", __FUNCTION__, instance_id);
|
||||
err = sam_data_restore (saved_data2, sizeof (saved_data2));
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof (saved_data); i++) {
|
||||
saved_data[i] = (char)(i - 5);
|
||||
}
|
||||
|
||||
if (memcmp (saved_data, saved_data2, sizeof (saved_data2) - 7) != 0) {
|
||||
fprintf (stderr, "Retored data are not same\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf ("%s iid %d: sam_data_store 6\n", __FUNCTION__, instance_id);
|
||||
err = sam_data_store (NULL, 0);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (instance_id == 3) {
|
||||
printf ("%s iid %d: sam_data_getsize 8\n", __FUNCTION__, instance_id);
|
||||
err = sam_data_getsize (&size);
|
||||
if (err != CS_OK) {
|
||||
fprintf (stderr, "Test should return CS_OK. Error returned %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
if (size != 0) {
|
||||
fprintf (stderr, "Test should return size of 0. Returned %zx\n", size);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int test5_hc_cb (void)
|
||||
{
|
||||
printf ("%s %d\n", __FUNCTION__, ++test5_hc_cb_count);
|
||||
|
||||
sam_data_store (&test5_hc_cb_count, sizeof (test5_hc_cb_count));
|
||||
|
||||
if (test5_hc_cb_count > 10)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@ -285,10 +537,11 @@ static int test4_hc_cb (void)
|
||||
/*
|
||||
* Test event driven healtchecking.
|
||||
*/
|
||||
static int test4 (void)
|
||||
static int test5 (void)
|
||||
{
|
||||
cs_error_t error;
|
||||
unsigned int instance_id;
|
||||
int hc_cb_count;
|
||||
|
||||
printf ("%s: initialize\n", __FUNCTION__);
|
||||
error = sam_initialize (100, SAM_RECOVERY_POLICY_RESTART);
|
||||
@ -305,7 +558,7 @@ static int test4 (void)
|
||||
|
||||
if (instance_id == 1) {
|
||||
printf ("%s iid %d: hc callback register\n", __FUNCTION__, instance_id);
|
||||
error = sam_hc_callback_register (test4_hc_cb);
|
||||
error = sam_hc_callback_register (test5_hc_cb);
|
||||
if (error != CS_OK) {
|
||||
fprintf (stderr, "Can't register hc cb. Error %d\n", error);
|
||||
return 1;
|
||||
@ -326,12 +579,25 @@ static int test4 (void)
|
||||
}
|
||||
|
||||
if (instance_id == 2) {
|
||||
error = sam_data_restore (&hc_cb_count, sizeof (hc_cb_count));
|
||||
if (error != CS_OK) {
|
||||
fprintf (stderr, "sam_data_restore should return CS_OK. Error returned %d\n", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (hc_cb_count != 11) {
|
||||
fprintf (stderr, "%s iid %d: Premature killed. hc_cb_count should be 11 and it is %d\n",
|
||||
__FUNCTION__, instance_id - 1, hc_cb_count);
|
||||
return 1;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pid_t pid;
|
||||
@ -347,17 +613,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
err = test1 ();
|
||||
|
||||
fprintf (stderr, "test1 %s\n", (err == 0 ? "passed" : "failed"));
|
||||
if (err != 0)
|
||||
all_passed = 0;
|
||||
|
||||
return err;
|
||||
return (test1 ());
|
||||
}
|
||||
|
||||
waitpid (pid, NULL, 0);
|
||||
waitpid (pid, &stat, 0);
|
||||
|
||||
fprintf (stderr, "test1 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
|
||||
if (WEXITSTATUS (stat) != 0)
|
||||
all_passed = 0;
|
||||
|
||||
pid = fork ();
|
||||
|
||||
@ -386,15 +649,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
err = test3 ();
|
||||
|
||||
fprintf (stderr, "test3 %s\n", (err == 0 ? "passed" : "failed"));
|
||||
if (err != 0)
|
||||
all_passed = 0;
|
||||
return err;
|
||||
return (test3 ());
|
||||
}
|
||||
|
||||
waitpid (pid, NULL, 0);
|
||||
waitpid (pid, &stat, 0);
|
||||
|
||||
fprintf (stderr, "test3 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
|
||||
if (WEXITSTATUS (stat) != 0)
|
||||
all_passed = 0;
|
||||
|
||||
pid = fork ();
|
||||
|
||||
@ -404,15 +666,32 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
err = test4 ();
|
||||
return (test4 ());
|
||||
}
|
||||
|
||||
waitpid (pid, &stat, 0);
|
||||
|
||||
fprintf (stderr, "test4 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
|
||||
if (WEXITSTATUS (stat) != 0)
|
||||
all_passed = 0;
|
||||
|
||||
pid = fork ();
|
||||
|
||||
if (pid == -1) {
|
||||
fprintf (stderr, "Can't fork\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
err = test5 ();
|
||||
|
||||
fprintf (stderr, "test4 %s\n", (err == 0 ? "passed" : "failed"));
|
||||
if (err != 0)
|
||||
all_passed = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
waitpid (pid, NULL, 0);
|
||||
waitpid (pid, &stat, 0);
|
||||
fprintf (stderr, "test5 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
|
||||
if (WEXITSTATUS (stat) != 0)
|
||||
all_passed = 0;
|
||||
|
||||
if (all_passed)
|
||||
fprintf (stderr, "All tests passed\n");
|
||||
|
Loading…
Reference in New Issue
Block a user