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:
parent
1cdaf10c45
commit
0becad39a7
@ -127,6 +127,8 @@ struct hast_resource {
|
||||
int hr_extentsize;
|
||||
/* Maximum number of extents that are kept dirty. */
|
||||
int hr_keepdirty;
|
||||
/* Path to a program to execute on various events. */
|
||||
char hr_exec[PATH_MAX];
|
||||
|
||||
/* Path to local component. */
|
||||
char hr_localpath[PATH_MAX];
|
||||
|
@ -62,7 +62,7 @@ const char *cfgpath = HAST_CONFIG;
|
||||
/* Hastd configuration. */
|
||||
static struct hastd_config *cfg;
|
||||
/* Was SIGCHLD signal received? */
|
||||
static bool sigchld_received = false;
|
||||
bool sigchld_received = false;
|
||||
/* Was SIGHUP signal received? */
|
||||
bool sighup_received = false;
|
||||
/* Was SIGINT or SIGTERM signal received? */
|
||||
@ -189,6 +189,8 @@ resource_needs_restart(const struct hast_resource *res0,
|
||||
return (true);
|
||||
if (res0->hr_timeout != res1->hr_timeout)
|
||||
return (true);
|
||||
if (strcmp(res0->hr_exec, res1->hr_exec) != 0)
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
@ -211,6 +213,8 @@ resource_needs_reload(const struct hast_resource *res0,
|
||||
return (true);
|
||||
if (res0->hr_timeout != res1->hr_timeout)
|
||||
return (true);
|
||||
if (strcmp(res0->hr_exec, res1->hr_exec) != 0)
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "hast.h"
|
||||
|
||||
extern const char *cfgpath;
|
||||
extern bool sigexit_received, sighup_received;
|
||||
extern bool sigchld_received, sigexit_received, sighup_received;
|
||||
extern struct pidfh *pfh;
|
||||
|
||||
void hastd_primary(struct hast_resource *res);
|
||||
|
@ -61,6 +61,7 @@ static char depth0_control[HAST_ADDRSIZE];
|
||||
static char depth0_listen[HAST_ADDRSIZE];
|
||||
static int depth0_replication;
|
||||
static int depth0_timeout;
|
||||
static char depth0_exec[PATH_MAX];
|
||||
|
||||
static char depth1_provname[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;
|
||||
strlcpy(depth0_control, HAST_CONTROL, sizeof(depth0_control));
|
||||
strlcpy(depth0_listen, HASTD_LISTEN, sizeof(depth0_listen));
|
||||
depth0_exec[0] = '\0';
|
||||
|
||||
lconfig = calloc(1, sizeof(*lconfig));
|
||||
if (lconfig == NULL) {
|
||||
@ -190,6 +192,14 @@ yy_config_parse(const char *config, bool exitonerror)
|
||||
*/
|
||||
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);
|
||||
@ -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 NUM STR OB CB
|
||||
|
||||
@ -239,6 +249,8 @@ statement:
|
||||
|
|
||||
timeout_statement
|
||||
|
|
||||
exec_statement
|
||||
|
|
||||
node_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
|
||||
{
|
||||
mynode = false;
|
||||
@ -456,6 +494,7 @@ resource_start: STR
|
||||
curres->hr_previous_role = HAST_ROLE_INIT;
|
||||
curres->hr_replication = -1;
|
||||
curres->hr_timeout = -1;
|
||||
curres->hr_exec[0] = '\0';
|
||||
curres->hr_provname[0] = '\0';
|
||||
curres->hr_localpath[0] = '\0';
|
||||
curres->hr_localfd = -1;
|
||||
@ -474,6 +513,8 @@ resource_entry:
|
||||
|
|
||||
timeout_statement
|
||||
|
|
||||
exec_statement
|
||||
|
|
||||
name_statement
|
||||
|
|
||||
local_statement
|
||||
|
@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "hast.h"
|
||||
#include "hast_proto.h"
|
||||
#include "hastd.h"
|
||||
#include "hooks.h"
|
||||
#include "metadata.h"
|
||||
#include "proto.h"
|
||||
#include "pjdlog.h"
|
||||
@ -433,6 +434,7 @@ init_environment(struct hast_resource *res __unused)
|
||||
signal(SIGINT, sighandler);
|
||||
signal(SIGTERM, sighandler);
|
||||
signal(SIGHUP, sighandler);
|
||||
signal(SIGCHLD, sighandler);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -791,6 +793,7 @@ hastd_primary(struct hast_resource *res)
|
||||
signal(SIGHUP, SIG_DFL);
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
|
||||
hook_init();
|
||||
init_local(res);
|
||||
if (real_remote(res) && init_remote(res, NULL, NULL))
|
||||
sync_start();
|
||||
@ -1737,6 +1740,9 @@ sighandler(int sig)
|
||||
case SIGHUP:
|
||||
sighup_received = true;
|
||||
break;
|
||||
case SIGCHLD:
|
||||
sigchld_received = true;
|
||||
break;
|
||||
default:
|
||||
assert(!"invalid condition");
|
||||
}
|
||||
@ -1788,6 +1794,7 @@ config_reload(void)
|
||||
#define MODIFIED_REMOTEADDR 0x1
|
||||
#define MODIFIED_REPLICATION 0x2
|
||||
#define MODIFIED_TIMEOUT 0x4
|
||||
#define MODIFIED_EXEC 0x8
|
||||
modified = 0;
|
||||
if (strcmp(gres->hr_remoteaddr, res->hr_remoteaddr) != 0) {
|
||||
/*
|
||||
@ -1805,6 +1812,10 @@ config_reload(void)
|
||||
gres->hr_timeout = res->hr_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
|
||||
* reconnecting.
|
||||
@ -1830,7 +1841,8 @@ config_reload(void)
|
||||
"Unable to set connection timeout");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if ((modified &
|
||||
(MODIFIED_REMOTEADDR | MODIFIED_REPLICATION)) != 0) {
|
||||
for (ii = 0; ii < ncomps; ii++) {
|
||||
if (!ISREMOTE(ii))
|
||||
continue;
|
||||
@ -1844,6 +1856,7 @@ config_reload(void)
|
||||
#undef MODIFIED_REMOTEADDR
|
||||
#undef MODIFIED_REPLICATION
|
||||
#undef MODIFIED_TIMEOUT
|
||||
#undef MODIFIED_EXEC
|
||||
|
||||
pjdlog_info("Configuration reloaded successfully.");
|
||||
return;
|
||||
@ -1907,6 +1920,9 @@ guard_thread(void *arg)
|
||||
sighup_received = false;
|
||||
config_reload();
|
||||
}
|
||||
hook_check(sigchld_received);
|
||||
if (sigchld_received)
|
||||
sigchld_received = false;
|
||||
|
||||
timeout = KEEPALIVE_SLEEP;
|
||||
pjdlog_debug(2, "remote_guard: Checking connections.");
|
||||
|
@ -49,6 +49,7 @@ listen { DP; return LISTEN; }
|
||||
port { DP; return PORT; }
|
||||
replication { DP; return REPLICATION; }
|
||||
timeout { DP; return TIMEOUT; }
|
||||
exec { DP; return EXEC; }
|
||||
resource { DP; return RESOURCE; }
|
||||
name { DP; return NAME; }
|
||||
local { DP; return LOCAL; }
|
||||
|
Loading…
Reference in New Issue
Block a user