- moved ctdbd specific options to ctdbd.c from cmdline.c
authorAndrew Tridgell <tridge@samba.org>
Tue, 29 May 2007 02:49:25 +0000 (12:49 +1000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 29 May 2007 02:49:25 +0000 (12:49 +1000)
- allow a event script to be specified that will take IPs, release
  IPs, and handle recovery in system specific ways

- redirect stderr in subcommands to the log

(This used to be ctdb commit de0fc9ba370db781f9c46406ed180c8211946c7a)

ctdb/common/cmdline.c
ctdb/common/ctdb.c
ctdb/direct/ctdbd.c
ctdb/include/ctdb_private.h
ctdb/takeover/ctdb_takeover.c
ctdb/takeover/system.c

index 7eb15d567404af5a1055337c1aaffe492164f7b7..19a31514aef128931f74bb8128fc26932d6c49be 100644 (file)
@@ -30,8 +30,6 @@
 
 static struct {
        const char *nlist;
-       const char *public_address_list;
-       const char *public_interface;
        const char *transport;
        const char *myaddress;
        const char *socketname;
@@ -42,8 +40,6 @@ static struct {
        const char *events;
 } ctdb_cmdline = {
        .nlist = NULL,
-       .public_address_list = NULL,
-       .public_interface = NULL,
        .transport = "tcp",
        .myaddress = NULL,
        .socketname = CTDB_PATH,
@@ -80,8 +76,6 @@ struct poptOption popt_ctdb_cmdline[] = {
        { "torture", 0, POPT_ARG_NONE, &ctdb_cmdline.torture, 0, "enable nastiness in library", NULL },
        { "logfile", 0, POPT_ARG_STRING, &ctdb_cmdline.logfile, 0, "log file location", "filename" },
        { "events", 0, POPT_ARG_STRING, NULL, OPT_EVENTSYSTEM, "event system", NULL },
-       { "public-addresses", 0, POPT_ARG_STRING, &ctdb_cmdline.public_address_list, 0, "public address list file", "filename" },
-       { "public-interface", 0, POPT_ARG_STRING, &ctdb_cmdline.public_interface, 0, "public interface", "interface"},
        { NULL }
 };
 
@@ -148,20 +142,6 @@ struct ctdb_context *ctdb_cmdline_init(struct event_context *ev)
                exit(1);
        }
 
-       if (ctdb_cmdline.public_interface) {
-               ctdb->takeover.interface = talloc_strdup(ctdb, ctdb_cmdline.public_interface);
-               CTDB_NO_MEMORY_NULL(ctdb, ctdb->takeover.interface);
-       }
-
-       if (ctdb_cmdline.public_address_list) {
-               ret = ctdb_set_public_addresses(ctdb, ctdb_cmdline.public_address_list);
-               if (ret == -1) {
-                       printf("Unable to setup public address list\n");
-                       exit(1);
-               }
-               ctdb->takeover.enabled = true;
-       }
-
        if (ctdb_cmdline.db_dir) {
                ret = ctdb_set_tdb_dir(ctdb, ctdb_cmdline.db_dir);
                if (ret == -1) {
index 1f43a95b11e84b76375c8f178375f43092c41a85..1a2bacd0096ccf008f85766d7a780979f287c4c0 100644 (file)
@@ -44,6 +44,7 @@ int ctdb_set_logfile(struct ctdb_context *ctdb, const char *logfile)
        if (ctdb->logfile != NULL) {
                int fd;
                close(1);
+               close(2);
                fd = open(ctdb->logfile, O_WRONLY|O_APPEND|O_CREAT, 0666);
                if (fd == -1) {
                        abort();
@@ -52,6 +53,8 @@ int ctdb_set_logfile(struct ctdb_context *ctdb, const char *logfile)
                        dup2(fd, 1);
                        close(fd);
                }
+               /* also catch stderr of subcommands to the log file */
+               dup2(1, 2);
        }
        return 0;
 }
index e60e1812af8363f5d76d763bac4f36a446f35690..cc92c333bf202bee19ecd17f65d959c758f363b4 100644 (file)
@@ -38,6 +38,14 @@ static void block_signal(int signum)
        sigaction(signum, &act, NULL);
 }
 
+static struct {
+       const char *public_address_list;
+       const char *public_interface;
+       const char *event_script;
+} options = {
+       .event_script = "/etc/ctdb/events"
+};
+
 
 /*
   main program
@@ -51,9 +59,12 @@ int main(int argc, const char *argv[])
                POPT_AUTOHELP
                POPT_CTDB_CMDLINE
                { "interactive", 'i', POPT_ARG_NONE, &interactive, 0, "don't fork", NULL },
+               { "public-addresses", 0, POPT_ARG_STRING, &options.public_address_list, 0, "public address list file", "filename" },
+               { "public-interface", 0, POPT_ARG_STRING, &options.public_interface, 0, "public interface", "interface"},
+               { "event-script", 0, POPT_ARG_STRING, &options.event_script, 0, "event script", "filename" },
                POPT_TABLEEND
        };
-       int opt;
+       int opt, ret;
        const char **extra_argv;
        int extra_argc = 0;
        poptContext pc;
@@ -83,6 +94,26 @@ int main(int argc, const char *argv[])
 
        ctdb = ctdb_cmdline_init(ev);
 
+       if (options.public_interface) {
+               ctdb->takeover.interface = talloc_strdup(ctdb, options.public_interface);
+               CTDB_NO_MEMORY(ctdb, ctdb->takeover.interface);
+       }
+
+       if (options.public_address_list) {
+               ret = ctdb_set_public_addresses(ctdb, options.public_address_list);
+               if (ret == -1) {
+                       printf("Unable to setup public address list\n");
+                       exit(1);
+               }
+               ctdb->takeover.enabled = true;
+       }
+
+       ret = ctdb_set_event_script(ctdb, options.event_script);
+       if (ret == -1) {
+               printf("Unable to setup event script\n");
+               exit(1);
+       }
+
        /* useful default logfile */
        if (ctdb->logfile == NULL) {
                char *name = talloc_asprintf(ctdb, "%s/log.ctdb.vnn%u", 
index c6d514fae50cce3072aee1a2cfeaf53859d740b3..a5f98b3d3f8fba999e3c144991102db8ee10b225 100644 (file)
@@ -263,6 +263,7 @@ enum ctdb_freeze_mode {CTDB_FREEZE_NONE, CTDB_FREEZE_PENDING, CTDB_FREEZE_FROZEN
 struct ctdb_takeover {
        bool enabled;
        const char *interface;
+       const char *event_script;
        TALLOC_CTX *last_ctx;
 };
 
@@ -930,13 +931,11 @@ int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
 /* from takeover/system.c */
 int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface);
 bool ctdb_sys_have_ip(const char *ip);
-int ctdb_sys_take_ip(const char *ip, const char *interface);
-int ctdb_sys_release_ip(const char *ip, const char *interface);
 int ctdb_sys_send_ack(const struct sockaddr_in *dest, 
                      const struct sockaddr_in *src);
 
 int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist);
-
+int ctdb_set_event_script(struct ctdb_context *ctdb, const char *script);
 int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap);
 
 int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id, 
@@ -947,4 +946,5 @@ int32_t ctdb_control_startup(struct ctdb_context *ctdb, uint32_t vnn);
 
 void ctdb_takeover_client_destructor_hook(struct ctdb_client *client);
 
+
 #endif
index 931217df0fefd6d3db481a05cc18e2dd0825d54a..aa358c5fd39e962f1197c43244183ccbdd65cebf 100644 (file)
@@ -92,6 +92,26 @@ static void ctdb_control_send_arp(struct event_context *ev, struct timed_event *
 }
 
 
+/*
+  run the event script
+ */
+static int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
+{
+       va_list ap;
+       char *cmdstr;
+       int ret;
+
+       va_start(ap, fmt);
+       cmdstr = talloc_vasprintf(ctdb, fmt, ap);
+       va_end(ap);
+       CTDB_NO_MEMORY(ctdb, cmdstr);
+
+       ret = system(cmdstr);
+       talloc_free(cmdstr);
+
+       return ret;
+}
+
 /*
   take over an ip address
  */
@@ -107,8 +127,13 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb, TDB_DATA indata)
                return 0;
        }
 
