Author: pjd
Date: Fri Aug 27 15:16:52 2010
New Revision: 211886
URL: http://svn.freebsd.org/changeset/base/211886

Log:
  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

Modified:
  head/sbin/hastd/hast.h
  head/sbin/hastd/hastd.c
  head/sbin/hastd/hastd.h
  head/sbin/hastd/parse.y
  head/sbin/hastd/primary.c
  head/sbin/hastd/token.l

Modified: head/sbin/hastd/hast.h
==============================================================================
--- head/sbin/hastd/hast.h      Fri Aug 27 14:38:12 2010        (r211885)
+++ head/sbin/hastd/hast.h      Fri Aug 27 15:16:52 2010        (r211886)
@@ -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];

Modified: head/sbin/hastd/hastd.c
==============================================================================
--- head/sbin/hastd/hastd.c     Fri Aug 27 14:38:12 2010        (r211885)
+++ head/sbin/hastd/hastd.c     Fri Aug 27 15:16:52 2010        (r211886)
@@ -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
                        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_
                return (true);
        if (res0->hr_timeout != res1->hr_timeout)
                return (true);
+       if (strcmp(res0->hr_exec, res1->hr_exec) != 0)
+               return (true);
        return (false);
 }
 

Modified: head/sbin/hastd/hastd.h
==============================================================================
--- head/sbin/hastd/hastd.h     Fri Aug 27 14:38:12 2010        (r211885)
+++ head/sbin/hastd/hastd.h     Fri Aug 27 15:16:52 2010        (r211886)
@@ -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);

Modified: head/sbin/hastd/parse.y
==============================================================================
--- head/sbin/hastd/parse.y     Fri Aug 27 14:38:12 2010        (r211885)
+++ head/sbin/hastd/parse.y     Fri Aug 27 15:16:52 2010        (r211886)
@@ -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
        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
                         */
                        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 *conf
 }
 %}
 
-%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

Modified: head/sbin/hastd/primary.c
==============================================================================
--- head/sbin/hastd/primary.c   Fri Aug 27 14:38:12 2010        (r211885)
+++ head/sbin/hastd/primary.c   Fri Aug 27 15:16:52 2010        (r211886)
@@ -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 *r
        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.");

Modified: head/sbin/hastd/token.l
==============================================================================
--- head/sbin/hastd/token.l     Fri Aug 27 14:38:12 2010        (r211885)
+++ head/sbin/hastd/token.l     Fri Aug 27 15:16:52 2010        (r211886)
@@ -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; }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to