server/ctdb_control.o server/ctdb_call.o server/ctdb_ltdb_server.o \
server/ctdb_traverse.o server/eventscript.o server/ctdb_takeover.o \
server/ctdb_serverids.o server/ctdb_persistent.o \
- server/ctdb_keepalive.o server/ctdb_logging.o \
+ server/ctdb_keepalive.o server/ctdb_logging.o server/ctdb_uptime.c \
$(CTDB_CLIENT_OBJ) $(CTDB_TCP_OBJ) @INFINIBAND_WRAPPER_OBJ@
TEST_BINS=bin/ctdb_bench bin/ctdb_fetch bin/ctdb_store bin/ctdb_randrec bin/ctdb_persistent bin/rb_test \
return ctdb->pnn;
}
+
+/*
+ get the uptime of a remote node
+ */
+struct ctdb_client_control_state *
+ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
+{
+ return ctdb_control_send(ctdb, destnode, 0,
+ CTDB_CONTROL_UPTIME, 0, tdb_null,
+ mem_ctx, &timeout, NULL);
+}
+
+int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime)
+{
+ int ret;
+ int32_t res;
+ TDB_DATA outdata;
+
+ ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
+ if (ret != 0 || res != 0) {
+ DEBUG(0,(__location__ " ctdb_ctrl_uptime_recv failed\n"));
+ return -1;
+ }
+
+ *uptime = (struct ctdb_uptime *)talloc_steal(mem_ctx, outdata.dptr);
+
+ return 0;
+}
+
+int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime)
+{
+ struct ctdb_client_control_state *state;
+
+ state = ctdb_ctrl_uptime_send(ctdb, mem_ctx, timeout, destnode);
+ return ctdb_ctrl_uptime_recv(ctdb, mem_ctx, state, uptime);
+}
+
struct timeval timeout, uint32_t destnode,
struct ctdb_server_id_list **svid_list);
+struct ctdb_uptime {
+ struct timeval current_time;
+ struct timeval ctdbd_start_time;
+ struct timeval last_recovery_time;
+};
+
int ctdb_socket_connect(struct ctdb_context *ctdb);
+/*
+ get the uptime of a remote node
+ */
+int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime);
+
+struct ctdb_client_control_state *ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode);
+
+int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime);
+
#endif
/* main state of the ctdb daemon */
struct ctdb_context {
struct event_context *ev;
+ struct timeval ctdbd_start_time;
+ struct timeval last_recovery_time;
uint32_t recovery_mode;
TALLOC_CTX *tickle_update_context;
TALLOC_CTX *keepalive_ctx;
CTDB_CONTROL_TRANSACTION_COMMIT = 66,
CTDB_CONTROL_WIPE_DATABASE = 67,
CTDB_CONTROL_DELETE_RECORD = 68,
+ CTDB_CONTROL_UPTIME = 69,
};
/*
TDB_DATA indata);
int32_t ctdb_control_get_server_id_list(struct ctdb_context *ctdb,
TDB_DATA *outdata);
+int32_t ctdb_control_uptime(struct ctdb_context *ctdb,
+ TDB_DATA *outdata);
int ctdb_attach_persistent(struct ctdb_context *ctdb);
case CTDB_CONTROL_DELETE_RECORD:
return ctdb_control_delete_record(ctdb, indata);
+ case CTDB_CONTROL_UPTIME:
+ return ctdb_control_uptime(ctdb, outdata);
+
default:
DEBUG(0,(__location__ " Unknown CTDB control opcode %u\n", opcode));
return -1;
#include "includes.h"
#include "lib/events/events.h"
#include "lib/tdb/include/tdb.h"
+#include "system/time.h"
#include "system/network.h"
#include "system/filesys.h"
#include "system/wait.h"
ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
talloc_free(state);
+
+ gettimeofday(&ctdb->last_recovery_time, NULL);
}
/*
#include "lib/events/events.h"
#include "system/filesys.h"
#include "popt.h"
+#include "system/time.h"
#include "system/wait.h"
#include "system/network.h"
#include "cmdline.h"
}
DEBUG(0,("Starting CTDB daemon\n"));
-
+ gettimeofday(&ctdb->ctdbd_start_time, NULL);
+ gettimeofday(&ctdb->last_recovery_time, NULL);
ctdb->recovery_mode = CTDB_RECOVERY_NORMAL;
ctdb->recovery_master = (uint32_t)-1;
ctdb->upcalls = &ctdb_upcalls;
#include "includes.h"
#include "lib/events/events.h"
+#include "system/time.h"
#include "system/filesys.h"
#include "system/network.h"
#include "popt.h"
}
+/*
+ display uptime of remote node
+ */
+static int control_uptime(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ int ret;
+ int mypnn;
+ struct ctdb_uptime *uptime = NULL;
+ int tmp, days, hours, minutes, seconds;
+
+ mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
+ if (mypnn == -1) {
+ return -1;
+ }
+
+ ret = ctdb_ctrl_uptime(ctdb, ctdb, TIMELIMIT(), options.pnn, &uptime);
+ if (ret != 0) {
+ DEBUG(0, ("Unable to get uptime from node %u\n", options.pnn));
+ return ret;
+ }
+
+ printf("Current time of node : %s", ctime(&uptime->current_time.tv_sec));
+
+ tmp = uptime->current_time.tv_sec - uptime->ctdbd_start_time.tv_sec;
+ seconds = tmp%60;
+ tmp /= 60;
+ minutes = tmp%60;
+ tmp /= 60;
+ hours = tmp%24;
+ tmp /= 24;
+ days = tmp;
+ printf("Ctdbd start time : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->ctdbd_start_time.tv_sec));
+
+ tmp = uptime->current_time.tv_sec - uptime->last_recovery_time.tv_sec;
+ seconds = tmp%60;
+ tmp /= 60;
+ minutes = tmp%60;
+ tmp /= 60;
+ hours = tmp%24;
+ tmp /= 24;
+ days = tmp;
+ printf("Time of last recovery : (%03d %02d:%02d:%02d) %s", days, hours, minutes, seconds, ctime(&uptime->last_recovery_time.tv_sec));
+
+ return 0;
+}
+
/*
display remote ctdb status
*/
const char *args;
} ctdb_commands[] = {
{ "status", control_status, true, "show node status" },
+ { "uptime", control_uptime, true, "show node uptime" },
{ "ping", control_ping, true, "ping all nodes" },
{ "getvar", control_getvar, true, "get a tunable variable", "<name>"},
{ "setvar", control_setvar, true, "set a tunable variable", "<name> <value>"},