Beispiel #1
0
static void msg_pool_usage_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_s)
{
	const char *name = talloc_get_name(ptr);
	struct msg_pool_usage_state *state = (struct msg_pool_usage_state *)_s;

	if (is_ref) {
		sprintf_append(state->mem_ctx, &state->s, &state->len, &state->buflen,
			       "%*sreference to: %s\n", depth*4, "", name);
		return;
	}

	if (depth == 0) {
		sprintf_append(state->mem_ctx, &state->s, &state->len, &state->buflen,
			       "%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", 
			       (max_depth < 0 ? "full " :""), name,
			       (unsigned long)talloc_total_size(ptr),
			       (unsigned long)talloc_total_blocks(ptr));
		return;
	}

	sprintf_append(state->mem_ctx, &state->s, &state->len, &state->buflen,
		       "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", 
		       depth*4, "",
		       name,
		       (unsigned long)talloc_total_size(ptr),
		       (unsigned long)talloc_total_blocks(ptr),
		       talloc_reference_count(ptr));
}
Beispiel #2
0
void
check_leaks_push(TALLOC_CTX *ctx)
{
    struct size_snapshot *snapshot;

    snapshot = talloc(NULL, struct size_snapshot);
    snapshot->ctx = ctx;
    snapshot->bytes_allocated = talloc_total_size(ctx);
    DLIST_ADD(snapshot_stack, snapshot);
}
Beispiel #3
0
static void free_pipe_context(struct pipes_struct *p)
{
	data_blob_free(&p->out_data.frag);
	data_blob_free(&p->out_data.rdata);
	data_blob_free(&p->in_data.data);

	DEBUG(3, ("free_pipe_context: "
		"destroying talloc pool of size %lu\n",
		(unsigned long)talloc_total_size(p->mem_ctx)));
	talloc_free_children(p->mem_ctx);
}
Beispiel #4
0
static void free_pipe_context(pipes_struct *p)
{
	if (p->mem_ctx) {
		DEBUG(3,("free_pipe_context: destroying talloc pool of size "
			 "%lu\n", (unsigned long)talloc_total_size(p->mem_ctx) ));
		talloc_free_children(p->mem_ctx);
	} else {
		p->mem_ctx = talloc_init("pipe %s %p", p->name, p);
		if (p->mem_ctx == NULL) {
			p->fault_state = True;
		}
	}
}
Beispiel #5
0
/** Mark module instance data as being read only
 *
 * This still allows memory to be modified, but not allocated
 */
int module_instance_read_only(void *inst, char const *name)
{
	int	rcode;
	size_t	size;

	size = talloc_total_size(inst);
	rcode = talloc_set_memlimit(inst, size);
	if (rcode < 0) {
		ERROR("Failed setting memory limit for module %s", name);
	} else {
		DEBUG3("Memory limit for module %s is set to %zd bytes", name, size);
	}

	return rcode;
}
Beispiel #6
0
bool
_check_leaks(TALLOC_CTX *ctx, size_t bytes, const char *location)
{
    size_t bytes_allocated;

    bytes_allocated = talloc_total_size(ctx);
    if (bytes_allocated != bytes) {
        fprintf(stderr, "Leak report for %s:\n", location);
        talloc_report_full(ctx, stderr);
        _set_leak_err_msg("%s: memory leaks detected, %zd bytes still allocated",
                          location, bytes_allocated - bytes);
        return false;
    }

    return true;
}
Beispiel #7
0
/*
  process a control request
 */