-       DEBUG(0,("Takover of IP %s on interface %s\n", ip, ctdb->takeover.interface));
-       ret = ctdb_sys_take_ip(ip, ctdb->takeover.interface);
+       DEBUG(0,("Takover of IP %s/%u on interface %s\n", 
+                ip, ctdb->nodes[ctdb->vnn]->public_netmask_bits, 
+                ctdb->takeover.interface));
+       ret = ctdb_event_script(ctdb, "takeip %s %s %u",
+                               ctdb->takeover.interface, 
+                               ip,
+                               ctdb->nodes[ctdb->vnn]->public_netmask_bits);
        if (ret != 0) {
                DEBUG(0,(__location__ " Failed to takeover IP %s on interface %s\n",
                         ip, ctdb->takeover.interface));
@@ -158,13 +183,18 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb, TDB_DATA indata)
                return 0;
        }
 
-       DEBUG(0,("Release of IP %s on interface %s\n", ip, ctdb->takeover.interface));
+       DEBUG(0,("Release of IP %s/%u on interface %s\n", 
+                ip, ctdb->nodes[ctdb->vnn]->public_netmask_bits, 
+                ctdb->takeover.interface));
 
        /* stop any previous arps */
        talloc_free(ctdb->takeover.last_ctx);
        ctdb->takeover.last_ctx = NULL;
 
