Allow to execute specified program on various HAST events.

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-27 15:16:52 +00:00
parent 1cdaf10c45
commit 0becad39a7
6 changed files with 68 additions and 4 deletions

View File

@ -127,6 +127,8 @@ struct hast_resource {
int hr_extentsize; int hr_extentsize;
/* Maximum number of extents that are kept dirty. */ /* Maximum number of extents that are kept dirty. */
int hr_keepdirty; int hr_keepdirty;
/* Path to a program to execute on various events. */
char hr_exec[PATH_MAX];
/* Path to local component. */ /* Path to local component. */
char hr_localpath[PATH_MAX]; char hr_localpath[PATH_MAX];

View File

@ -62,7 +62,7 @@ const char *cfgpath = HAST_CONFIG;
/* Hastd configuration. */ /* Hastd configuration. */
static struct hastd_config *cfg; static struct hastd_config *cfg;
/* Was SIGCHLD signal received? */ /* Was SIGCHLD signal received? */
static bool sigchld_received = false; bool sigchld_received = false;
/* Was SIGHUP signal received? */ /* Was SIGHUP signal received? */
bool sighup_received = false; bool sighup_received = false;
/* Was SIGINT or SIGTERM signal received? */ /* Was SIGINT or SIGTERM signal received? */
@ -189,6 +189,8 @@ resource_needs_restart(const struct hast_resource *res0,
return (true); return (true);
if (res0->hr_timeout != res1->hr_timeout) if (res0->hr_timeout != res1->hr_timeout)
return (true); return (true);
if (strcmp(res0->hr_exec, res1->hr_exec) != 0)
return (true);
} }
return (false); return (false);
} }
@ -211,6 +213,8 @@ resource_needs_reload(const struct hast_resource *res0,
return (true); return (true);
if (res0->hr_timeout != res1->hr_timeout) if (res0->hr_timeout != res1->hr_timeout)
return (true); return (true);
if (strcmp(res0->hr_exec, res1->hr_exec) != 0)
return (true);
return (false); return (false);
} }

View File

@ -40,7 +40,7 @@
#include "hast.h" #include "hast.h"
extern const char *cfgpath; extern const char *cfgpath;
extern bool sigexit_received, sighup_received; extern bool sigchld_received, sigexit_received, sighup_received;
extern struct pidfh *pfh; extern struct pidfh *pfh;
void hastd_primary(struct hast_resource *res); void hastd_primary(struct hast_resource *res);

View File