static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb, 
				     struct ctdb_req_control_old *c,
				     TDB_DATA indata,
				     TDB_DATA *outdata, uint32_t srcnode,
				     const char **errormsg,
				     bool *async_reply)
{
	uint32_t opcode = c->opcode;
	uint64_t srvid = c->srvid;
	uint32_t client_id = c->client_id;

	switch (opcode) {
	case CTDB_CONTROL_PROCESS_EXISTS: {
		CHECK_CONTROL_DATA_SIZE(sizeof(pid_t));
		return ctdb_control_process_exists(ctdb, *(pid_t *)indata.dptr);
	}

	case CTDB_CONTROL_SET_DEBUG: {
		CHECK_CONTROL_DATA_SIZE(sizeof(int32_t));
		DEBUGLEVEL = *(int32_t *)indata.dptr;
		return 0;
	}

	case CTDB_CONTROL_GET_DEBUG: {
		CHECK_CONTROL_DATA_SIZE(0);
		outdata->dptr = (uint8_t *)&(DEBUGLEVEL);
		outdata->dsize = sizeof(DEBUGLEVEL);
		return 0;
	}

	case CTDB_CONTROL_STATISTICS: {
		CHECK_CONTROL_DATA_SIZE(0);
		ctdb->statistics.memory_used = talloc_total_size(NULL);
		ctdb->statistics.num_clients = ctdb->num_clients;
		ctdb->statistics.frozen = (ctdb_db_all_frozen(ctdb) ? 1 : 0);
		ctdb->statistics.recovering = (ctdb->recovery_mode == CTDB_RECOVERY_ACTIVE);
		ctdb->statistics.statistics_current_time = timeval_current();

		outdata->dptr = (uint8_t *)&ctdb->statistics;
		outdata->dsize = sizeof(ctdb->statistics);
		return 0;
	}

	case CTDB_CONTROL_GET_ALL_TUNABLES: {
		CHECK_CONTROL_DATA_SIZE(0);
		outdata->dptr = (uint8_t *)&ctdb->tunable;
		outdata->dsize = sizeof(ctdb->tunable);
		return 0;
	}

	case CTDB_CONTROL_DUMP_MEMORY: {
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_dump_memory(ctdb, outdata);
	}

	case CTDB_CONTROL_STATISTICS_RESET: {
		struct ctdb_db_context *ctdb_db;

		CHECK_CONTROL_DATA_SIZE(0);
		ZERO_STRUCT(ctdb->statistics);
		for (ctdb_db = ctdb->db_list;
		     ctdb_db != NULL;
		     ctdb_db = ctdb_db->next) {
			ctdb_db_statistics_reset(ctdb_db);
		}
		ctdb->statistics.statistics_start_time = timeval_current();
		return 0;
	}

	case CTDB_CONTROL_GETVNNMAP:
		return ctdb_control_getvnnmap(ctdb, opcode, indata, outdata);

	case CTDB_CONTROL_GET_DBMAP:
		return ctdb_control_getdbmap(ctdb, opcode, indata, outdata);

	case CTDB_CONTROL_GET_NODEMAPv4:
		return control_not_implemented("GET_NODEMAPv4", "GET_NODEMAP");

	case CTDB_CONTROL_GET_NODEMAP:
		return ctdb_control_getnodemap(ctdb, opcode, indata, outdata);

	case CTDB_CONTROL_GET_NODES_FILE:
		return ctdb_control_getnodesfile(ctdb, opcode, indata, outdata);

	case CTDB_CONTROL_RELOAD_NODES_FILE:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_reload_nodes_file(ctdb, opcode);

	case CTDB_CONTROL_SET_DB_STICKY: {
		uint32_t db_id;
		struct ctdb_db_context *ctdb_db;

		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;
		return ctdb_set_db_sticky(ctdb, ctdb_db);
	}

	case CTDB_CONTROL_SETVNNMAP:
		return ctdb_control_setvnnmap(ctdb, opcode, indata, outdata);

	case CTDB_CONTROL_PULL_DB: 
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_pulldb));
		return ctdb_control_pull_db(ctdb, indata, outdata);

	case CTDB_CONTROL_SET_DMASTER: 
		return control_not_implemented("SET_DMASTER", NULL);

	case CTDB_CONTROL_PUSH_DB:
		return ctdb_control_push_db(ctdb, indata);

	case CTDB_CONTROL_GET_RECMODE: {
		return ctdb->recovery_mode;
	}

	case CTDB_CONTROL_SET_RECMASTER: {
		return ctdb_control_set_recmaster(ctdb, opcode, indata);
	}

	case CTDB_CONTROL_GET_RECMASTER:
		return ctdb->recovery_master;

	case CTDB_CONTROL_GET_PID:
		return getpid();

	case CTDB_CONTROL_GET_PNN:
		return ctdb->pnn;

	case CTDB_CONTROL_PING:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb->num_clients;

	case CTDB_CONTROL_GET_RUNSTATE:
		CHECK_CONTROL_DATA_SIZE(0);
		outdata->dptr = (uint8_t *)&ctdb->runstate;
		outdata->dsize = sizeof(uint32_t);
		return 0;


	case CTDB_CONTROL_SET_DB_READONLY: {
		uint32_t db_id;
		struct ctdb_db_context *ctdb_db;

		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;
		return ctdb_set_db_readonly(ctdb, ctdb_db);
	}
	case CTDB_CONTROL_GET_DBNAME: {
		uint32_t db_id;
		struct ctdb_db_context *ctdb_db;

		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;
		outdata->dptr = discard_const(ctdb_db->db_name);
		outdata->dsize = strlen(ctdb_db->db_name)+1;
		return 0;
	}

	case CTDB_CONTROL_GETDBPATH: {
		uint32_t db_id;
		struct ctdb_db_context *ctdb_db;

		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;
		outdata->dptr = discard_const(ctdb_db->db_path);
		outdata->dsize = strlen(ctdb_db->db_path)+1;
		return 0;
	}

	case CTDB_CONTROL_DB_ATTACH:
	  return ctdb_control_db_attach(ctdb, indata, outdata, srvid, false, client_id, c, async_reply);

	case CTDB_CONTROL_DB_ATTACH_PERSISTENT:
	  return ctdb_control_db_attach(ctdb, indata, outdata, srvid, true, client_id, c, async_reply);

	case CTDB_CONTROL_SET_CALL:
		return control_not_implemented("SET_CALL", NULL);

	case CTDB_CONTROL_TRAVERSE_START:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_traverse_start));
		return ctdb_control_traverse_start(ctdb, indata, outdata, srcnode, client_id);

	case CTDB_CONTROL_TRAVERSE_START_EXT:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_traverse_start_ext));
		return ctdb_control_traverse_start_ext(ctdb, indata, outdata, srcnode, client_id);

	case CTDB_CONTROL_TRAVERSE_ALL:
		return ctdb_control_traverse_all(ctdb, indata, outdata);

	case CTDB_CONTROL_TRAVERSE_ALL_EXT:
		return ctdb_control_traverse_all_ext(ctdb, indata, outdata);

	case CTDB_CONTROL_TRAVERSE_DATA:
		return ctdb_control_traverse_data(ctdb, indata, outdata);

	case CTDB_CONTROL_TRAVERSE_KILL:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_traverse_start));
		return ctdb_control_traverse_kill(ctdb, indata, outdata, srcnode);

	case CTDB_CONTROL_REGISTER_SRVID:
		return daemon_register_message_handler(ctdb, client_id, srvid);

	case CTDB_CONTROL_DEREGISTER_SRVID:
		return daemon_deregister_message_handler(ctdb, client_id, srvid);

	case CTDB_CONTROL_CHECK_SRVIDS:
		return daemon_check_srvids(ctdb, indata, outdata);

	case CTDB_CONTROL_ENABLE_SEQNUM:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_ltdb_enable_seqnum(ctdb, *(uint32_t *)indata.dptr);

	case CTDB_CONTROL_UPDATE_SEQNUM:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));		
		return ctdb_ltdb_update_seqnum(ctdb, *(uint32_t *)indata.dptr, srcnode);

	case CTDB_CONTROL_FREEZE:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_freeze(ctdb, c, async_reply);

	case CTDB_CONTROL_THAW:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_thaw(ctdb, (uint32_t)c->srvid, true);

	case CTDB_CONTROL_SET_RECMODE:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));		
		return ctdb_control_set_recmode(ctdb, c, indata, async_reply, errormsg);

	case CTDB_CONTROL_GET_MONMODE: 
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_monitoring_mode(ctdb);
		
	case CTDB_CONTROL_ENABLE_MONITOR: 
		CHECK_CONTROL_DATA_SIZE(0);
		ctdb_enable_monitoring(ctdb);
		return 0;
	
	case CTDB_CONTROL_RUN_EVENTSCRIPTS: 
		return ctdb_run_eventscripts(ctdb, c, indata, async_reply);

	case CTDB_CONTROL_DISABLE_MONITOR: 
		CHECK_CONTROL_DATA_SIZE(0);
		ctdb_disable_monitoring(ctdb);
		return 0;

	case CTDB_CONTROL_SHUTDOWN:
		DEBUG(DEBUG_NOTICE,("Received SHUTDOWN command.\n"));
		ctdb_shutdown_sequence(ctdb, 0);
		/* In case above returns due to duplicate shutdown */
		return 0;

	case CTDB_CONTROL_TAKEOVER_IPv4:
		return control_not_implemented("TAKEOVER_IPv4", "TAKEOVER_IP");

	case CTDB_CONTROL_TAKEOVER_IP:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ip));
		return ctdb_control_takeover_ip(ctdb, c, indata, async_reply);

	case CTDB_CONTROL_RELEASE_IPv4:
		return control_not_implemented("RELEASE_IPv4", "RELEASE_IP");

	case CTDB_CONTROL_RELEASE_IP:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ip));
		return ctdb_control_release_ip(ctdb, c, indata, async_reply);

	case CTDB_CONTROL_IPREALLOCATED:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_ipreallocated(ctdb, c, async_reply);

	case CTDB_CONTROL_GET_PUBLIC_IPSv4:
		return control_not_implemented("GET_PUBLIC_IPSv4",
					       "GET_PUBLIC_IPS");

	case CTDB_CONTROL_GET_PUBLIC_IPS:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_get_public_ips(ctdb, c, outdata);

	case CTDB_CONTROL_TCP_CLIENT:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_connection));
		return ctdb_control_tcp_client(ctdb, client_id, indata);

	case CTDB_CONTROL_STARTUP: 
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_startup(ctdb, srcnode);

	case CTDB_CONTROL_TCP_ADD: 
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_connection));
		return ctdb_control_tcp_add(ctdb, indata, false);

	case CTDB_CONTROL_TCP_ADD_DELAYED_UPDATE: 
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_connection));
		return ctdb_control_tcp_add(ctdb, indata, true);

	case CTDB_CONTROL_TCP_REMOVE: 
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_connection));
		return ctdb_control_tcp_remove(ctdb, indata);

	case CTDB_CONTROL_SET_TUNABLE:
		return ctdb_control_set_tunable(ctdb, indata);

	case CTDB_CONTROL_GET_TUNABLE:
		return ctdb_control_get_tunable(ctdb, indata, outdata);

	case CTDB_CONTROL_LIST_TUNABLES:
		return ctdb_control_list_tunables(ctdb, outdata);

	case CTDB_CONTROL_MODIFY_FLAGS:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_node_flag_change));
		return ctdb_control_modflags(ctdb, indata);

	case CTDB_CONTROL_KILL_TCP: 
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_connection));
		return ctdb_control_kill_tcp(ctdb, indata);

	case CTDB_CONTROL_GET_TCP_TICKLE_LIST:
		CHECK_CONTROL_DATA_SIZE(sizeof(ctdb_sock_addr));
		return ctdb_control_get_tcp_tickle_list(ctdb, indata, outdata);

	case CTDB_CONTROL_SET_TCP_TICKLE_LIST:
		/* data size is verified in the called function */
		return ctdb_control_set_tcp_tickle_list(ctdb, indata);

	case CTDB_CONTROL_REGISTER_SERVER_ID: 
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_client_id));
		return ctdb_control_register_server_id(ctdb, client_id, indata);

	case CTDB_CONTROL_UNREGISTER_SERVER_ID: 
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_client_id));
		return ctdb_control_unregister_server_id(ctdb, indata);

	case CTDB_CONTROL_CHECK_SERVER_ID: 
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_client_id));
		return ctdb_control_check_server_id(ctdb, indata);

	case CTDB_CONTROL_GET_SERVER_ID_LIST:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_get_server_id_list(ctdb, outdata);

	case CTDB_CONTROL_PERSISTENT_STORE:
		return control_not_implemented("PERSISTENT_STORE", NULL);

	case CTDB_CONTROL_UPDATE_RECORD:
		return ctdb_control_update_record(ctdb, c, indata, async_reply);

	case CTDB_CONTROL_SEND_GRATUITOUS_ARP:
		return ctdb_control_send_gratious_arp(ctdb, indata);

	case CTDB_CONTROL_TRANSACTION_START:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_control_transaction_start(ctdb, *(uint32_t *)indata.dptr);

	case CTDB_CONTROL_TRANSACTION_COMMIT:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_control_transaction_commit(ctdb, *(uint32_t *)indata.dptr);

	case CTDB_CONTROL_WIPE_DATABASE:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_transdb));
		return ctdb_control_wipe_database(ctdb, indata);

	case CTDB_CONTROL_UPTIME:
		return ctdb_control_uptime(ctdb, outdata);

	case CTDB_CONTROL_START_RECOVERY:
		return ctdb_control_start_recovery(ctdb, c, async_reply);

	case CTDB_CONTROL_END_RECOVERY:
		return ctdb_control_end_recovery(ctdb, c, async_reply);

	case CTDB_CONTROL_TRY_DELETE_RECORDS:
		return ctdb_control_try_delete_records(ctdb, indata, outdata);

	case CTDB_CONTROL_ADD_PUBLIC_IP:
		return ctdb_control_add_public_address(ctdb, indata);

	case CTDB_CONTROL_DEL_PUBLIC_IP:
		return ctdb_control_del_public_address(ctdb, c, indata,
						       async_reply);

	case CTDB_CONTROL_GET_CAPABILITIES:
		return ctdb_control_get_capabilities(ctdb, outdata);

	case CTDB_CONTROL_START_PERSISTENT_UPDATE:
		return ctdb_control_start_persistent_update(ctdb, c, indata);

	case CTDB_CONTROL_CANCEL_PERSISTENT_UPDATE:
		return ctdb_control_cancel_persistent_update(ctdb, c, indata);

	case CTDB_CONTROL_TRANS2_COMMIT:
	case CTDB_CONTROL_TRANS2_COMMIT_RETRY:
		return control_not_implemented("TRANS2_COMMIT", "TRANS3_COMMIT");

	case CTDB_CONTROL_TRANS2_ERROR:
		return control_not_implemented("TRANS2_ERROR", NULL);

	case CTDB_CONTROL_TRANS2_FINISHED:
		return control_not_implemented("TRANS2_FINISHED", NULL);

	case CTDB_CONTROL_TRANS2_ACTIVE:
		return control_not_implemented("TRANS2_ACTIVE", NULL);

	case CTDB_CONTROL_TRANS3_COMMIT:
		return ctdb_control_trans3_commit(ctdb, c, indata, async_reply);

	case CTDB_CONTROL_RECD_PING:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_recd_ping(ctdb);

	case CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_control_get_event_script_status(ctdb, *(uint32_t *)indata.dptr, outdata);

	case CTDB_CONTROL_RECD_RECLOCK_LATENCY:
		CHECK_CONTROL_DATA_SIZE(sizeof(double));
		CTDB_UPDATE_RECLOCK_LATENCY(ctdb, "recd reclock", reclock.recd, *((double *)indata.dptr));
		return 0;
	case CTDB_CONTROL_GET_RECLOCK_FILE:
		CHECK_CONTROL_DATA_SIZE(0);
		if (ctdb->recovery_lock_file != NULL) {
			outdata->dptr  = discard_const(ctdb->recovery_lock_file);
			outdata->dsize = strlen(ctdb->recovery_lock_file) + 1;
		}
		return 0;
	case CTDB_CONTROL_SET_RECLOCK_FILE: {
		char *t;

		if (indata.dsize == 0) {
			TALLOC_FREE(ctdb->recovery_lock_file);
			return 0;
		}

		/* Return silent success if unchanged.  Recovery
		 * master updates all nodes on each recovery - we
		 * don't need the extra memory allocation or log
		 * message each time. */
		if (ctdb->recovery_lock_file != NULL &&
		    strcmp(discard_const(indata.dptr),
			   ctdb->recovery_lock_file) == 0) {
			return 0;
		}

		t = talloc_strdup(ctdb, discard_const(indata.dptr));
		if (t == NULL) {
			DEBUG(DEBUG_ERR, ("Out of memory in SET_RECLOCK_FILE\n"));
			return -1;
		}

		talloc_free(ctdb->recovery_lock_file);
		ctdb->recovery_lock_file = t;
		DEBUG(DEBUG_NOTICE, ("Updated recovery lock file to %s\n", t));

		return 0;
	}

	case CTDB_CONTROL_STOP_NODE:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_stop_node(ctdb);

	case CTDB_CONTROL_CONTINUE_NODE:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_continue_node(ctdb);

	case CTDB_CONTROL_SET_NATGWSTATE:
		return control_not_implemented("SET_NATGWSTATE", NULL);

	case CTDB_CONTROL_SET_LMASTERROLE: {
		uint32_t lmasterrole;

		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));		
		lmasterrole = *(uint32_t *)indata.dptr;
		if (lmasterrole == 0) {
			ctdb->capabilities &= ~CTDB_CAP_LMASTER;
		} else {
			ctdb->capabilities |= CTDB_CAP_LMASTER;
		}
		return 0;
	}

	case CTDB_CONTROL_SET_RECMASTERROLE: {
		uint32_t recmasterrole;

		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));		
		recmasterrole = *(uint32_t *)indata.dptr;
		if (recmasterrole == 0) {
			ctdb->capabilities &= ~CTDB_CAP_RECMASTER;
		} else {
			ctdb->capabilities |= CTDB_CAP_RECMASTER;
		}
		return 0;
	}

	case CTDB_CONTROL_ENABLE_SCRIPT:
		return ctdb_control_enable_script(ctdb, indata);

	case CTDB_CONTROL_DISABLE_SCRIPT:
		return ctdb_control_disable_script(ctdb, indata);

	case CTDB_CONTROL_SET_BAN_STATE:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_ban_state));
		return ctdb_control_set_ban_state(ctdb, indata);

	case CTDB_CONTROL_GET_BAN_STATE:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_get_ban_state(ctdb, outdata);

	case CTDB_CONTROL_SET_DB_PRIORITY:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_db_priority));
		return ctdb_control_set_db_priority(ctdb, indata, client_id);

	case CTDB_CONTROL_GET_DB_PRIORITY: {
		uint32_t db_id;
		struct ctdb_db_context *ctdb_db;

		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;
		return ctdb_db->priority;
	}

	case CTDB_CONTROL_TRANSACTION_CANCEL:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_transaction_cancel(ctdb);

	case CTDB_CONTROL_REGISTER_NOTIFY:
		return ctdb_control_register_notify(ctdb, client_id, indata);

	case CTDB_CONTROL_DEREGISTER_NOTIFY:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint64_t));
		return ctdb_control_deregister_notify(ctdb, client_id, indata);

	case CTDB_CONTROL_GET_LOG:
		return control_not_implemented("GET_LOG", NULL);

	case CTDB_CONTROL_CLEAR_LOG:
		return control_not_implemented("CLEAR_LOG", NULL);

	case CTDB_CONTROL_GET_DB_SEQNUM:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint64_t));
		return ctdb_control_get_db_seqnum(ctdb, indata, outdata);

	case CTDB_CONTROL_DB_SET_HEALTHY:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_control_db_set_healthy(ctdb, indata);

	case CTDB_CONTROL_DB_GET_HEALTH:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_control_db_get_health(ctdb, indata, outdata);

	case CTDB_CONTROL_GET_PUBLIC_IP_INFO:
		CHECK_CONTROL_DATA_SIZE(sizeof(ctdb_sock_addr));
		return ctdb_control_get_public_ip_info(ctdb, c, indata, outdata);

	case CTDB_CONTROL_GET_IFACES:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_get_ifaces(ctdb, c, outdata);

	case CTDB_CONTROL_SET_IFACE_LINK_STATE:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_iface));
		return ctdb_control_set_iface_link(ctdb, c, indata);

	case CTDB_CONTROL_GET_STAT_HISTORY:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_get_stat_history(ctdb, c, outdata);

	case CTDB_CONTROL_SCHEDULE_FOR_DELETION: {
		struct ctdb_control_schedule_for_deletion *d;
		size_t size = offsetof(struct ctdb_control_schedule_for_deletion, key);
		CHECK_CONTROL_MIN_DATA_SIZE(size);
		d = (struct ctdb_control_schedule_for_deletion *)indata.dptr;
		size += d->keylen;
		CHECK_CONTROL_DATA_SIZE(size);
		return ctdb_control_schedule_for_deletion(ctdb, indata);
	}
	case CTDB_CONTROL_GET_DB_STATISTICS:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_control_get_db_statistics(ctdb, *(uint32_t *)indata.dptr, outdata);

	case CTDB_CONTROL_RELOAD_PUBLIC_IPS:
		CHECK_CONTROL_DATA_SIZE(0);
		return ctdb_control_reload_public_ips(ctdb, c, async_reply);

	case CTDB_CONTROL_RECEIVE_RECORDS:
		return ctdb_control_receive_records(ctdb, indata, outdata);

	case CTDB_CONTROL_DB_DETACH:
		return ctdb_control_db_detach(ctdb, indata, client_id);

	case CTDB_CONTROL_DB_FREEZE:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_control_db_freeze(ctdb, c, *(uint32_t *)indata.dptr,
					      async_reply);

	case CTDB_CONTROL_DB_THAW:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_control_db_thaw(ctdb, *(uint32_t *)indata.dptr);

	case CTDB_CONTROL_DB_TRANSACTION_START:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_transdb));
		return ctdb_control_db_transaction_start(ctdb, indata);

	case CTDB_CONTROL_DB_TRANSACTION_COMMIT:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_transdb));
		return ctdb_control_db_transaction_commit(ctdb, indata);

	case CTDB_CONTROL_DB_TRANSACTION_CANCEL:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_control_db_transaction_cancel(ctdb, indata);

	case CTDB_CONTROL_DB_PULL:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_pulldb_ext));
		return ctdb_control_db_pull(ctdb, c, indata, outdata);

	case CTDB_CONTROL_DB_PUSH_START:
		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_pulldb_ext));
		return ctdb_control_db_push_start(ctdb, indata);

	case CTDB_CONTROL_DB_PUSH_CONFIRM:
		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
		return ctdb_control_db_push_confirm(ctdb, indata, outdata);

	default:
		DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
		return -1;
	}
}
Beispiel #8
0
/*
  main program
*/
int main(int argc, const char *argv[])
{
    int traverse_count;
    int i,j,k;
    trbt_tree_t *tree;
    uint32_t *data;
    uint32_t key[3];
    uint32_t key1[3] = {0,10,20};
    uint32_t key2[3] = {0,10,21};
    uint32_t key3[3] = {0,11,20};
    uint32_t key4[3] = {2,10,20};
    TALLOC_CTX *memctx;
    uint32_t **u32array;
    uint32_t checksum;

    /* testing trbt_insert32_callback for num_records */
    memctx   = talloc_new(NULL);
    assert(memctx != NULL);

    u32array = talloc_array(memctx, uint32_t *, num_records);
    assert(u32array != NULL);

    tree = trbt_create(memctx, 0);
    assert(tree != NULL);

    for (i=0; i<num_records; i++) {
        u32array[i]  = talloc(u32array, uint32_t);
        assert(u32array[i] != NULL);
        *u32array[i] = 0;
        trbt_insert32_callback(tree, i, callback, u32array[i]);
    }
    for (i=3; i<num_records; i++) {
        trbt_insert32_callback(tree, i, callback, NULL);
    }

    /* first 3 keys should have data == 1
     * the rest of the keys should have data == 2
     */
    for (i=0; i<num_records; i++) {
        data = trbt_lookup32(tree, i);
        if (i < 3) {
            assert(*data == 1);
        } else {
            assert(*data == 2);
        }
    }

    /* deleting key 2 */
    talloc_free(u32array[2]);

    /* deleting key 1 */
    talloc_free(u32array[1]);

    assert(talloc_total_size(memctx) == 212);

    /* freeing tree */
    talloc_free(memctx);


    printf("testing trbt_insertarray32_callback\n");
    memctx   = talloc_new(NULL);
    assert(memctx != NULL);

    tree = trbt_create(memctx, 0);
    assert(tree != NULL);

    u32array = talloc_array(memctx, uint32_t *, 4);
    assert(u32array != NULL);

    for (i=0; i<4; i++) {
        u32array[i]  = talloc(u32array, uint32_t);
        assert(u32array[i] != NULL);
        *u32array[i] = 0;
    }

    trbt_insertarray32_callback(tree, 3, key1, callback, u32array[0]);
    trbt_insertarray32_callback(tree, 3, key1, callback, u32array[0]);
    trbt_insertarray32_callback(tree, 3, key2, callback, u32array[1]);
    trbt_insertarray32_callback(tree, 3, key3, callback, u32array[2]);
    trbt_insertarray32_callback(tree, 3, key2, callback, u32array[1]);
    trbt_insertarray32_callback(tree, 3, key1, callback, u32array[0]);

    data = trbt_lookuparray32(tree, 3, key1);
    assert(data != NULL && *data == 3);
    data = trbt_lookuparray32(tree, 3, key2);
    assert(data != NULL && *data == 2);
    data = trbt_lookuparray32(tree, 3, key3);
    assert(data != NULL && *data == 1);
    data = trbt_lookuparray32(tree, 3, key4);
    assert(data == NULL);
    trbt_traversearray32(tree, 3, traverse, NULL);

    printf("\ndeleting key4\n");
    talloc_free(trbt_lookuparray32(tree, 3, key4));

    data = trbt_lookuparray32(tree, 3, key1);
    assert(data != NULL && *data == 3);
    data = trbt_lookuparray32(tree, 3, key2);
    assert(data != NULL && *data == 2);
    data = trbt_lookuparray32(tree, 3, key3);
    assert(data != NULL && *data == 1);
    data = trbt_lookuparray32(tree, 3, key4);
    assert(data == NULL);
    trbt_traversearray32(tree, 3, traverse, NULL);

    printf("\ndeleting key2\n");
    talloc_free(trbt_lookuparray32(tree, 3, key2));

    data = trbt_lookuparray32(tree, 3, key1);
    assert(data != NULL && *data == 3);
    data = trbt_lookuparray32(tree, 3, key2);
    assert(data == NULL);
    data = trbt_lookuparray32(tree, 3, key3);
    assert(data != NULL && *data == 1);
    data = trbt_lookuparray32(tree, 3, key4);
    assert(data == NULL);
    trbt_traversearray32(tree, 3, traverse, NULL);

    printf("\ndeleting key3\n");
    talloc_free(trbt_lookuparray32(tree, 3, key3));

    data = trbt_lookuparray32(tree, 3, key1);
    assert(data != NULL && *data == 3);
    data = trbt_lookuparray32(tree, 3, key2);
    assert(data == NULL);
    data = trbt_lookuparray32(tree, 3, key3);
    assert(data == NULL);
    data = trbt_lookuparray32(tree, 3, key4);
    assert(data == NULL);
    trbt_traversearray32(tree, 3, traverse, NULL);

    printf("\ndeleting key1\n");
    talloc_free(trbt_lookuparray32(tree, 3, key1));

    data = trbt_lookuparray32(tree, 3, key1);
    assert(data == NULL);
    data = trbt_lookuparray32(tree, 3, key2);
    assert(data == NULL);
    data = trbt_lookuparray32(tree, 3, key3);
    assert(data == NULL);
    data = trbt_lookuparray32(tree, 3, key4);
    assert(data == NULL);
    trbt_traversearray32(tree, 3, traverse, NULL);

    talloc_free(tree);
    talloc_free(memctx);


    printf("\nrun random insert and delete for 60 seconds\n");
    memctx   = talloc_new(NULL);
    assert(memctx != NULL);

    tree = trbt_create(memctx, 0);
    assert(tree != NULL);

    i=0;
    start_timer();
    checksum = 0;
    /* add and delete nodes from a 3 level tree fro 60 seconds.
       each time a node is added or deleted, traverse the tree and
       compute a checksum over the data stored in the tree and compare this
       with a checksum we keep which contains what the checksum should be
     */
    while(end_timer() < 60.0) {
        char *str;

        i++;
        key[0]=random()%10;
        key[1]=random()%10;
        key[2]=random()%10;

        if (random()%2) {
            if (trbt_lookuparray32(tree, 3, key) == NULL) {
                /* this node does not yet exist, add it to the
                   tree and update the checksum
                 */
                str=talloc_asprintf(memctx, "%d.%d.%d", key[0],key[1],key[2]);
                trbt_insertarray32_callback(tree, 3, key, random_add, str);
                checksum += key[0]*100+key[1]*10+key[2];
            }
        } else {
            if ((str=trbt_lookuparray32(tree, 3, key)) != NULL) {
                /* this node does exist in  the tree, delete
                   it and update the checksum accordingly
                 */
                talloc_free(str);
                checksum -= key[0]*100+key[1]*10+key[2];
            }
        }
        /* traverse all nodes in the tree and calculate the checksum
           it better match the one we keep track of in
           'checksum'
        */
        calc_checksum = 0;
        trbt_traversearray32(tree, 3, traverse_checksum, NULL);
        assert(checksum == calc_checksum);
    }

    /*
    printf("\niterations passed:%d\n", i);
    trbt_traversearray32(tree, 3, random_traverse, NULL);
    printf("\n");
    printf("first node: %s\n", (char *)trbt_findfirstarray32(tree, 3));
    */

    traverse_count = 0;
    trbt_traversearray32(tree, 3, count_traverse, &traverse_count);
    assert(traverse_count > 0);

    traverse_count = 0;
    trbt_traversearray32(tree, 3, count_traverse_abort, &traverse_count);
    assert(traverse_count == 1);

    printf("\ndeleting all entries\n");
    for(i=0; i<10; i++) {
        for(j=0; j<10; j++) {
            for(k=0; k<10; k++) {
                key[0]=i;
                key[1]=j;
                key[2]=k;
                talloc_free(trbt_lookuparray32(tree, 3, key));
            }
        }
    }
    trbt_traversearray32(tree, 3, random_traverse, NULL);

    assert(talloc_total_size(memctx) == 16);

    return 0;
}
Beispiel #9
0
void debugwin_redraw(int clip_x0, int clip_y0, int clip_x1, int clip_y1)
{
	char s[40];
	int y, x, w;
	unsigned int users;
	unsigned int talloc_size;
	unsigned int size = 0;
	struct content *content;
	struct content_user *user;
//	bool want_knockout;

	/* Set up font style for headings */
	fstyle.family = PLOT_FONT_FAMILY_SANS_SERIF;
	fstyle.size = 12 * FONT_SIZE_SCALE;
	fstyle.weight = 900;
	fstyle.flags = 0;
	fstyle.background = 0xff4400;
	fstyle.foreground = 0xffffff;

	/* Set up plot style for heading cell backgrounds */
	style.stroke_type = PLOT_OP_TYPE_NONE;
	style.stroke_width = 0;
	style.stroke_colour = 0x000000;
	style.fill_type = PLOT_OP_TYPE_SOLID;
	style.fill_colour = 0xff4400;

	/* Column widths */
	int w_type = 50;
	int w_fresh = 40;
	int w_mime_type = 80;
	int w_users = 40;
	int w_status = 60;
	int w_size = 200;
	int w_url = DEBUGWIN_WINDOW_WIDTH - w_size - 1 - w_status - 1 -
			w_users - 1 - w_mime_type - 1 - w_fresh - 1 -
			w_type - 1;

//	want_knockout = plot.option_knockout;
//	if (want_knockout)
//		knockout_plot_start(&plot);

	/* Render column heading cells */
	y = 0;
	x = 0;
	w = w_url;
	debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
			"url", DEBUGWIN_CENTRE, clip_x0, clip_y0,
			clip_x1, clip_y1);
	x += w + 1;
	w = w_type;
	debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
			"type", DEBUGWIN_CENTRE, clip_x0, clip_y0,
			clip_x1, clip_y1);
	x += w + 1;
	w = w_fresh;
	debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
			"fresh", DEBUGWIN_CENTRE, clip_x0, clip_y0,
			clip_x1, clip_y1);
	x += w + 1;
	w = w_mime_type;
	debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
			"mime-type", DEBUGWIN_CENTRE, clip_x0, clip_y0,
			clip_x1, clip_y1);
	x += w + 1;
	w = w_users;
	debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
			"users", DEBUGWIN_CENTRE, clip_x0, clip_y0,
			clip_x1, clip_y1);
	x += w + 1;
	w = w_status;
	debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
			"status", DEBUGWIN_CENTRE, clip_x0, clip_y0,
			clip_x1, clip_y1);
	x += w + 1;
	w = w_size;
	debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
			"size", DEBUGWIN_CENTRE, clip_x0, clip_y0,
			clip_x1, clip_y1);

	/* Move down to next row */
	y += DEBUGWIN_TEXT_HEIGHT + 2 * DEBUGWIN_CELL_PADDING + 1;

	/* Change style for non-heading cells */
	fstyle.weight = 400;
	fstyle.background = 0xffaa88;
	fstyle.foreground = 0x000000;
	style.fill_colour = 0xffaa88;

	/* Create a row in the table for each content */
	for (content = content_list; content; content = content->next) {
		/* Create URL cell */
		x = 0;
		w = w_url;
		debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
				content->url, DEBUGWIN_RIGHT, clip_x0, clip_y0,
				clip_x1, clip_y1);
		/* Create Type cell */
		x += w + 1;
		w = w_type;
		debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
				content_type_name[content->type], DEBUGWIN_LEFT,
				clip_x0, clip_y0, clip_x1, clip_y1);
		/* Create cell for showing wheher content is fresh */
		x += w + 1;
		w = w_fresh;
		debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
				content->fresh ? "yes" : "no", DEBUGWIN_LEFT,
				clip_x0, clip_y0, clip_x1, clip_y1);
		/* Create Mime-type cell */
		x += w + 1;
		w = w_mime_type;
		debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
				content->mime_type, DEBUGWIN_LEFT,
				clip_x0, clip_y0, clip_x1, clip_y1);
		/* Create Users cell */
		users = 0;
		/* Count content users */
		for (user = content->user_list->next; user; user = user->next)
			users++;
		snprintf(s, sizeof s, "%u", users);
		x += w + 1;
		w = w_users;
		debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
				s, DEBUGWIN_RIGHT, clip_x0, clip_y0,
				clip_x1, clip_y1);
		/* Create Status cell */
		x += w + 1;
		w = w_status;
		debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
				content_status_name[content->status],
				DEBUGWIN_LEFT, clip_x0, clip_y0,
				clip_x1, clip_y1);
		/* Create Size cell */
		talloc_size = talloc_total_size(content);
		snprintf(s, sizeof s, "%u+%u= %u", content->size, talloc_size,
				content->size + talloc_size);
		x += w + 1;
		w = w_size;
		debugwin_render_cell(x, y, w, DEBUGWIN_TEXT_HEIGHT,
				s, DEBUGWIN_RIGHT, clip_x0, clip_y0,
				clip_x1, clip_y1);

		/* Keep running total of size used */
		size += content->size + talloc_size;

		/* Move down for next row */
		y += DEBUGWIN_TEXT_HEIGHT + 2 * DEBUGWIN_CELL_PADDING + 1;
	}
	snprintf(s, sizeof s, "%u", size);

	/* Show total size */
	debugwin_render_cell(DEBUGWIN_WINDOW_WIDTH - w_size, y,
			w_size, DEBUGWIN_TEXT_HEIGHT, s, DEBUGWIN_RIGHT,
			clip_x0, clip_y0, clip_x1, clip_y1);

	/* Heading cell for total size */
	fstyle.weight = 900;
	fstyle.background = 0xff4400;
	fstyle.foreground = 0xffffff;
	style.fill_colour = 0xff4400;
	debugwin_render_cell(0, y,
			DEBUGWIN_WINDOW_WIDTH - w_size - 1,
			DEBUGWIN_TEXT_HEIGHT, "total size:", DEBUGWIN_RIGHT,
			clip_x0, clip_y0, clip_x1, clip_y1);

