int ctdb_status(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_status *status)
{
int ret;
- TDB_DATA data, outdata;
+ TDB_DATA data;
int32_t res;
ZERO_STRUCT(data);
ret = ctdb_control(ctdb, destnode, 0,
CTDB_CONTROL_STATUS, data,
- ctdb, &outdata, &res);
+ ctdb, &data, &res);
if (ret != 0 || res != 0) {
DEBUG(0,(__location__ " ctdb_control for status failed\n"));
return -1;
}
- if (outdata.dsize != sizeof(struct ctdb_status)) {
+ if (data.dsize != sizeof(struct ctdb_status)) {
DEBUG(0,(__location__ " Wrong status size %u - expected %u\n",
- outdata.dsize, sizeof(struct ctdb_status)));
+ data.dsize, sizeof(struct ctdb_status)));
return -1;
}
- *status = *(struct ctdb_status *)outdata.dptr;
+ *status = *(struct ctdb_status *)data.dptr;
+ talloc_free(data.dptr);
return 0;
}
}
c = *(struct ctdb_context *)data.dptr;
+ talloc_free(data.dptr);
ctdb->num_nodes = c.num_nodes;
ctdb->num_connected = c.num_connected;
talloc_free(data.dptr);
return 0;
-
+}
+
+/*
+ get debug level on a node
+ */
+int ctdb_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, uint32_t *level)
+{
+ int ret;
+ int32_t res;
+ TDB_DATA data;
+
+ ZERO_STRUCT(data);
+ ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, data,
+ ctdb, &data, &res);
+ if (ret != 0 || res != 0) {
+ return -1;
+ }
+ if (data.dsize != sizeof(uint32_t)) {
+ DEBUG(0,("Bad control reply size in ctdb_get_debuglevel (got %u)\n",
+ data.dsize));
+ return -1;
+ }
+ *level = *(uint32_t *)data.dptr;
+ talloc_free(data.dptr);
+ return 0;
+}
+
+/*
+ set debug level on a node
+ */
+int ctdb_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, uint32_t level)
+{
+ int ret;
+ int32_t res;
+ TDB_DATA data;
+
+ data.dptr = (uint8_t *)&level;
+ data.dsize = sizeof(level);
+
+ ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_DEBUG, data,
+ NULL, NULL, &res);
+ if (ret != 0 || res != 0) {
+ return -1;
+ }
+ return 0;
}
};
#define CHECK_CONTROL_DATA_SIZE(size) do { \
- if (indata.dsize != sizeof(pid_t)) { \
- DEBUG(0,(__location__ " Invalid data in opcode %u\n", opcode)); \
+ if (indata.dsize != size) { \
+ DEBUG(0,(__location__ " Invalid data size in opcode %u. Got %u expected %u\n", \
+ opcode, indata.dsize, size)); \
return -1; \
} \
} while (0)
return kill(pid, 0);
}
+ case CTDB_CONTROL_SET_DEBUG: {
+ CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
+ LogLevel = *(uint32_t *)indata.dptr;
+ return 0;
+ }
+
+ case CTDB_CONTROL_GET_DEBUG: {
+ CHECK_CONTROL_DATA_SIZE(0);
+ outdata->dptr = (uint8_t *)&LogLevel;
+ outdata->dsize = sizeof(LogLevel);
+ return 0;
+ }
+
case CTDB_CONTROL_STATUS: {
CHECK_CONTROL_DATA_SIZE(0);
outdata->dptr = (uint8_t *)&ctdb->status;
uint32_t db_id;
struct ctdb_db_context *ctdb_db;
- CHECK_CONTROL_DATA_SIZE(db_id);
+ CHECK_CONTROL_DATA_SIZE(sizeof(db_id));
db_id = *(uint32_t *)indata.dptr;
ctdb_db = find_ctdb_db(ctdb, db_id);
if (ctdb_db == NULL) return -1;
int ctdb_get_config(struct ctdb_context *ctdb);
+int ctdb_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, uint32_t *level);
+int ctdb_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, uint32_t level);
+
#endif
CTDB_CONTROL_PING,
CTDB_CONTROL_GETDBPATH,
CTDB_CONTROL_GETVNNMAP,
- CTDB_CONTROL_SETVNNMAP};
+ CTDB_CONTROL_SETVNNMAP,
+ CTDB_CONTROL_GET_DEBUG,
+ CTDB_CONTROL_SET_DEBUG};
enum call_state {CTDB_CALL_WAIT, CTDB_CALL_DONE, CTDB_CALL_ERROR};
printf("Usage: ctdb_control [options] <control>\n");
printf("\nControls:\n");
printf(" ping\n");
- printf(" process-exists <vnn:pid>\n");
- printf(" status <vnn>\n");
- printf(" getvnnmap <vnn>\n");
+ printf(" process-exists <vnn:pid> see if a process exists\n");
+ printf(" status <vnn> show ctdb status on a node\n");
+ printf(" debug <vnn> <level> set ctdb debug level on a node\n");
+ printf(" debuglevel display ctdb debug levels\n");
+ printf(" getvnnmap <vnn> display ctdb vnnmap\n");
printf(" setvnnmap <vnn> <generation> <numslots> <lmaster>*\n");
exit(1);
}
+/*
+ see if a process exists
+ */
static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv)
{
uint32_t vnn, pid;
printf(" max_lockwait_latency %.6f sec\n", s->max_lockwait_latency);
}
+/*
+ display remote ctdb status
+ */
static int control_status(struct ctdb_context *ctdb, int argc, const char **argv)
{
uint32_t vnn;
return 0;
}
+/*
+ display remote ctdb vnn map
+ */
static int control_getvnnmap(struct ctdb_context *ctdb, int argc, const char **argv)
{
uint32_t vnn;
return 0;
}
+/*
+ set remote ctdb vnn map
+ */
static int control_setvnnmap(struct ctdb_context *ctdb, int argc, const char **argv)
{
uint32_t vnn;
return 0;
}
+/*
+ ping all node
+ */
static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
{
int ret, i;
return 0;
}
+
+/*
+ display debug level on all node
+ */
+static int control_debuglevel(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ int ret, i;
+
+ for (i=0;i<ctdb->num_nodes;i++) {
+ uint32_t level;
+ ret = ctdb_get_debuglevel(ctdb, i, &level);
+ if (ret != 0) {
+ printf("Unable to get debuglevel response from node %u\n", i);
+ } else {
+ printf("Node %u is at debug level %u\n", i, level);
+ }
+ }
+ return 0;
+}
+
+/*
+ set debug level on a node
+ */
+static int control_debug(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ int ret;
+ uint32_t vnn, level;
+
+ if (argc < 2) {
+ usage();
+ }
+
+ vnn = strtoul(argv[0], NULL, 0);
+ level = strtoul(argv[1], NULL, 0);
+
+ ret = ctdb_set_debuglevel(ctdb, vnn, level);
+ if (ret != 0) {
+ printf("Unable to set debug level on node %u\n", vnn);
+ }
+ return 0;
+}
+
/*
main program
*/
ret = control_setvnnmap(ctdb, extra_argc-1, extra_argv+1);
} else if (strcmp(control, "ping") == 0) {
ret = control_ping(ctdb, extra_argc-1, extra_argv+1);
+ } else if (strcmp(control, "debug") == 0) {
+ ret = control_debug(ctdb, extra_argc-1, extra_argv+1);
+ } else if (strcmp(control, "debuglevel") == 0) {
+ ret = control_debuglevel(ctdb, extra_argc-1, extra_argv+1);
} else {
printf("Unknown control '%s'\n", control);
exit(1);