static struct {
const char *nlist;
- const char *public_address_list;
- const char *public_interface;
const char *transport;
const char *myaddress;
const char *socketname;
const char *events;
} ctdb_cmdline = {
.nlist = NULL,
- .public_address_list = NULL,
- .public_interface = NULL,
.transport = "tcp",
.myaddress = NULL,
.socketname = CTDB_PATH,
{ "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 }
};
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) {
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();
dup2(fd, 1);
close(fd);
}
+ /* also catch stderr of subcommands to the log file */
+ dup2(1, 2);
}
return 0;
}
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
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;
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",
struct ctdb_takeover {
bool enabled;
const char *interface;
+ const char *event_script;
TALLOC_CTX *last_ctx;
};
/* 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,
void ctdb_takeover_client_destructor_hook(struct ctdb_client *client);
+
#endif
}
+/*
+ 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
*/
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));
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));
}
+/*
+ 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
*/
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;
-}