//	if (want_knockout)
//		knockout_plot_end();
}
Beispiel #10
0
/*
  process a control request
 */
static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                                     struct ctdb_req_control *c,
                                     TDB_DATA indata,
                                     TDB_DATA *outdata, uint32_t srcnode,
                                     const char **errormsg,
                                     bool *async_reply)
{
    uint32_t opcode = c->opcode;
    uint64_t srvid = c->srvid;
    uint32_t client_id = c->client_id;

    switch (opcode) {
    case CTDB_CONTROL_PROCESS_EXISTS: {
        CHECK_CONTROL_DATA_SIZE(sizeof(pid_t));
        return ctdb_control_process_exists(ctdb, *(pid_t *)indata.dptr);
    }

    case CTDB_CONTROL_SET_DEBUG: {
        CHECK_CONTROL_DATA_SIZE(sizeof(int32_t));
        LogLevel = *(int32_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_STATISTICS: {
        int i;
        CHECK_CONTROL_DATA_SIZE(0);
        ctdb->statistics.memory_used = talloc_total_size(NULL);
        ctdb->statistics.frozen = 0;
        for (i=1; i<= NUM_DB_PRIORITIES; i++) {
            if (ctdb->freeze_mode[i] == CTDB_FREEZE_FROZEN) {
                ctdb->statistics.frozen = 1;
            }
        }
        ctdb->statistics.recovering = (ctdb->recovery_mode == CTDB_RECOVERY_ACTIVE);
        outdata->dptr = (uint8_t *)&ctdb->statistics;
        outdata->dsize = sizeof(ctdb->statistics);
        return 0;
    }

    case CTDB_CONTROL_GET_ALL_TUNABLES: {
        CHECK_CONTROL_DATA_SIZE(0);
        outdata->dptr = (uint8_t *)&ctdb->tunable;
        outdata->dsize = sizeof(ctdb->tunable);
        return 0;
    }

    case CTDB_CONTROL_DUMP_MEMORY: {
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_dump_memory(ctdb, outdata);
    }

    case CTDB_CONTROL_STATISTICS_RESET: {
        CHECK_CONTROL_DATA_SIZE(0);
        ZERO_STRUCT(ctdb->statistics);
        return 0;
    }

    case CTDB_CONTROL_GETVNNMAP:
        return ctdb_control_getvnnmap(ctdb, opcode, indata, outdata);

    case CTDB_CONTROL_GET_DBMAP:
        return ctdb_control_getdbmap(ctdb, opcode, indata, outdata);

    case CTDB_CONTROL_GET_NODEMAPv4:
        return ctdb_control_getnodemapv4(ctdb, opcode, indata, outdata);

    case CTDB_CONTROL_GET_NODEMAP:
        return ctdb_control_getnodemap(ctdb, opcode, indata, outdata);

    case CTDB_CONTROL_RELOAD_NODES_FILE:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_reload_nodes_file(ctdb, opcode);

    case CTDB_CONTROL_SETVNNMAP:
        return ctdb_control_setvnnmap(ctdb, opcode, indata, outdata);

    case CTDB_CONTROL_PULL_DB:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_pulldb));
        return ctdb_control_pull_db(ctdb, indata, outdata);

    case CTDB_CONTROL_SET_DMASTER:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_set_dmaster));
        return ctdb_control_set_dmaster(ctdb, indata);

    case CTDB_CONTROL_PUSH_DB:
        return ctdb_control_push_db(ctdb, indata);

    case CTDB_CONTROL_GET_RECMODE: {
        return ctdb->recovery_mode;
    }

    case CTDB_CONTROL_SET_RECMASTER: {
        return ctdb_control_set_recmaster(ctdb, opcode, indata);
    }

    case CTDB_CONTROL_GET_RECMASTER:
        return ctdb->recovery_master;

    case CTDB_CONTROL_GET_PID:
        return getpid();

    case CTDB_CONTROL_GET_PNN:
        return ctdb->pnn;

    case CTDB_CONTROL_PING:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb->statistics.num_clients;

    case CTDB_CONTROL_GET_DBNAME: {
        uint32_t db_id;
        struct ctdb_db_context *ctdb_db;

        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;
        outdata->dptr = discard_const(ctdb_db->db_name);
        outdata->dsize = strlen(ctdb_db->db_name)+1;
        return 0;
    }

    case CTDB_CONTROL_GETDBPATH: {
        uint32_t db_id;
        struct ctdb_db_context *ctdb_db;

        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;
        outdata->dptr = discard_const(ctdb_db->db_path);
        outdata->dsize = strlen(ctdb_db->db_path)+1;
        return 0;
    }

    case CTDB_CONTROL_DB_ATTACH:
        return ctdb_control_db_attach(ctdb, indata, outdata, srvid, false);

    case CTDB_CONTROL_DB_ATTACH_PERSISTENT:
        return ctdb_control_db_attach(ctdb, indata, outdata, srvid, true);

    case CTDB_CONTROL_SET_CALL: {
        struct ctdb_control_set_call *sc =
            (struct ctdb_control_set_call *)indata.dptr;
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_set_call));
        return ctdb_daemon_set_call(ctdb, sc->db_id, sc->fn, sc->id);
    }

    case CTDB_CONTROL_TRAVERSE_START:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_traverse_start));
        return ctdb_control_traverse_start(ctdb, indata, outdata, srcnode, client_id);

    case CTDB_CONTROL_TRAVERSE_ALL:
        return ctdb_control_traverse_all(ctdb, indata, outdata);

    case CTDB_CONTROL_TRAVERSE_DATA:
        return ctdb_control_traverse_data(ctdb, indata, outdata);

    case CTDB_CONTROL_TRAVERSE_KILL:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_traverse_start));
        return ctdb_control_traverse_kill(ctdb, indata, outdata, srcnode);

    case CTDB_CONTROL_REGISTER_SRVID:
        return daemon_register_message_handler(ctdb, client_id, srvid);

    case CTDB_CONTROL_DEREGISTER_SRVID:
        return daemon_deregister_message_handler(ctdb, client_id, srvid);

    case CTDB_CONTROL_ENABLE_SEQNUM:
        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        return ctdb_ltdb_enable_seqnum(ctdb, *(uint32_t *)indata.dptr);

    case CTDB_CONTROL_UPDATE_SEQNUM:
        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        return ctdb_ltdb_update_seqnum(ctdb, *(uint32_t *)indata.dptr, srcnode);

    case CTDB_CONTROL_FREEZE:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_freeze(ctdb, c, async_reply);

    case CTDB_CONTROL_THAW:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_thaw(ctdb, (uint32_t)c->srvid);

    case CTDB_CONTROL_SET_RECMODE:
        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        return ctdb_control_set_recmode(ctdb, c, indata, async_reply, errormsg);

    case CTDB_CONTROL_GET_MONMODE:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_monitoring_mode(ctdb);

    case CTDB_CONTROL_ENABLE_MONITOR:
        CHECK_CONTROL_DATA_SIZE(0);
        ctdb_enable_monitoring(ctdb);
        return 0;

    case CTDB_CONTROL_RUN_EVENTSCRIPTS:
        return ctdb_run_eventscripts(ctdb, c, indata, async_reply);

    case CTDB_CONTROL_DISABLE_MONITOR:
        CHECK_CONTROL_DATA_SIZE(0);
        ctdb_disable_monitoring(ctdb);
        return 0;

    case CTDB_CONTROL_SHUTDOWN:
        ctdb_stop_recoverd(ctdb);
        ctdb_stop_keepalive(ctdb);
        ctdb_stop_monitoring(ctdb);
        ctdb_release_all_ips(ctdb);
        if (ctdb->methods != NULL) {
            ctdb->methods->shutdown(ctdb);
        }
        ctdb_event_script(ctdb, CTDB_EVENT_SHUTDOWN);
        DEBUG(DEBUG_NOTICE,("Received SHUTDOWN command. Stopping CTDB daemon.\n"));
        exit(0);

    case CTDB_CONTROL_TAKEOVER_IPv4:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ipv4));
        return ctdb_control_takeover_ipv4(ctdb, c, indata, async_reply);

    case CTDB_CONTROL_TAKEOVER_IP:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ip));
        return ctdb_control_takeover_ip(ctdb, c, indata, async_reply);

    case CTDB_CONTROL_RELEASE_IPv4:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ipv4));
        return ctdb_control_release_ipv4(ctdb, c, indata, async_reply);

    case CTDB_CONTROL_RELEASE_IP:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ip));
        return ctdb_control_release_ip(ctdb, c, indata, async_reply);

    case CTDB_CONTROL_GET_PUBLIC_IPSv4:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_get_public_ipsv4(ctdb, c, outdata);

    case CTDB_CONTROL_GET_PUBLIC_IPS:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_get_public_ips(ctdb, c, outdata);

    case CTDB_CONTROL_TCP_CLIENT:
        return ctdb_control_tcp_client(ctdb, client_id, indata);

    case CTDB_CONTROL_STARTUP:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_startup(ctdb, srcnode);

    case CTDB_CONTROL_TCP_ADD:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_tcp_vnn));
        return ctdb_control_tcp_add(ctdb, indata);

    case CTDB_CONTROL_SET_TUNABLE:
        return ctdb_control_set_tunable(ctdb, indata);

    case CTDB_CONTROL_GET_TUNABLE:
        return ctdb_control_get_tunable(ctdb, indata, outdata);

    case CTDB_CONTROL_LIST_TUNABLES:
        return ctdb_control_list_tunables(ctdb, outdata);

    case CTDB_CONTROL_MODIFY_FLAGS:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_node_flag_change));
        return ctdb_control_modflags(ctdb, indata);

    case CTDB_CONTROL_KILL_TCP:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_killtcp));
        return ctdb_control_kill_tcp(ctdb, indata);

    case CTDB_CONTROL_GET_TCP_TICKLE_LIST:
        CHECK_CONTROL_DATA_SIZE(sizeof(ctdb_sock_addr));
        return ctdb_control_get_tcp_tickle_list(ctdb, indata, outdata);

    case CTDB_CONTROL_SET_TCP_TICKLE_LIST:
        /* data size is verified in the called function */
        return ctdb_control_set_tcp_tickle_list(ctdb, indata);

    case CTDB_CONTROL_REGISTER_SERVER_ID:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_server_id));
        return ctdb_control_register_server_id(ctdb, client_id, indata);

    case CTDB_CONTROL_UNREGISTER_SERVER_ID:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_server_id));
        return ctdb_control_unregister_server_id(ctdb, indata);

    case CTDB_CONTROL_CHECK_SERVER_ID:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_server_id));
        return ctdb_control_check_server_id(ctdb, indata);

    case CTDB_CONTROL_GET_SERVER_ID_LIST:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_get_server_id_list(ctdb, outdata);

    case CTDB_CONTROL_PERSISTENT_STORE:
        return ctdb_control_persistent_store(ctdb, c, indata, async_reply);

    case CTDB_CONTROL_UPDATE_RECORD:
        return ctdb_control_update_record(ctdb, c, indata, async_reply);

    case CTDB_CONTROL_SEND_GRATIOUS_ARP:
        return ctdb_control_send_gratious_arp(ctdb, indata);

    case CTDB_CONTROL_TRANSACTION_START:
        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        return ctdb_control_transaction_start(ctdb, *(uint32_t *)indata.dptr);

    case CTDB_CONTROL_TRANSACTION_COMMIT:
        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        return ctdb_control_transaction_commit(ctdb, *(uint32_t *)indata.dptr);

    case CTDB_CONTROL_WIPE_DATABASE:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_wipe_database));
        return ctdb_control_wipe_database(ctdb, indata);

    case CTDB_CONTROL_UPTIME:
        return ctdb_control_uptime(ctdb, outdata);

    case CTDB_CONTROL_START_RECOVERY:
        return ctdb_control_start_recovery(ctdb, c, async_reply);

    case CTDB_CONTROL_END_RECOVERY:
        return ctdb_control_end_recovery(ctdb, c, async_reply);

    case CTDB_CONTROL_TRY_DELETE_RECORDS:
        return ctdb_control_try_delete_records(ctdb, indata, outdata);

    case CTDB_CONTROL_ADD_PUBLIC_IP:
        return ctdb_control_add_public_address(ctdb, indata);

    case CTDB_CONTROL_DEL_PUBLIC_IP:
        return ctdb_control_del_public_address(ctdb, indata);

    case CTDB_CONTROL_GET_CAPABILITIES:
        return ctdb_control_get_capabilities(ctdb, outdata);

    case CTDB_CONTROL_START_PERSISTENT_UPDATE:
        return ctdb_control_start_persistent_update(ctdb, c, indata);

    case CTDB_CONTROL_CANCEL_PERSISTENT_UPDATE:
        return ctdb_control_cancel_persistent_update(ctdb, c, indata);

    case CTDB_CONTROL_TRANS2_COMMIT:
    case CTDB_CONTROL_TRANS2_COMMIT_RETRY:
        return ctdb_control_trans2_commit(ctdb, c, indata, async_reply);

    case CTDB_CONTROL_TRANS2_ERROR:
        return ctdb_control_trans2_error(ctdb, c);

    case CTDB_CONTROL_TRANS2_FINISHED:
        return ctdb_control_trans2_finished(ctdb, c);

    case CTDB_CONTROL_TRANS2_ACTIVE:
        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        return ctdb_control_trans2_active(ctdb, c, *(uint32_t *)indata.dptr);

    case CTDB_CONTROL_TRANS3_COMMIT:
        return ctdb_control_trans3_commit(ctdb, c, indata, async_reply);

    case CTDB_CONTROL_RECD_PING:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_recd_ping(ctdb);

    case CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS:
        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        return ctdb_control_get_event_script_status(ctdb, *(uint32_t *)indata.dptr, outdata);

    case CTDB_CONTROL_RECD_RECLOCK_LATENCY:
        CHECK_CONTROL_DATA_SIZE(sizeof(double));
        ctdb_reclock_latency(ctdb, "recd reclock", &ctdb->statistics.reclock.recd, *((double *)indata.dptr));
        return 0;
    case CTDB_CONTROL_GET_RECLOCK_FILE:
        CHECK_CONTROL_DATA_SIZE(0);
        if (ctdb->recovery_lock_file != NULL) {
            outdata->dptr  = discard_const(ctdb->recovery_lock_file);
            outdata->dsize = strlen(ctdb->recovery_lock_file) + 1;
        }
        return 0;
    case CTDB_CONTROL_SET_RECLOCK_FILE:
        ctdb->tunable.verify_recovery_lock = 0;
        if (ctdb->recovery_lock_file != NULL) {
            talloc_free(ctdb->recovery_lock_file);
            ctdb->recovery_lock_file = NULL;
        }
        if (indata.dsize > 0) {
            ctdb->recovery_lock_file = talloc_strdup(ctdb, discard_const(indata.dptr));
            ctdb->tunable.verify_recovery_lock = 1;
        }
        return 0;

    case CTDB_CONTROL_STOP_NODE:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_stop_node(ctdb, c, async_reply);

    case CTDB_CONTROL_CONTINUE_NODE:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_continue_node(ctdb);

    case CTDB_CONTROL_SET_NATGWSTATE: {
        uint32_t natgwstate;

        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        natgwstate = *(uint32_t *)indata.dptr;
        if (natgwstate == 0) {
            ctdb->capabilities &= ~CTDB_CAP_NATGW;
        } else {
            ctdb->capabilities |= CTDB_CAP_NATGW;
        }
        return 0;
    }

    case CTDB_CONTROL_SET_LMASTERROLE: {
        uint32_t lmasterrole;

        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        lmasterrole = *(uint32_t *)indata.dptr;
        if (lmasterrole == 0) {
            ctdb->capabilities &= ~CTDB_CAP_LMASTER;
        } else {
            ctdb->capabilities |= CTDB_CAP_LMASTER;
        }
        return 0;
    }

    case CTDB_CONTROL_SET_RECMASTERROLE: {
        uint32_t recmasterrole;

        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        recmasterrole = *(uint32_t *)indata.dptr;
        if (recmasterrole == 0) {
            ctdb->capabilities &= ~CTDB_CAP_RECMASTER;
        } else {
            ctdb->capabilities |= CTDB_CAP_RECMASTER;
        }
        return 0;
    }

    case CTDB_CONTROL_ENABLE_SCRIPT:
        return ctdb_control_enable_script(ctdb, indata);

    case CTDB_CONTROL_DISABLE_SCRIPT:
        return ctdb_control_disable_script(ctdb, indata);

    case CTDB_CONTROL_SET_BAN_STATE:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_ban_time));
        return ctdb_control_set_ban_state(ctdb, indata);

    case CTDB_CONTROL_GET_BAN_STATE:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_get_ban_state(ctdb, outdata);

    case CTDB_CONTROL_SET_DB_PRIORITY:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_db_priority));
        return ctdb_control_set_db_priority(ctdb, indata);

    case CTDB_CONTROL_GET_DB_PRIORITY: {
        uint32_t db_id;
        struct ctdb_db_context *ctdb_db;

        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;
        return ctdb_db->priority;
    }

    case CTDB_CONTROL_TRANSACTION_CANCEL:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_transaction_cancel(ctdb);

    case CTDB_CONTROL_REGISTER_NOTIFY:
        return ctdb_control_register_notify(ctdb, client_id, indata);

    case CTDB_CONTROL_DEREGISTER_NOTIFY:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_client_notify_deregister));
        return ctdb_control_deregister_notify(ctdb, client_id, indata);

    case CTDB_CONTROL_GET_LOG:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_get_log_addr));
        return ctdb_control_get_log(ctdb, indata);

    case CTDB_CONTROL_CLEAR_LOG:
        return ctdb_control_clear_log(ctdb);

    case CTDB_CONTROL_GET_DB_SEQNUM:
        CHECK_CONTROL_DATA_SIZE(sizeof(uint64_t));
        return ctdb_control_get_db_seqnum(ctdb, indata, outdata);

    case CTDB_CONTROL_DB_SET_HEALTHY:
        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        return ctdb_control_db_set_healthy(ctdb, indata);

    case CTDB_CONTROL_DB_GET_HEALTH:
        CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
        return ctdb_control_db_get_health(ctdb, indata, outdata);

    case CTDB_CONTROL_GET_PUBLIC_IP_INFO:
        CHECK_CONTROL_DATA_SIZE(sizeof(ctdb_sock_addr));
        return ctdb_control_get_public_ip_info(ctdb, c, indata, outdata);

    case CTDB_CONTROL_GET_IFACES:
        CHECK_CONTROL_DATA_SIZE(0);
        return ctdb_control_get_ifaces(ctdb, c, outdata);

    case CTDB_CONTROL_SET_IFACE_LINK_STATE:
        CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_iface_info));
        return ctdb_control_set_iface_link(ctdb, c, indata);

    default:
        DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
        return -1;
    }
}