Patch allows warn_signal_set call in child.
Regards,
Honza
>From a1b644f243523f1148738c1eaf3be064593e55eb Mon Sep 17 00:00:00 2001
From: Jan Friesse <[email protected]>
Date: Thu, 29 Apr 2010 16:34:53 +0200
Subject: [PATCH 1/2] Allow call sam_warn_signal_set after sam_register
Patch fixes situation, when user want to change warn signal after
call of sam_register function. This was not possible, because parent
process never got new value from child.
---
trunk/lib/libsam.verso | 2 +-
trunk/lib/sam.c | 132 ++++++++++++++++++++++++++++++-------
trunk/test/testsam.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 278 insertions(+), 29 deletions(-)
diff --git a/trunk/lib/libsam.verso b/trunk/lib/libsam.verso
index 6aba2b2..fae6e3d 100644
--- a/trunk/lib/libsam.verso
+++ b/trunk/lib/libsam.verso
@@ -1 +1 @@
-4.2.0
+4.2.1
diff --git a/trunk/lib/sam.c b/trunk/lib/sam.c
index 207d4f9..95654e7 100644
--- a/trunk/lib/sam.c
+++ b/trunk/lib/sam.c
@@ -73,6 +73,7 @@ enum sam_command_t {
SAM_COMMAND_STOP,
SAM_COMMAND_HB,
SAM_COMMAND_DATA_STORE,
+ SAM_COMMAND_WARN_SIGNAL_SET,
};
enum sam_reply_t {
@@ -194,6 +195,40 @@ static size_t sam_safe_read (
return (bytes_read);
}
+static cs_error_t sam_read_reply (
+ int child_fd_in)
+{
+ char reply;
+ cs_error_t err;
+
+ 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;
+ }
+
+ return (CS_OK);
+}
+
cs_error_t sam_data_getsize (size_t *size)
{
if (size == NULL) {
@@ -247,7 +282,6 @@ cs_error_t sam_data_store (
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 &&
@@ -290,29 +324,8 @@ cs_error_t sam_data_store (
/*
* 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);
- }
-
+ if ((err = sam_read_reply (sam_internal_data.child_fd_in)) != CS_OK) {
return (err);
- break;
- case SAM_REPLY_OK:
- /*
- * Everything correct
- */
- break;
- default:
- return (CS_ERR_LIBRARY);
- break;
}
}
@@ -421,17 +434,87 @@ exit_error:
cs_error_t sam_warn_signal_set (int warn_signal)
{
+ char command;
+ cs_error_t err;
+
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.am_i_child) {
+ /*
+ * We are child so we must send data to parent
+ */
+ command = SAM_COMMAND_WARN_SIGNAL_SET;
+ 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, &warn_signal, sizeof (warn_signal)) !=
+ sizeof (warn_signal)) {
+ return (CS_ERR_LIBRARY);
+ }
+
+ /*
+ * And wait for reply
+ */
+ if ((err = sam_read_reply (sam_internal_data.child_fd_in)) != CS_OK) {
+ return (err);
+ }
+ }
+
+ /*
+ * We are parent or we received OK reply from parent -> do required action
+ */
sam_internal_data.warn_signal = warn_signal;
return (CS_OK);
}
+static cs_error_t sam_parent_warn_signal_set (
+ int parent_fd_in,
+ int parent_fd_out)
+{
+ char reply;
+ char *user_data;
+ int warn_signal;
+ cs_error_t err;
+
+ err = CS_OK;
+ user_data = NULL;
+
+ if (sam_safe_read (parent_fd_in, &warn_signal, sizeof (warn_signal)) != sizeof (warn_signal)) {
+ err = CS_ERR_LIBRARY;
+ goto error_reply;
+ }
+
+ err = sam_warn_signal_set (warn_signal);
+ if (err != CS_OK) {
+ goto error_reply;
+ }
+
+ reply = SAM_REPLY_OK;
+ if (sam_safe_write (parent_fd_out, &reply, sizeof (reply)) != sizeof (reply)) {
+ err = CS_ERR_LIBRARY;
+ goto error_reply;
+ }
+
+ return (CS_OK);
+
+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 cs_error_t sam_parent_data_store (
int parent_fd_in,
int parent_fd_out)
@@ -604,6 +687,9 @@ static enum sam_parent_action_t sam_parent_handler (
case SAM_COMMAND_DATA_STORE:
sam_parent_data_store (parent_fd_in, parent_fd_out);
break;
+ case SAM_COMMAND_WARN_SIGNAL_SET:
+ sam_parent_warn_signal_set (parent_fd_in, parent_fd_out);
+ break;
}
} /* select_error > 0 */
} /* action == SAM_PARENT_ACTION_CONTINUE */
diff --git a/trunk/test/testsam.c b/trunk/test/testsam.c
index ce68d2b..6941b32 100644
--- a/trunk/test/testsam.c
+++ b/trunk/test/testsam.c
@@ -51,6 +51,7 @@
static int test2_sig_delivered = 0;
static int test5_hc_cb_count = 0;
+static int test6_sig_delivered = 0;
/*
* First test will just register SAM, with policy restart. First instance will
@@ -597,6 +598,142 @@ static int test5 (void)
return 1;
}
+static void test6_signal (int sig) {
+ cs_error_t error;
+
+ printf ("%s\n", __FUNCTION__);
+ test6_sig_delivered++;
+
+ if ((error = sam_data_store (&test6_sig_delivered, sizeof (test6_sig_delivered))) != CS_OK) {
+ fprintf (stderr, "Can't store data! Error : %d\n", error);
+ }
+}
+
+/*
+ * Test warn signal set.
+ */
+static int test6 (void) {
+ cs_error_t error;
+ unsigned int instance_id;
+ int test6_sig_del;
+
+ printf ("%s: initialize\n", __FUNCTION__);
+ error = sam_initialize (2000, SAM_RECOVERY_POLICY_RESTART);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't initialize SAM API. Error %d\n", error);
+ return 1;
+ }
+ printf ("%s: register\n", __FUNCTION__);
+ error = sam_register (&instance_id);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't register. Error %d\n", error);
+ return 1;
+ }
+
+ if (instance_id == 1) {
+ error = sam_warn_signal_set (SIGUSR1);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't set warn signal. Error %d\n", error);
+ return 1;
+ }
+
+ signal (SIGUSR1, test6_signal);
+
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ error = sam_start ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", error);
+ return 1;
+ }
+
+ printf ("%s iid %d: sleep 1\n", __FUNCTION__, instance_id);
+ sleep (1);
+
+ printf ("%s iid %d: hc send\n", __FUNCTION__, instance_id);
+ error = sam_hc_send ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't send hc. Error %d\n", error);
+ return 1;
+ }
+
+
+ printf ("%s iid %d: wait for delivery of signal\n", __FUNCTION__, instance_id);
+ while (!test6_sig_delivered) {
+ sleep (1);
+ }
+
+ printf ("%s iid %d: wait for real kill\n", __FUNCTION__, instance_id);
+
+ sleep (3);
+
+ printf ("%s iid %d: wasn't killed\n", __FUNCTION__, instance_id);
+ return (1);
+ }
+
+ if (instance_id == 2) {
+ error = sam_data_restore (&test6_sig_del, sizeof (test6_sig_del));
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't restore data. Error %d\n", error);
+ return 1;
+ }
+
+ if (test6_sig_del != 1) {
+ fprintf (stderr, "Previous test failed. Signal was not delivered\n");
+ return 1;
+ }
+
+ error = sam_warn_signal_set (SIGKILL);
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't set warn signal. Error %d\n", error);
+ return 1;
+ }
+
+ signal (SIGUSR1, test6_signal);
+
+ printf ("%s iid %d: start\n", __FUNCTION__, instance_id);
+ error = sam_start ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't start hc. Error %d\n", error);
+ return 1;
+ }
+
+ printf ("%s iid %d: sleep 1\n", __FUNCTION__, instance_id);
+ sleep (1);
+
+ printf ("%s iid %d: hc send\n", __FUNCTION__, instance_id);
+ error = sam_hc_send ();
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't send hc. Error %d\n", error);
+ return 1;
+ }
+
+
+ printf ("%s iid %d: wait for delivery of signal\n", __FUNCTION__, instance_id);
+ while (!test6_sig_delivered) {
+ sleep (1);
+ }
+
+ printf ("%s iid %d: wasn't killed\n", __FUNCTION__, instance_id);
+ return (1);
+ }
+
+ if (instance_id == 3) {
+ error = sam_data_restore (&test6_sig_del, sizeof (test6_sig_del));
+ if (error != CS_OK) {
+ fprintf (stderr, "Can't restore data. Error %d\n", error);
+ return 1;
+ }
+
+ if (test6_sig_del != 1) {
+ fprintf (stderr, "Previous test failed. Signal WAS delivered\n");
+ return 1;
+ }
+
+ return (0);
+ }
+
+ return 1;
+}
int main(int argc, char *argv[])
{
@@ -613,7 +750,9 @@ int main(int argc, char *argv[])
}
if (pid == 0) {
- return (test1 ());
+ err = test1 ();
+ sam_finalize ();
+ return err;
}
waitpid (pid, &stat, 0);
@@ -632,7 +771,8 @@ int main(int argc, char *argv[])
if (pid == 0) {
err = test2 ();
- return err;
+ sam_finalize ();
+ return (err);
}
waitpid (pid, &stat, 0);
@@ -649,7 +789,9 @@ int main(int argc, char *argv[])
}
if (pid == 0) {
- return (test3 ());
+ err = test3 ();
+ sam_finalize ();
+ return (err);
}
waitpid (pid, &stat, 0);
@@ -666,7 +808,9 @@ int main(int argc, char *argv[])
}
if (pid == 0) {
- return (test4 ());
+ err = test4 ();
+ sam_finalize ();
+ return (err);
}
waitpid (pid, &stat, 0);
@@ -685,7 +829,8 @@ int main(int argc, char *argv[])
if (pid == 0) {
err = test5 ();
- return err;
+ sam_finalize ();
+ return (err);
}
waitpid (pid, &stat, 0);
@@ -693,6 +838,24 @@ int main(int argc, char *argv[])
if (WEXITSTATUS (stat) != 0)
all_passed = 0;
+ pid = fork ();
+
+ if (pid == -1) {
+ fprintf (stderr, "Can't fork\n");
+ return 1;
+ }
+
+ if (pid == 0) {
+ err = test6 ();
+ sam_finalize ();
+ return (err);
+ }
+
+ waitpid (pid, &stat, 0);
+ fprintf (stderr, "test6 %s\n", (WEXITSTATUS (stat) == 0 ? "passed" : "failed"));
+ if (WEXITSTATUS (stat) != 0)
+ all_passed = 0;
+
if (all_passed)
fprintf (stderr, "All tests passed\n");
--
1.6.2.5
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais