summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2010-08-27 15:16:52 +0000
committerpjd <pjd@FreeBSD.org>2010-08-27 15:16:52 +0000
commit74741a8c60590fd6adadb341f500aeadbdf656e8 (patch)
treebdae12fd7401b11b403ff6d526a8574d9aa98483 /sbin
parentaeab5efe07c7865c2e084ae4ad41a58592f0a106 (diff)
downloadFreeBSD-src-74741a8c60590fd6adadb341f500aeadbdf656e8.zip
FreeBSD-src-74741a8c60590fd6adadb341f500aeadbdf656e8.tar.gz
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
Diffstat (limited to 'sbin')
-rw-r--r--sbin/hastd/hast.h2
-rw-r--r--sbin/hastd/hastd.c6
-rw-r--r--sbin/hastd/hastd.h2
-rw-r--r--sbin/hastd/parse.y43
-rw-r--r--sbin/hastd/primary.c18
-rw-r--r--sbin/hastd/token.l1
6 files changed, 68 insertions, 4 deletions
diff --git a/sbin/hastd/hast.h b/sbin/hastd/hast.h
index 1f3b386..7137917 100644
--- a/sbin/hastd/hast.h
+++ b/sbin/hastd/hast.h
@@ -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];
diff --git a/sbin/hastd/hastd.c b/sbin/hastd/hastd.c
index 31fc3bf..c5eebf4 100644
--- a/sbin/hastd/hastd.c
+++ b/sbin/hastd/hastd.c
@@ -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);
}
diff --git a/sbin/hastd/hastd.h b/sbin/hastd/hastd.h
index 12b384d..a32e512 100644
--- a/sbin/hastd/hastd.h
+++ b/sbin/hastd/hastd.h
@@ -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);
diff --git a/sbin/hastd/parse.y b/sbin/hastd/parse.y
index 5b4f3e5..ca575cf 100644
--- a/sbin/hastd/parse.y
+++ b/sbin/hastd/parse.y
@@ -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
diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c
index dd26f4a..bc91266 100644
--- a/sbin/hastd/primary.c
+++ b/sbin/hastd/primary.c
@@ -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.");
diff --git a/sbin/hastd/token.l b/sbin/hastd/token.l
index e5d4ca1..05d600c 100644
--- a/sbin/hastd/token.l
+++ b/sbin/hastd/token.l
@@ -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; }
OpenPOWER on IntegriCloud