/*
a tcp connection description
+ also used by tcp_add and tcp_remove controls
*/
struct ctdb_tcp_connection {
ctdb_sock_addr src_addr;
uint32_t traverse_timeout;
uint32_t keepalive_interval;
uint32_t keepalive_limit;
- uint32_t max_lacount;
uint32_t recover_timeout;
uint32_t recover_interval;
uint32_t election_timeout;
uint32_t deterministic_public_ips;
uint32_t reclock_ping_period;
uint32_t no_ip_failback;
+ uint32_t disable_ip_failover;
uint32_t verbose_memory_names;
uint32_t recd_ping_timeout;
uint32_t recd_ping_failcount;
uint32_t max_queue_depth_drop_msg;
uint32_t use_status_events_for_monitoring;
uint32_t allow_unhealthy_db_read;
+ uint32_t stat_history_interval;
+ uint32_t deferred_attach_timeout;
};
/*
const char *name; /* for debug messages */
void *private_data; /* private to transport */
uint32_t pnn;
-#define NODE_FLAGS_DISCONNECTED 0x00000001 /* node isn't connected */
-#define NODE_FLAGS_UNHEALTHY 0x00000002 /* monitoring says node is unhealthy */
-#define NODE_FLAGS_PERMANENTLY_DISABLED 0x00000004 /* administrator has disabled node */
-#define NODE_FLAGS_BANNED 0x00000008 /* recovery daemon has banned the node */
-#define NODE_FLAGS_DELETED 0x00000010 /* this node has been deleted */
-#define NODE_FLAGS_STOPPED 0x00000020 /* this node has been stopped */
-#define NODE_FLAGS_DISABLED (NODE_FLAGS_UNHEALTHY|NODE_FLAGS_PERMANENTLY_DISABLED)
-#define NODE_FLAGS_INACTIVE (NODE_FLAGS_DELETED|NODE_FLAGS_DISCONNECTED|NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)
uint32_t flags;
/* used by the dead node monitoring */
struct ctdb_queue *queue;
};
-/*
- ctdb status information
- */
-struct ctdb_statistics {
- uint32_t num_clients;
- uint32_t frozen;
- uint32_t recovering;
- uint32_t client_packets_sent;
- uint32_t client_packets_recv;
- uint32_t node_packets_sent;
- uint32_t node_packets_recv;
- uint32_t keepalive_packets_sent;
- uint32_t keepalive_packets_recv;
- struct {
- uint32_t req_call;
- uint32_t reply_call;
- uint32_t req_dmaster;
- uint32_t reply_dmaster;
- uint32_t reply_error;
- uint32_t req_message;
- uint32_t req_control;
- uint32_t reply_control;
- } node;
- struct {
- uint32_t req_call;
- uint32_t req_message;
- uint32_t req_control;
- } client;
- struct {
- uint32_t call;
- uint32_t control;
- uint32_t traverse;
- } timeouts;
- struct {
- double ctdbd;
- double recd;
- } reclock;
- uint32_t total_calls;
- uint32_t pending_calls;
- uint32_t lockwait_calls;
- uint32_t pending_lockwait_calls;
- uint32_t childwrite_calls;
- uint32_t pending_childwrite_calls;
- uint32_t memory_used;
- uint32_t __last_counter; /* hack for control_statistics_all */
- uint32_t max_hop_count;
- double max_call_latency;
- double max_lockwait_latency;
- double max_childwrite_latency;
- uint32_t num_recoveries;
- struct timeval statistics_start_time;
- struct timeval statistics_current_time;
-};
+
+#define CTDB_UPDATE_STAT(ctdb, counter, value) \
+ { \
+ if (value > ctdb->statistics.counter) { \
+ ctdb->statistics.counter = c->hopcount; \
+ } \
+ if (value > ctdb->statistics_current.counter) { \
+ ctdb->statistics_current.counter = c->hopcount; \
+ } \
+ }
+
+#define CTDB_INCREMENT_STAT(ctdb, counter) \
+ { \
+ ctdb->statistics.counter++; \
+ ctdb->statistics_current.counter++; \
+ }
+
+#define CTDB_DECREMENT_STAT(ctdb, counter) \
+ { \
+ if (ctdb->statistics.counter > 0) \
+ ctdb->statistics.counter--; \
+ if (ctdb->statistics_current.counter > 0) \
+ ctdb->statistics_current.counter--; \
+ }
+
+#define CTDB_UPDATE_RECLOCK_LATENCY(ctdb, name, counter, value) \
+ { \
+ if (value > ctdb->statistics.counter.max) \
+ ctdb->statistics.counter.max = value; \
+ if (value > ctdb->statistics_current.counter.max) \
+ ctdb->statistics_current.counter.max = value; \
+ \
+ if (ctdb->statistics.counter.num == 0 || value < ctdb->statistics.counter.min) \
+ ctdb->statistics.counter.min = value; \
+ if (ctdb->statistics_current.counter.num == 0 || value < ctdb->statistics_current.counter.min) \
+ ctdb->statistics_current.counter.min = value; \
+ \
+ ctdb->statistics.counter.total += value; \
+ ctdb->statistics_current.counter.total += value; \
+ \
+ ctdb->statistics.counter.num++; \
+ ctdb->statistics_current.counter.num++; \
+ \
+ if (ctdb->tunable.reclock_latency_ms != 0) { \
+ if (value*1000 > ctdb->tunable.reclock_latency_ms) { \
+ DEBUG(DEBUG_ERR, ("High RECLOCK latency %fs for operation %s\n", value, name)); \
+ } \
+ } \
+ }
+
+
+#define CTDB_UPDATE_LATENCY(ctdb, db, operation, counter, t) \
+ { \
+ double l = timeval_elapsed(&t); \
+ \
+ if (l > ctdb->statistics.counter.max) \
+ ctdb->statistics.counter.max = l; \
+ if (l > ctdb->statistics_current.counter.max) \
+ ctdb->statistics_current.counter.max = l; \
+ \
+ if (ctdb->statistics.counter.num == 0 || l < ctdb->statistics.counter.min) \
+ ctdb->statistics.counter.min = l; \
+ if (ctdb->statistics_current.counter.num == 0 || l < ctdb->statistics_current.counter.min) \
+ ctdb->statistics_current.counter.min = l; \
+ \
+ ctdb->statistics.counter.total += l; \
+ ctdb->statistics_current.counter.total += l; \
+ \
+ ctdb->statistics.counter.num++; \
+ ctdb->statistics_current.counter.num++; \
+ \
+ if (ctdb->tunable.log_latency_ms !=0) { \
+ if (l*1000 > ctdb->tunable.log_latency_ms) { \
+ DEBUG(DEBUG_WARNING, ("High latency %.6fs for operation %s on database %s\n", l, operation, db->db_name));\
+ } \
+ } \
+ }
+
+
+
#define INVALID_GENERATION 1
#define NUM_DB_PRIORITIES 3
/* main state of the ctdb daemon */
struct ctdb_context {
- struct event_context *ev;
+ struct tevent_context *ev;
struct timeval ctdbd_start_time;
struct timeval last_recovery_started;
struct timeval last_recovery_finished;
struct ctdb_message_list *message_list;
struct ctdb_daemon_data daemon;
struct ctdb_statistics statistics;
+ struct ctdb_statistics statistics_current;
+#define MAX_STAT_HISTORY 100
+ struct ctdb_statistics statistics_history[MAX_STAT_HISTORY];
struct ctdb_vnn_map *vnn_map;
uint32_t num_clients;
uint32_t recovery_master;
struct ctdb_call_state *pending_calls;
struct ctdb_client_ip *client_ip_list;
- bool do_checkpublicip;
- struct trbt_tree *server_ids;
+ struct trbt_tree *server_ids;
+ bool do_setsched;
+ void *saved_scheduler_param;
const char *event_script_dir;
const char *notification_script;
const char *default_public_interface;
TALLOC_CTX *banning_ctx;
+ struct ctdb_vacuum_child_context *vacuumers;
+
/* mapping from pid to ctdb_client * */
struct ctdb_client_pid_list *client_pids;
/* used in the recovery daemon to remember the ip allocation */
struct trbt_tree *ip_tree;
+
+ /* Used to defer db attach requests while in recovery mode */
+ struct ctdb_deferred_attach_context *deferred_attach;
};
struct ctdb_db_context {
bool transaction_active;
struct ctdb_vacuum_handle *vacuum_handle;
char *unhealthy_reason;
+ int pending_requests;
+ struct lockwait_handle *lockwait_active;
+ struct lockwait_handle *lockwait_overflow;
+ struct ctdb_persistent_state *persistent_state;
};
char iface[1];
};
-/*
- struct for tcp_add and tcp_remove controls
- */
-struct ctdb_control_tcp_vnn {
- ctdb_sock_addr src;
- ctdb_sock_addr dest;
-};
-
/*
persistent store control - update this record on all other nodes
*/
TALLOC_CTX *mem_ctx, TDB_DATA *data);
int ctdb_ltdb_store(struct ctdb_db_context *ctdb_db, TDB_DATA key,
struct ctdb_ltdb_header *header, TDB_DATA data);
+int ctdb_ltdb_delete(struct ctdb_db_context *ctdb_db, TDB_DATA key);
int32_t ctdb_control_start_persistent_update(struct ctdb_context *ctdb,
struct ctdb_req_control *c,
TDB_DATA recdata);
TALLOC_CTX *mem_ctx, int fd, int alignment,
ctdb_queue_cb_fn_t callback,
- void *private_data);
+ void *private_data, const char *fmt, ...)
+ PRINTF_ATTRIBUTE(7,8);
/*
allocate a packet for use in client<->daemon communication
struct ctdb_ltdb_header *header);
int ctdb_call_local(struct ctdb_db_context *ctdb_db, struct ctdb_call *call,
- struct ctdb_ltdb_header *header, TALLOC_CTX *mem_ctx, TDB_DATA *data,
- uint32_t caller);
+ struct ctdb_ltdb_header *header, TALLOC_CTX *mem_ctx,
+ TDB_DATA *data);
#define ctdb_reqid_find(ctdb, reqid, type) (type *)_ctdb_reqid_find(ctdb, reqid, #type, __location__)
int ctdb_socket_connect(struct ctdb_context *ctdb);
-void ctdb_latency(struct ctdb_db_context *ctdb_db, const char *name, double *latency, struct timeval t);
-void ctdb_reclock_latency(struct ctdb_context *ctdb, const char *name, double *latency, double l);
-
#define CTDB_BAD_REQID ((uint32_t)-1)
uint32_t ctdb_reqid_new(struct ctdb_context *ctdb, void *state);
void *_ctdb_reqid_find(struct ctdb_context *ctdb, uint32_t reqid, const char *type, const char *location);
void *private_data);
int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
- TDB_DATA *outdata, uint64_t tdb_flags, bool persistent);
+ TDB_DATA *outdata, uint64_t tdb_flags,
+ bool persistent, uint32_t client_id,
+ struct ctdb_req_control *c,
+ bool *async_reply);
int ctdb_daemon_set_call(struct ctdb_context *ctdb, uint32_t db_id,
ctdb_fn_t fn, int id);
int ctdb_control_writerecord(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata);
-struct ctdb_traverse_start {
- uint32_t db_id;
- uint32_t reqid;
- uint64_t srvid;
-};
-
-/*
- structure used to pass record data between the child and parent
- */
-struct ctdb_rec_data {
- uint32_t length;
- uint32_t reqid;
- uint32_t keylen;
- uint32_t datalen;
- uint8_t data[1];
-};
-
-
/* structure used for pulldb control */
struct ctdb_control_pulldb {
uint32_t db_id;
};
-/* table that contains a list of all nodes a ctdb knows about and their
- status
- */
-struct ctdb_node_and_flags {
- uint32_t pnn;
- uint32_t flags;
- ctdb_sock_addr addr;
-};
-
-struct ctdb_node_map {
- uint32_t num;
- struct ctdb_node_and_flags nodes[1];
-};
-
struct ctdb_node_and_flagsv4 {
uint32_t pnn;
uint32_t flags;
void ctdb_node_dead(struct ctdb_node *node);
void ctdb_node_connected(struct ctdb_node *node);
bool ctdb_blocking_freeze(struct ctdb_context *ctdb);
-void ctdb_high_priority(struct ctdb_context *ctdb);
-void ctdb_reduce_priority(struct ctdb_context *ctdb);
+void ctdb_set_scheduler(struct ctdb_context *ctdb);
+void ctdb_restore_scheduler(struct ctdb_context *ctdb);
+pid_t ctdb_fork(struct ctdb_context *ctdb);
int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
struct ctdb_req_control *c,
TDB_DATA indata,
struct sockaddr_in sin;
};
-struct ctdb_public_ip {
- uint32_t pnn;
- ctdb_sock_addr addr;
-};
int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
uint32_t destnode, struct ctdb_public_ip *ip);
int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
struct ctdb_public_ipv4 ips[1];
};
-struct ctdb_all_public_ips {
- uint32_t num;
- struct ctdb_public_ip ips[1];
-};
int32_t ctdb_control_get_public_ipsv4(struct ctdb_context *ctdb, struct ctdb_req_control *c, TDB_DATA *outdata);
int32_t ctdb_control_get_public_ips(struct ctdb_context *ctdb, struct ctdb_req_control *c, TDB_DATA *outdata);
int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
TDB_DATA indata);
-int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata);
+int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata, bool tcp_update_needed);
int32_t ctdb_control_tcp_remove(struct ctdb_context *ctdb, TDB_DATA indata);
int32_t ctdb_control_startup(struct ctdb_context *ctdb, uint32_t vnn);
int32_t ctdb_control_kill_tcp(struct ctdb_context *ctdb, TDB_DATA indata);
struct ctdb_req_control *c,
TDB_DATA recdata, bool *async_reply);
+void ctdb_persistent_finish_trans3_commits(struct ctdb_context *ctdb);
+
int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb, uint32_t id);
int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb, uint32_t id);
int32_t ctdb_control_transaction_cancel(struct ctdb_context *ctdb);
int32_t ctdb_control_set_recmaster(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata);
extern int script_log_level;
+extern bool fast_start;
int32_t ctdb_control_get_event_script_status(struct ctdb_context *ctdb,
uint32_t call_type,
int32_t ctdb_control_stop_node(struct ctdb_context *ctdb, struct ctdb_req_control *c, bool *async_reply);
int32_t ctdb_control_continue_node(struct ctdb_context *ctdb);
+void ctdb_stop_vacuuming(struct ctdb_context *ctdb);
int ctdb_vacuum_init(struct ctdb_db_context *ctdb_db);
int32_t ctdb_control_enable_script(struct ctdb_context *ctdb, TDB_DATA indata);
int update_ip_assignment_tree(struct ctdb_context *ctdb,
struct ctdb_public_ip *ip);
+int ctdb_init_tevent_logging(struct ctdb_context *ctdb);
+
+int ctdb_statistics_init(struct ctdb_context *ctdb);
+
+int32_t ctdb_control_get_stat_history(struct ctdb_context *ctdb,
+ struct ctdb_req_control *c,
+ TDB_DATA *outdata);
+
+int ctdb_deferred_drop_all_ips(struct ctdb_context *ctdb);
+
+int ctdb_process_deferred_attach(struct ctdb_context *ctdb);
+
#endif