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;
|
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];
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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.");
|
||||||
|
@ -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; }
|
||||||
|
Loading…
Reference in New Issue
Block a user