@ -61,6 +61,7 @@ static char depth0_control[HAST_ADDRSIZE];
static char depth0_listen[HAST_ADDRSIZE]; static char depth0_listen[HAST_ADDRSIZE];
static int depth0_replication; static int depth0_replication;
static int depth0_timeout; static int depth0_timeout;
static char depth0_exec[PATH_MAX];
static char depth1_provname[PATH_MAX]; static char depth1_provname[PATH_MAX];
static char depth1_localpath[PATH_MAX]; static char depth1_localpath[PATH_MAX];
@ -130,6 +131,7 @@ yy_config_parse(const char *config, bool exitonerror)
depth0_replication = HAST_REPLICATION_MEMSYNC; depth0_replication = HAST_REPLICATION_MEMSYNC;
strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control)); strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control));
strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen)); strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen));
depth0_exec[0] = '\0';
lconfig = calloc(1, sizeof(*lconfig)); lconfig = calloc(1, sizeof(*lconfig));
if (lconfig == NULL) { if (lconfig == NULL) {
@ -190,6 +192,14 @@ yy_config_parse(const char *config, bool exitonerror)
*/ */
curres->hr_timeout = depth0_timeout; curres->hr_timeout = depth0_timeout;
} }
if (curres->hr_exec[0] == '\0') {
/*
* Exec is not set at resource-level.
* Use global or default setting.
*/
strlcpy(curres->hr_exec, depth0_exec,
sizeof(curres->hr_exec));
}
} }
return (lconfig); return (lconfig);
@ -208,7 +218,7 @@ yy_config_free(struct hastd_config *config)
} }
%} %}
%token CONTROL LISTEN PORT REPLICATION TIMEOUT EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON %token CONTROL LISTEN PORT REPLICATION TIMEOUT EXEC EXTENTSIZE RESOURCE NAME LOCAL REMOTE ON
%token FULLSYNC MEMSYNC ASYNC %token FULLSYNC MEMSYNC ASYNC
%token NUM STR OB CB %token NUM STR OB CB
@ -239,6 +249,8 @@ statement:
| |
timeout_statement timeout_statement
| |
exec_statement
|
node_statement node_statement
| |
resource_statement resource_statement
@ -338,6 +350,32 @@ timeout_statement: TIMEOUT NUM
} }
; ;
exec_statement: EXEC STR
{
switch (depth) {
case 0:
if (strlcpy(depth0_exec, $2, sizeof(depth0_exec)) >=
sizeof(depth0_exec)) {
pjdlog_error("Exec path is too long.");
return (1);
}
break;
case 1:
if (curres == NULL)
break;
if (strlcpy(curres->hr_exec, $2,
sizeof(curres->hr_exec)) >=
sizeof(curres->hr_exec)) {
pjdlog_error("Exec path is too long.");
return (1);
}
break;
default:
assert(!"exec at wrong depth level");
}
}
;
node_statement: ON node_start OB node_entries CB node_statement: ON node_start OB node_entries CB
{ {
mynode = false; mynode = false;
@ -456,6 +494,7 @@ resource_start: STR
curres->hr_previous_role = HAST_ROLE_INIT; curres->hr_previous_role = HAST_ROLE_INIT;
curres->hr_replication = -1; curres->hr_replication = -1;
curres->hr_timeout = -1; curres->hr_timeout = -1;
curres->hr_exec[0] = '\0';
curres->hr_provname[0] = '\0'; curres->hr_provname[0] = '\0';
curres->hr_localpath[0] = '\0'; curres->hr_localpath[0] = '\0';
curres->hr_localfd = -1; curres->hr_localfd = -1;
@ -474,6 +513,8 @@ resource_entry:
| |
timeout_statement timeout_statement
| |
exec_statement
|
name_statement name_statement
| |
local_statement local_statement

View File

@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include "hast.h" #include "hast.h"
#include "hast_proto.h" #include "hast_proto.h"
#include "hastd.h" #include "hastd.h"
#include "hooks.h"
#include "metadata.h" #include "metadata.h"
#include "proto.h" #include "proto.h"
#include "pjdlog.h" #include "pjdlog.h"
@ -433,6 +434,7 @@ init_environment(struct hast_resource *res __unused)
signal(SIGINT, sighandler); signal(SIGINT, sighandler);
signal(SIGTERM, sighandler); signal(SIGTERM, sighandler);
signal(SIGHUP, sighandler); signal(SIGHUP, sighandler);
signal(SIGCHLD, sighandler);
} }
static void static void
@ -791,6 +793,7 @@ hastd_primary(struct hast_resource *res)
signal(SIGHUP, SIG_DFL); signal(SIGHUP, SIG_DFL);
signal(SIGCHLD, SIG_DFL); signal(SIGCHLD, SIG_DFL);
hook_init();
init_local(res); init_local(res);
if (real_remote(res) && init_remote(res, NULL, NULL)) if (real_remote(res) && init_remote(res, NULL, NULL))
sync_start(); sync_start();
@ -1737,6 +1740,9 @@ sighandler(int sig)
case SIGHUP: case SIGHUP:
sighup_received = true; sighup_received = true;
break; break;
case SIGCHLD:
sigchld_received = true;
break;
default: default:
assert(!"invalid condition"); assert(!"invalid condition");
} }
@ -1788,6 +1794,7 @@ config_reload(void)
#define MODIFIED_REMOTEADDR 0x1 #define MODIFIED_REMOTEADDR 0x1
#define MODIFIED_REPLICATION 0x2 #define MODIFIED_REPLICATION 0x2
#define MODIFIED_TIMEOUT 0x4 #define MODIFIED_TIMEOUT 0x4
#define MODIFIED_EXEC 0x8
modified = 0; modified = 0;
if (strcmp(gres->hr_remoteaddr, res->hr_remoteaddr) != 0) { if (strcmp(gres->hr_remoteaddr, res->hr_remoteaddr) != 0) {
/* /*
@ -1805,6 +1812,10 @@ config_reload(void)
gres->hr_timeout = res->hr_timeout; gres->hr_timeout = res->hr_timeout;
modified |= MODIFIED_TIMEOUT; modified |= MODIFIED_TIMEOUT;
} }
if (strcmp(gres->hr_exec, res->hr_exec) != 0) {
strlcpy(gres->hr_exec, res->hr_exec, sizeof(gres->hr_exec));
modified |= MODIFIED_EXEC;
}
/* /*
* If only timeout was modified we only need to change it without * If only timeout was modified we only need to change it without
* reconnecting. * reconnecting.
@ -1830,7 +1841,8 @@ config_reload(void)
"Unable to set connection timeout"); "Unable to set connection timeout");
} }
} }
} else { } else if ((modified &
(MODIFIED_REMOTEADDR | MODIFIED_REPLICATION)) != 0) {
for (ii = 0; ii < ncomps; ii++) { for (ii = 0; ii < ncomps; ii++) {
if (!ISREMOTE(ii)) if (!ISREMOTE(ii))
continue; continue;
@ -1844,6 +1856,7 @@ config_reload(void)
#undef MODIFIED_REMOTEADDR #undef MODIFIED_REMOTEADDR
#undef MODIFIED_REPLICATION #undef MODIFIED_REPLICATION
#undef MODIFIED_TIMEOUT #undef MODIFIED_TIMEOUT
#undef MODIFIED_EXEC
pjdlog_info("Configuration reloaded successfully."); pjdlog_info("Configuration reloaded successfully.");
return; return;
@ -1907,6 +1920,9 @@ guard_thread(void *arg)
sighup_received = false; sighup_received = false;
config_reload(); config_reload();
} }
hook_check(sigchld_received);
if (sigchld_received)
sigchld_received = false;
timeout = KEEPALIVE_SLEEP; timeout = KEEPALIVE_SLEEP;
pjdlog_debug(2, "remote_guard: Checking connections."); pjdlog_debug(2, "remote_guard: Checking connections.");

View File

@ -49,6 +49,7 @@ listen { DP; return LISTEN; }
port { DP; return PORT; } port { DP; return PORT; }
replication { DP; return REPLICATION; } replication { DP; return REPLICATION; }
timeout { DP; return TIMEOUT; } timeout { DP; return TIMEOUT; }
exec { DP; return EXEC; }
resource { DP; return RESOURCE; } resource { DP; return RESOURCE; }
name { DP; return NAME; } name { DP; return NAME; }
local { DP; return LOCAL; } local { DP; return LOCAL; }