Execute hook when connection between the nodes is established or lost.

MFC after:	2 weeks
Obtained from:	Wheel Systems Sp. z o.o. http://www.wheelsystems.com
This commit is contained in:
Pawel Jakub Dawidek 2010-08-30 00:31:30 +00:00
parent 2be8fd75ff
commit 5b41e64486
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=211984
3 changed files with 41 additions and 10 deletions

View File

@ -28,7 +28,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd August 29, 2010 .Dd August 30, 2010
.Dt HAST.CONF 5 .Dt HAST.CONF 5
.Os .Os
.Sh NAME .Sh NAME
@ -212,6 +212,20 @@ Execute the given program on various HAST events.
Below is the list of currently implemented events and arguments the given Below is the list of currently implemented events and arguments the given
program is executed with: program is executed with:
.Bl -tag -width ".Ic xxxx" .Bl -tag -width ".Ic xxxx"
.It Ic "<path> role <resource> <oldrole> <newrole>"
.Pp
Executed on both primary and secondary nodes when resource role is changed.
.Pp
.It Ic "<path> connect <resource>"
.Pp
Executed on both primary and secondary nodes when connection for the given
resource between the nodes is established.
.Pp
.It Ic "<path> disconnect <resource>"
.Pp
Executed on both primary and secondary nodes when connection for the given
resource between the nodes is lost.
.Pp
.It Ic "<path> syncstart <resource>" .It Ic "<path> syncstart <resource>"
.Pp .Pp
Executed on primary node when synchronization process of secondary node is Executed on primary node when synchronization process of secondary node is
@ -228,10 +242,6 @@ Executed on primary node when synchronization process of secondary node is
interrupted, most likely due to secondary node outage or connection failure interrupted, most likely due to secondary node outage or connection failure
between the nodes. between the nodes.
.Pp .Pp
.It Ic "<path> role <resource> <oldrole> <newrole>"
.Pp
Executed on both primary and secondary nodes when resource role is changed.
.Pp
.It Ic "<path> split-brain <resource>" .It Ic "<path> split-brain <resource>"
.Pp .Pp
Executed on both primary and secondary nodes when split-brain condition is Executed on both primary and secondary nodes when split-brain condition is

View File

@ -672,6 +672,7 @@ init_remote(struct hast_resource *res, struct proto_conn **inp,
res->hr_remotein = in; res->hr_remotein = in;
res->hr_remoteout = out; res->hr_remoteout = out;
} }
hook_exec(res->hr_exec, "connect", res->hr_name, NULL);
return (true); return (true);
close: close:
if (errmsg != NULL && strcmp(errmsg, "Split-brain condition!") == 0) if (errmsg != NULL && strcmp(errmsg, "Split-brain condition!") == 0)
@ -765,8 +766,6 @@ hastd_primary(struct hast_resource *res)
pid_t pid; pid_t pid;
int error; int error;
gres = res;
/* /*
* Create communication channel between parent and child. * Create communication channel between parent and child.
*/ */
@ -788,6 +787,8 @@ hastd_primary(struct hast_resource *res)
return; return;
} }
gres = res;
(void)pidfile_close(pfh); (void)pidfile_close(pfh);
hook_fini(); hook_fini();
@ -894,6 +895,8 @@ remote_close(struct hast_resource *res, int ncomp)
* Stop synchronization if in-progress. * Stop synchronization if in-progress.
*/ */
sync_stop(); sync_stop();
hook_exec(res->hr_exec, "disconnect", res->hr_name, NULL);
} }
/* /*

View File

@ -74,6 +74,8 @@ struct hio {
TAILQ_ENTRY(hio) hio_next; TAILQ_ENTRY(hio) hio_next;
}; };
static struct hast_resource *gres;
/* /*
* Free list holds unused structures. When free list is empty, we have to wait * Free list holds unused structures. When free list is empty, we have to wait
* until some in-progress requests are freed. * until some in-progress requests are freed.
@ -360,6 +362,8 @@ hastd_secondary(struct hast_resource *res, struct nv *nvin)
return; return;
} }
gres = res;
(void)pidfile_close(pfh); (void)pidfile_close(pfh);
hook_fini(); hook_fini();
@ -378,6 +382,7 @@ hastd_secondary(struct hast_resource *res, struct nv *nvin)
init_local(res); init_local(res);
init_remote(res, nvin); init_remote(res, nvin);
init_environment(); init_environment();
hook_exec(res->hr_exec, "connect", res->hr_name, NULL);
error = pthread_create(&td, NULL, recv_thread, res); error = pthread_create(&td, NULL, recv_thread, res);
assert(error == 0); assert(error == 0);
@ -501,6 +506,19 @@ requnpack(struct hast_resource *res, struct hio *hio)
return (hio->hio_error); return (hio->hio_error);
} }
static void
secondary_exit(int exitcode, const char *fmt, ...)
{
va_list ap;
assert(exitcode != EX_OK);
va_start(ap, fmt);
pjdlogv_errno(LOG_ERR, fmt, ap);
va_end(ap);
hook_exec(gres->hr_exec, "disconnect", gres->hr_name, NULL);
exit(exitcode);
}
/* /*
* Thread receives requests from the primary node. * Thread receives requests from the primary node.
*/ */
@ -515,7 +533,7 @@ recv_thread(void *arg)
QUEUE_TAKE(free, hio); QUEUE_TAKE(free, hio);
pjdlog_debug(2, "recv: (%p) Got request.", hio); pjdlog_debug(2, "recv: (%p) Got request.", hio);
if (hast_proto_recv_hdr(res->hr_remotein, &hio->hio_nv) < 0) { if (hast_proto_recv_hdr(res->hr_remotein, &hio->hio_nv) < 0) {
pjdlog_exit(EX_TEMPFAIL, secondary_exit(EX_TEMPFAIL,
"Unable to receive request header"); "Unable to receive request header");
} }
if (requnpack(res, hio) != 0) { if (requnpack(res, hio) != 0) {
@ -537,7 +555,7 @@ recv_thread(void *arg)
} else if (hio->hio_cmd == HIO_WRITE) { } else if (hio->hio_cmd == HIO_WRITE) {
if (hast_proto_recv_data(res, res->hr_remotein, if (hast_proto_recv_data(res, res->hr_remotein,
hio->hio_nv, hio->hio_data, MAXPHYS) < 0) { hio->hio_nv, hio->hio_data, MAXPHYS) < 0) {
pjdlog_exit(EX_TEMPFAIL, secondary_exit(EX_TEMPFAIL,
"Unable to receive reply data"); "Unable to receive reply data");
} }
} }
@ -693,7 +711,7 @@ send_thread(void *arg)
nv_add_int16(nvout, hio->hio_error, "error"); nv_add_int16(nvout, hio->hio_error, "error");
if (hast_proto_send(res, res->hr_remoteout, nvout, data, if (hast_proto_send(res, res->hr_remoteout, nvout, data,
length) < 0) { length) < 0) {
pjdlog_exit(EX_TEMPFAIL, "Unable to send reply."); secondary_exit(EX_TEMPFAIL, "Unable to send reply.");
} }
nv_free(nvout); nv_free(nvout);
pjdlog_debug(2, "send: (%p) Moving request to the free queue.", pjdlog_debug(2, "send: (%p) Moving request to the free queue.",