-       ret = ctdb_sys_release_ip(ip, ctdb->takeover.interface);
+       ret = ctdb_event_script(ctdb, "releaseip %s %s %u",
+                               ctdb->takeover.interface, 
+                               ip,
+                               ctdb->nodes[ctdb->vnn]->public_netmask_bits);
        if (ret != 0) {
                DEBUG(0,(__location__ " Failed to release IP %s on interface %s\n",
                         ip, ctdb->takeover.interface));
@@ -203,6 +233,16 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb, TDB_DATA indata)
 }
 
 
+/*
+  setup the event script
+*/
+int ctdb_set_event_script(struct ctdb_context *ctdb, const char *script)
+{
+       ctdb->takeover.event_script = talloc_strdup(ctdb, script);
+       CTDB_NO_MEMORY(ctdb, ctdb->takeover.event_script);
+       return 0;
+}
+
 /*
   setup the public address list from a file
 */
index d4a03460eac9bfb0bc787eb0737b380686be40fb..db55f2c2099c0bc2b46d7e6cd6ac6be0a8ea0c8d 100644 (file)
@@ -257,34 +257,3 @@ bool ctdb_sys_have_ip(const char *ip)
        return ret == 0;
 }
 
-/*
-  takeover an IP on an interface
- */
-int ctdb_sys_take_ip(const char *ip, const char *interface)
-{
-       char *cmdstr;
-       cmdstr = talloc_asprintf(NULL, "/sbin/ip addr add %s/32 dev %s 2> /dev/null",
-                                ip, interface);
-       if (cmdstr == NULL) {
-               return -1;
-       }
-       system(cmdstr);
-       talloc_free(cmdstr);
-       return 0;
-}
-
-/*
-  release an IP on an interface
- */
-int ctdb_sys_release_ip(const char *ip, const char *interface)
-{
-       char *cmdstr;
-       cmdstr = talloc_asprintf(NULL, "/sbin/ip addr del %s/32 dev %s 2> /dev/null",
-                                ip, interface);
-       if (cmdstr == NULL) {
-               return -1;
-       }
-       system(cmdstr);
-       talloc_free(cmdstr);
-       return 0;
-}