From 6504900f1f52927adab3489b8d04b6644ceaee7d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 08:06:51 +0000 Subject: r23806: update Samba4 with the latest ctdb code. This doesn't get the ctdb code fully working in Samba4, it just gets it building and not breaking non-clustered use of Samba. It will take a bit longer to update some of the calling ctdb_cluster.c code to make it work correctly in Samba4. Note also that Samba4 now only links to the client portion of ctdb. For the moment I am leaving the ctdbd as a separate daemon, which you install separately from http://ctdb.samba.org/. (This used to be commit b196077cbb55cbecad87065133c2d67198e31066) --- source4/cluster/ctdb/tools/ctdb.c | 1024 ++++++++++++++++++++++++++++++ source4/cluster/ctdb/tools/ctdb_status.c | 132 ---- source4/cluster/ctdb/tools/onnode.rsh | 43 ++ source4/cluster/ctdb/tools/onnode.ssh | 43 ++ 4 files changed, 1110 insertions(+), 132 deletions(-) create mode 100644 source4/cluster/ctdb/tools/ctdb.c delete mode 100644 source4/cluster/ctdb/tools/ctdb_status.c create mode 100644 source4/cluster/ctdb/tools/onnode.rsh create mode 100755 source4/cluster/ctdb/tools/onnode.ssh (limited to 'source4/cluster/ctdb/tools') diff --git a/source4/cluster/ctdb/tools/ctdb.c b/source4/cluster/ctdb/tools/ctdb.c new file mode 100644 index 0000000000..2308261d00 --- /dev/null +++ b/source4/cluster/ctdb/tools/ctdb.c @@ -0,0 +1,1024 @@ +/* + ctdb control tool + + Copyright (C) Andrew Tridgell 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include "includes.h" +#include "lib/events/events.h" +#include "system/filesys.h" +#include "system/network.h" +#include "popt.h" +#include "cmdline.h" +#include "../include/ctdb.h" +#include "../include/ctdb_private.h" + +static void usage(void); + +static struct { + int timelimit; + uint32_t vnn; + int machinereadable; +} options; + +#define TIMELIMIT() timeval_current_ofs(options.timelimit, 0) + +/* + see if a process exists + */ +static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv) +{ + uint32_t vnn, pid; + int ret; + if (argc < 1) { + usage(); + } + + if (sscanf(argv[0], "%u:%u", &vnn, &pid) != 2) { + printf("Badly formed vnn:pid\n"); + return -1; + } + + ret = ctdb_ctrl_process_exists(ctdb, vnn, pid); + if (ret == 0) { + printf("%u:%u exists\n", vnn, pid); + } else { + printf("%u:%u does not exist\n", vnn, pid); + } + return ret; +} + +/* + display statistics structure + */ +static void show_statistics(struct ctdb_statistics *s) +{ + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + int i; + const char *prefix=NULL; + int preflen=0; + const struct { + const char *name; + uint32_t offset; + } fields[] = { +#define STATISTICS_FIELD(n) { #n, offsetof(struct ctdb_statistics, n) } + STATISTICS_FIELD(num_clients), + STATISTICS_FIELD(frozen), + STATISTICS_FIELD(recovering), + STATISTICS_FIELD(client_packets_sent), + STATISTICS_FIELD(client_packets_recv), + STATISTICS_FIELD(node_packets_sent), + STATISTICS_FIELD(node_packets_recv), + STATISTICS_FIELD(keepalive_packets_sent), + STATISTICS_FIELD(keepalive_packets_recv), + STATISTICS_FIELD(node.req_call), + STATISTICS_FIELD(node.reply_call), + STATISTICS_FIELD(node.req_dmaster), + STATISTICS_FIELD(node.reply_dmaster), + STATISTICS_FIELD(node.reply_error), + STATISTICS_FIELD(node.req_message), + STATISTICS_FIELD(node.req_control), + STATISTICS_FIELD(node.reply_control), + STATISTICS_FIELD(client.req_call), + STATISTICS_FIELD(client.req_message), + STATISTICS_FIELD(client.req_control), + STATISTICS_FIELD(timeouts.call), + STATISTICS_FIELD(timeouts.control), + STATISTICS_FIELD(timeouts.traverse), + STATISTICS_FIELD(total_calls), + STATISTICS_FIELD(pending_calls), + STATISTICS_FIELD(lockwait_calls), + STATISTICS_FIELD(pending_lockwait_calls), + STATISTICS_FIELD(memory_used), + STATISTICS_FIELD(max_hop_count), + }; + printf("CTDB version %u\n", CTDB_VERSION); + for (i=0;imax_call_latency); + printf(" %-30s %.6f sec\n", "max_lockwait_latency", s->max_lockwait_latency); + talloc_free(tmp_ctx); +} + +/* + display remote ctdb statistics combined from all nodes + */ +static int control_statistics_all(struct ctdb_context *ctdb) +{ + int ret, i; + struct ctdb_statistics statistics; + uint32_t *nodes; + uint32_t num_nodes; + + nodes = ctdb_get_connected_nodes(ctdb, TIMELIMIT(), ctdb, &num_nodes); + CTDB_NO_MEMORY(ctdb, nodes); + + ZERO_STRUCT(statistics); + + for (i=0;inum;i++){ + printf(":%d:%s:%d:%d:%d:\n", nodemap->nodes[i].vnn, + inet_ntoa(nodemap->nodes[i].sin.sin_addr), + !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED), + !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY), + !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED)); + } + return 0; + } + + printf("Number of nodes:%d\n", nodemap->num); + for(i=0;inum;i++){ + static const struct { + uint32_t flag; + const char *name; + } flag_names[] = { + { NODE_FLAGS_DISCONNECTED, "DISCONNECTED" }, + { NODE_FLAGS_PERMANENTLY_DISABLED, "DISABLED" }, + { NODE_FLAGS_BANNED, "BANNED" }, + { NODE_FLAGS_UNHEALTHY, "UNHEALTHY" }, + }; + char *flags_str = NULL; + int j; + for (j=0;jnodes[i].flags & flag_names[j].flag) { + if (flags_str == NULL) { + flags_str = talloc_strdup(ctdb, flag_names[j].name); + } else { + flags_str = talloc_asprintf_append(flags_str, "|%s", + flag_names[j].name); + } + CTDB_NO_MEMORY_FATAL(ctdb, flags_str); + } + } + if (flags_str == NULL) { + flags_str = talloc_strdup(ctdb, "OK"); + CTDB_NO_MEMORY_FATAL(ctdb, flags_str); + } + printf("vnn:%d %-16s %s%s\n", nodemap->nodes[i].vnn, + inet_ntoa(nodemap->nodes[i].sin.sin_addr), + flags_str, + nodemap->nodes[i].vnn == myvnn?" (THIS NODE)":""); + talloc_free(flags_str); + } + + ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), options.vnn, ctdb, &vnnmap); + if (ret != 0) { + printf("Unable to get vnnmap from node %u\n", options.vnn); + return ret; + } + printf("Generation:%d\n",vnnmap->generation); + printf("Size:%d\n",vnnmap->size); + for(i=0;isize;i++){ + printf("hash:%d lmaster:%d\n", i, vnnmap->map[i]); + } + + ret = ctdb_ctrl_getrecmode(ctdb, TIMELIMIT(), options.vnn, &recmode); + if (ret != 0) { + printf("Unable to get recmode from node %u\n", options.vnn); + return ret; + } + printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode); + + ret = ctdb_ctrl_getrecmaster(ctdb, TIMELIMIT(), options.vnn, &recmaster); + if (ret != 0) { + printf("Unable to get recmaster from node %u\n", options.vnn); + return ret; + } + printf("Recovery master:%d\n",recmaster); + + return 0; +} + +/* + kill a tcp connection + */ +static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int i, ret, numrst; + struct sockaddr_in src, dst; + + if (argc < 3) { + usage(); + } + + if (!parse_ip_port(argv[0], &src)) { + printf("Bad IP:port '%s'\n", argv[0]); + return -1; + } + + if (!parse_ip_port(argv[1], &dst)) { + printf("Bad IP:port '%s'\n", argv[1]); + return -1; + } + + numrst = strtoul(argv[2], NULL, 0); + + for (i=0;iev, &src, &dst); + + printf("ret:%d\n", ret); + if (ret==0) { + return 0; + } + } + + return -1; +} + +/* + send a tcp tickle ack + */ +static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int ret; + struct sockaddr_in src, dst; + + if (argc < 2) { + usage(); + } + + if (!parse_ip_port(argv[0], &src)) { + printf("Bad IP:port '%s'\n", argv[0]); + return -1; + } + + if (!parse_ip_port(argv[1], &dst)) { + printf("Bad IP:port '%s'\n", argv[1]); + return -1; + } + + ret = ctdb_sys_send_tcp(&src, &dst, 0, 0, 0); + if (ret==0) { + return 0; + } + printf("Error while sending tickle ack\n"); + + return -1; +} + +/* + display public ip status + */ +static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int i, ret; + struct ctdb_all_public_ips *ips; + uint32_t myvnn; + + myvnn = ctdb_ctrl_getvnn(ctdb, TIMELIMIT(), options.vnn); + + ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.vnn, ctdb, &ips); + if (ret != 0) { + printf("Unable to get public ips from node %u\n", options.vnn); + return ret; + } + + if(options.machinereadable){ + printf(":Public IP:Node:\n"); + for(i=0;inum;i++){ + printf(":%s:%d:\n", + inet_ntoa(ips->ips[i].sin.sin_addr), + ips->ips[i].takeover_vnn); + } + return 0; + } + + + printf("Number of nodes:%d\n", ips->num); + for(i=0;inum;i++){ + printf("%-16s %d\n", + inet_ntoa(ips->ips[i].sin.sin_addr), + ips->ips[i].takeover_vnn); + } + + return 0; +} + +/* + display pid of a ctdb daemon + */ +static int control_getpid(struct ctdb_context *ctdb, int argc, const char **argv) +{ + uint32_t pid; + int ret; + + ret = ctdb_ctrl_getpid(ctdb, TIMELIMIT(), options.vnn, &pid); + if (ret != 0) { + printf("Unable to get daemon pid from node %u\n", options.vnn); + return ret; + } + printf("Pid:%d\n", pid); + + return 0; +} + +/* + disable a remote node + */ +static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int ret; + + ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.vnn, NODE_FLAGS_PERMANENTLY_DISABLED, 0); + if (ret != 0) { + printf("Unable to disable node %u\n", options.vnn); + return ret; + } + + return 0; +} + +/* + enable a disabled remote node + */ +static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int ret; + + ret = ctdb_ctrl_modflags(ctdb, TIMELIMIT(), options.vnn, 0, NODE_FLAGS_PERMANENTLY_DISABLED); + if (ret != 0) { + printf("Unable to enable node %u\n", options.vnn); + return ret; + } + + return 0; +} + +/* + ban a node from the cluster + */ +static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int ret; + uint32_t recmaster; + struct ctdb_ban_info b; + TDB_DATA data; + uint32_t ban_time; + + if (argc < 1) { + usage(); + } + + ban_time = strtoul(argv[0], NULL, 0); + + ret = ctdb_ctrl_getrecmaster(ctdb, TIMELIMIT(), options.vnn, &recmaster); + if (ret != 0) { + DEBUG(0,("Failed to find the recmaster\n")); + return -1; + } + + b.vnn = options.vnn; + b.ban_time = ban_time; + + data.dptr = (uint8_t *)&b; + data.dsize = sizeof(b); + + ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_BAN_NODE, data); + if (ret != 0) { + DEBUG(0,("Failed to tell the recmaster to ban node %u\n", options.vnn)); + return -1; + } + + return 0; +} + + +/* + unban a node from the cluster + */ +static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int ret; + uint32_t recmaster; + TDB_DATA data; + + ret = ctdb_ctrl_getrecmaster(ctdb, TIMELIMIT(), options.vnn, &recmaster); + if (ret != 0) { + DEBUG(0,("Failed to find the recmaster\n")); + return -1; + } + + data.dptr = (uint8_t *)&options.vnn; + data.dsize = sizeof(uint32_t); + + ret = ctdb_send_message(ctdb, recmaster, CTDB_SRVID_UNBAN_NODE, data); + if (ret != 0) { + DEBUG(0,("Failed to tell the recmaster to unban node %u\n", options.vnn)); + return -1; + } + + return 0; +} + + +/* + shutdown a daemon + */ +static int control_shutdown(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int ret; + + ret = ctdb_ctrl_shutdown(ctdb, TIMELIMIT(), options.vnn); + if (ret != 0) { + printf("Unable to shutdown node %u\n", options.vnn); + return ret; + } + + return 0; +} + +/* + trigger a recovery + */ +static int control_recover(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int ret; + + ret = ctdb_ctrl_freeze(ctdb, TIMELIMIT(), options.vnn); + if (ret != 0) { + printf("Unable to freeze node\n"); + return ret; + } + + ret = ctdb_ctrl_setrecmode(ctdb, TIMELIMIT(), options.vnn, CTDB_RECOVERY_ACTIVE); + if (ret != 0) { + printf("Unable to set recovery mode\n"); + return ret; + } + + return 0; +} + + +/* + display monitoring mode of a remote node + */ +static int control_getmonmode(struct ctdb_context *ctdb, int argc, const char **argv) +{ + uint32_t monmode; + int ret; + + ret = ctdb_ctrl_getmonmode(ctdb, TIMELIMIT(), options.vnn, &monmode); + if (ret != 0) { + printf("Unable to get monmode from node %u\n", options.vnn); + return ret; + } + printf("Monitoring mode:%s (%d)\n",monmode==CTDB_MONITORING_ACTIVE?"ACTIVE":"DISABLED",monmode); + + return 0; +} + +/* + set the monitoring mode of a remote node + */ +static int control_setmonmode(struct ctdb_context *ctdb, int argc, const char **argv) +{ + uint32_t monmode; + int ret; + + if (argc < 1) { + usage(); + } + + monmode = strtoul(argv[0], NULL, 0); + + ret = ctdb_ctrl_setmonmode(ctdb, TIMELIMIT(), options.vnn, monmode); + if (ret != 0) { + printf("Unable to set monmode on node %u\n", options.vnn); + return ret; + } + + return 0; +} + +/* + display remote list of keys/data for a db + */ +static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv) +{ + const char *db_name; + struct ctdb_db_context *ctdb_db; + int ret; + + if (argc < 1) { + usage(); + } + + db_name = argv[0]; + ctdb_db = ctdb_attach(ctdb, db_name); + + if (ctdb_db == NULL) { + DEBUG(0,("Unable to attach to database '%s'\n", db_name)); + return -1; + } + + /* traverse and dump the cluster tdb */ + ret = ctdb_dump_db(ctdb_db, stdout); + if (ret == -1) { + printf("Unable to dump database\n"); + return -1; + } + talloc_free(ctdb_db); + + printf("Dumped %d records\n", ret); + return 0; +} + + +/* + display a list of the databases on a remote ctdb + */ +static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int i, ret; + struct ctdb_dbid_map *dbmap=NULL; + + ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.vnn, ctdb, &dbmap); + if (ret != 0) { + printf("Unable to get dbids from node %u\n", options.vnn); + return ret; + } + + printf("Number of databases:%d\n", dbmap->num); + for(i=0;inum;i++){ + const char *path; + const char *name; + + ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.vnn, dbmap->dbids[i], ctdb, &path); + ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.vnn, dbmap->dbids[i], ctdb, &name); + printf("dbid:0x%08x name:%s path:%s\n", dbmap->dbids[i], name, path); + } + + return 0; +} + +/* + ping a node + */ +static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv) +{ + int ret; + struct timeval tv = timeval_current(); + ret = ctdb_ctrl_ping(ctdb, options.vnn); + if (ret == -1) { + printf("Unable to get ping response from node %u\n", options.vnn); + } else { + printf("response from %u time=%.6f sec (%d clients)\n", + options.vnn, timeval_elapsed(&tv), ret); + } + return 0; +} + + +/* + get a tunable + */ +static int control_getvar(struct ctdb_context *ctdb, int argc, const char **argv) +{ + const char *name; + uint32_t value; + int ret; + + if (argc < 1) { + usage(); + } + + name = argv[0]; + ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(), options.vnn, name, &value); + if (ret == -1) { + printf("Unable to get tunable variable '%s'\n", name); + return -1; + } + + printf("%-19s = %u\n", name, value); + return 0; +} + +/* + set a tunable + */ +static int control_setvar(struct ctdb_context *ctdb, int argc, const char **argv) +{ + const char *name; + uint32_t value; + int ret; + + if (argc < 2) { + usage(); + } + + name = argv[0]; + value = strtoul(argv[1], NULL, 0); + + ret = ctdb_ctrl_set_tunable(ctdb, TIMELIMIT(), options.vnn, name, value); + if (ret == -1) { + printf("Unable to set tunable variable '%s'\n", name); + return -1; + } + return 0; +} + +/* + list all tunables + */ +static int control_listvars(struct ctdb_context *ctdb, int argc, const char **argv) +{ + uint32_t count; + const char **list; + int ret, i; + + ret = ctdb_ctrl_list_tunables(ctdb, TIMELIMIT(), options.vnn, ctdb, &list, &count); + if (ret == -1) { + printf("Unable to list tunable variables\n"); + return -1; + } + + for (i=0;i"}, + { "setvar", control_setvar, true, "set a tunable variable", " "}, + { "listvars", control_listvars, true, "list tunable variables"}, + { "statistics", control_statistics, false, "show statistics" }, + { "statisticsreset", control_statistics_reset, true, "reset statistics"}, + { "ip", control_ip, true, "show which public ip's that ctdb manages" }, + { "process-exists", control_process_exists, true, "check if a process exists on a node", ""}, + { "getdbmap", control_getdbmap, true, "show the database map" }, + { "catdb", control_catdb, true, "dump a database" , ""}, + { "getmonmode", control_getmonmode, true, "show monitoring mode" }, + { "setmonmode", control_setmonmode, true, "set monitoring mode", "<0|1>" }, + { "setdebug", control_setdebug, true, "set debug level", "" }, + { "getdebug", control_getdebug, true, "get debug level" }, + { "attach", control_attach, true, "attach to a database", "" }, + { "dumpmemory", control_dumpmemory, true, "dump memory map to logs" }, + { "getpid", control_getpid, true, "get ctdbd process ID" }, + { "disable", control_disable, true, "disable a nodes public IP" }, + { "enable", control_enable, true, "enable a nodes public IP" }, + { "ban", control_ban, true, "ban a node from the cluster", ""}, + { "unban", control_unban, true, "unban a node from the cluster" }, + { "shutdown", control_shutdown, true, "shutdown ctdbd" }, + { "recover", control_recover, true, "force recovery" }, + { "freeze", control_freeze, true, "freeze all databases" }, + { "thaw", control_thaw, true, "thaw all databases" }, + { "killtcp", kill_tcp, false, "kill a tcp connection. Try times.", " " }, + { "tickle", tickle_tcp, false, "send a tcp tickle ack", " " }, +}; + +/* + show usage message + */ +static void usage(void) +{ + int i; + printf( +"Usage: ctdb [options] \n" \ +"Options:\n" \ +" -n choose node number, or 'all' (defaults to local node)\n" +" -Y generate machinereadable output\n" +" -t set timelimit for control in seconds (default %u)\n", options.timelimit); + printf("Controls:\n"); + for (i=0;i. -*/ - -#include "includes.h" -#include "lib/events/events.h" -#include "system/filesys.h" -#include "popt.h" -#include "cmdline.h" -#include "../include/ctdb_private.h" - - -/* - display status structure - */ -static void show_status(struct ctdb_status *s) -{ - printf(" client_packets_sent %u\n", s->client_packets_sent); - printf(" client_packets_recv %u\n", s->client_packets_recv); - printf(" req_call %u\n", s->client.req_call); - printf(" req_message %u\n", s->client.req_message); - printf(" req_finished %u\n", s->client.req_finished); - printf(" req_register %u\n", s->client.req_register); - printf(" req_connect_wait %u\n", s->client.req_connect_wait); - printf(" req_shutdown %u\n", s->client.req_shutdown); - printf(" req_status %u\n", s->client.req_status); - printf(" node_packets_sent %u\n", s->node_packets_sent); - printf(" node_packets_recv %u\n", s->node_packets_recv); - printf(" req_call %u\n", s->client.req_call); - printf(" reply_call %u\n", s->count.reply_call); - printf(" reply_redirect %u\n", s->count.reply_redirect); - printf(" req_dmaster %u\n", s->count.req_dmaster); - printf(" reply_dmaster %u\n", s->count.reply_dmaster); - printf(" reply_error %u\n", s->count.reply_error); - printf(" reply_redirect %u\n", s->count.reply_redirect); - printf(" req_message %u\n", s->count.req_message); - printf(" req_finished %u\n", s->count.req_finished); - printf(" total_calls %u\n", s->total_calls); - printf(" pending_calls %u\n", s->pending_calls); - printf(" lockwait_calls %u\n", s->lockwait_calls); - printf(" pending_lockwait_calls %u\n", s->pending_lockwait_calls); - printf(" max_call_latency %.6f seconds\n", s->max_call_latency); - printf(" max_lockwait_latency %.6f seconds\n", s->max_lockwait_latency); -} - -/* - show usage message - */ -static void usage(void) -{ - printf("Usage: ctdb_status \n"); - exit(1); -} - -/* - main program -*/ -int main(int argc, const char *argv[]) -{ - struct ctdb_context *ctdb; - struct poptOption popt_options[] = { - POPT_AUTOHELP - POPT_CTDB_CMDLINE - POPT_TABLEEND - }; - int opt; - const char **extra_argv; - int extra_argc = 0; - int ret; - poptContext pc; - struct event_context *ev; - const char *ctdb_socket; - struct ctdb_status status; - - pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST); - - while ((opt = poptGetNextOpt(pc)) != -1) { - switch (opt) { - default: - fprintf(stderr, "Invalid option %s: %s\n", - poptBadOption(pc, 0), poptStrerror(opt)); - exit(1); - } - } - - /* setup the remaining options for the main program to use */ - extra_argv = poptGetArgs(pc); - if (extra_argv) { - extra_argv++; - while (extra_argv[extra_argc]) extra_argc++; - } - - if (extra_argc < 1) { - usage(); - } - - ctdb_socket = extra_argv[0]; - - ev = event_context_init(NULL); - - /* initialise ctdb */ - ctdb = ctdb_cmdline_client(ev, ctdb_socket); - if (ctdb == NULL) { - printf("Failed to init ctdb\n"); - exit(1); - } - - ret = ctdb_status(ctdb, &status); - if (ret != 0) { - printf("Failed to get ctdb status\n"); - exit(1); - } - - show_status(&status); - - return 0; -} diff --git a/source4/cluster/ctdb/tools/onnode.rsh b/source4/cluster/ctdb/tools/onnode.rsh new file mode 100644 index 0000000000..cdda3256f7 --- /dev/null +++ b/source4/cluster/ctdb/tools/onnode.rsh @@ -0,0 +1,43 @@ +#!/bin/sh +# onnode script for rsh + +if [ $# -lt 2 ]; then +cat < +EOF +exit 1 +fi + +NODE="$1" +shift +SCRIPT="$*" + +NODES=/etc/ctdb/nodes + +NUMNODES=`egrep '^[[:alnum:]]' $NODES | wc -l` +MAXNODE=`expr $NUMNODES - 1` + +if [ $NODE = "all" ]; then + for a in `egrep '^[[:alnum:]]' $NODES`; do + if [ -f "$SCRIPT" ]; then + rsh $a at -f $SCRIPT now + else + rsh $a $SCRIPT + fi + done + exit 0 +fi + +if [ $NODE -gt $MAXNODE ]; then + echo "Node $NODE doesn't exist" + exit 1 +fi + +NODEPLUSONE=`expr $NODE + 1` +a=`egrep '^[[:alnum:]]' $NODES | head -$NODEPLUSONE | tail -1` + +if [ -f "$SCRIPT" ]; then + exec rsh $a at -f $SCRIPT now +else + exec rsh $a $SCRIPT +fi diff --git a/source4/cluster/ctdb/tools/onnode.ssh b/source4/cluster/ctdb/tools/onnode.ssh new file mode 100755 index 0000000000..ec1231616e --- /dev/null +++ b/source4/cluster/ctdb/tools/onnode.ssh @@ -0,0 +1,43 @@ +#!/bin/sh +# onnode script for ssh + +if [ $# -lt 2 ]; then +cat < +EOF +exit 1 +fi + +NODE="$1" +shift +SCRIPT="$*" + +NODES=/etc/ctdb/nodes + +NUMNODES=`egrep '^[[:alnum:]]' $NODES | wc -l` +MAXNODE=`expr $NUMNODES - 1` + +if [ $NODE = "all" ]; then + for a in `egrep '^[[:alnum:]]' $NODES`; do + if [ -f "$SCRIPT" ]; then + ssh $a at -f $SCRIPT now + else + ssh $a $SCRIPT + fi + done + exit 0 +fi + +if [ $NODE -gt $MAXNODE ]; then + echo "Node $NODE doesn't exist" + exit 1 +fi + +NODEPLUSONE=`expr $NODE + 1` +a=`egrep '^[[:alnum:]]' $NODES | head -$NODEPLUSONE | tail -1` + +if [ -f "$SCRIPT" ]; then + exec ssh $a at -f $SCRIPT now +else + exec ssh $a $SCRIPT +fi -- cgit