Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

implemented gdb-callable connections_diag

This provides relatively easily accessible high-level diagnostics of
what is going on inside moxi

Change-Id: Iff04d63be694891bf0d329a89bc83ad5ffbd22b1
Reviewed-on: http://review.membase.org/3302
Tested-by: Aliaksey Kandratsenka <alkondratenko@gmail.com>
Reviewed-by: Steve Yen <steve.yen@gmail.com>
  • Loading branch information...
commit a4d1193dfc0b287ba6300da3b6c2ba7f644153cf 1 parent 1f0770f
@alk alk authored steveyen committed
Showing with 105 additions and 5 deletions.
  1. +81 −0 cproxy.c
  2. +4 −0 cproxy_config.c
  3. +8 −3 memcached.c
  4. +12 −2 memcached.h
View
81 cproxy.c
@@ -3221,3 +3221,84 @@ proxy *cproxy_find_proxy_by_auth(proxy_main *m,
return found;
}
+
+static
+void diag_single_connection(FILE *out, conn *c) {
+ fprintf(out, "%p (%d), ev: 0x%04x, state: 0x%x, substate: 0x%x - %s\n",
+ (void *)c, c->sfd, c->ev_flags,
+ c->state, c->substate,
+ c->update_diag ? c->update_diag : "(none)");
+}
+
+static
+void diag_connections(FILE *out, conn *head, int indent) {
+ static char *blank = "";
+ for (; head != NULL; head = head->next) {
+ fprintf(out, "%*s" "connection: ", indent, blank);
+ diag_single_connection(out, head);
+ }
+}
+
+static
+void diag_single_downstream(FILE *out, downstream *d, int indent) {
+ static char *blank = "";
+ conn *upstream = d->upstream_conn;
+ fprintf(out, "%*s" "upstream: ", indent, blank);
+ if (upstream) {
+ diag_single_connection(out, upstream);
+ } else {
+ fprintf(out, "none\n");
+ }
+
+ fprintf(out, "%*s" "downstream_used: %d\n", indent, blank, d->downstream_used);
+ fprintf(out, "%*s" "downstream_used_start: %d\n", indent, blank, d->downstream_used_start);
+ fprintf(out, "%*s" "downstream_conns:\n", indent, blank);
+
+ int n = mcs_server_count(&d->mst);
+ for (int i = 0; i < n; i++) {
+ if (d->downstream_conns[i] == NULL)
+ continue;
+ fprintf(out, "%*s", indent+2, blank);
+ diag_single_connection(out, d->downstream_conns[i]);
+ }
+}
+
+static
+void diag_downstream_chain(FILE *out, downstream *head, int indent) {
+ for (; head != NULL; head = head->next) {
+ diag_single_downstream(out, head, indent);
+ }
+}
+
+// this is supposed to be called from gdb when other threads are suspended
+void connections_diag(FILE *out);
+
+void connections_diag(FILE *out) {
+ extern proxy_main *diag_last_proxy_main;
+
+ proxy_main *m = diag_last_proxy_main;
+ if (!m) {
+ fputs("no proxy_main!\n", out);
+ return;
+ }
+
+ proxy *cur_proxy;
+ for (cur_proxy = m->proxy_head; cur_proxy != NULL ; cur_proxy = cur_proxy->next) {
+ int ti;
+ fprintf(out, "proxy: name='%s', port=%d, cfg=%s (%u)\n",
+ cur_proxy->name ? cur_proxy->name : "(null)",
+ cur_proxy->port,
+ cur_proxy->config, cur_proxy->config_ver);
+ for (ti = 0; ti < cur_proxy->thread_data_num; ti++) {
+ proxy_td *td = cur_proxy->thread_data + ti;
+ fprintf(out, " thread:%d\n", ti);
+ fprintf(out, " waiting_any_downstream:\n");
+ diag_connections(out, td->waiting_any_downstream_head, 6);
+
+ fprintf(out, " downstream_reserved:\n");
+ diag_downstream_chain(out, td->downstream_reserved, 6);
+ fprintf(out, " downstream_released:\n");
+ diag_downstream_chain(out, td->downstream_released, 6);
+ }
+ }
+}
View
4 cproxy_config.c
@@ -528,6 +528,8 @@ int cproxy_init_string(char *cfg_str,
return 0;
}
+proxy_main *diag_last_proxy_main;
+
proxy_main *cproxy_gen_proxy_main(proxy_behavior behavior, int nthreads,
enum_proxy_conf_type conf_type) {
proxy_main *m = calloc(1, sizeof(proxy_main));
@@ -545,6 +547,8 @@ proxy_main *cproxy_gen_proxy_main(proxy_behavior behavior, int nthreads,
m->stat_proxy_start_fails = 0;
m->stat_proxy_existings = 0;
m->stat_proxy_shutdowns = 0;
+
+ diag_last_proxy_main = m;
}
return m;
View
11 memcached.c
@@ -3232,16 +3232,19 @@ static enum try_read_result try_read_network(conn *c) {
return gotdata;
}
-bool update_event(conn *c, const int new_flags) {
- return update_event_timed(c, new_flags, NULL);
+bool update_event_real(conn *c, const int new_flags, const char *update_diag) {
+ return update_event_timed_real(c, new_flags, NULL, update_diag);
}
-bool update_event_timed(conn *c, const int new_flags, struct timeval *timeout) {
+bool update_event_timed_real(conn *c, const int new_flags, struct timeval *timeout, const char *update_diag) {
assert(c != NULL);
struct event_base *base = c->event.ev_base;
if (c->ev_flags == new_flags && timeout == NULL)
return true;
+
+ c->update_diag = update_diag;
+
if (event_del(&c->event) == -1)
return false;
c->ev_flags = new_flags;
@@ -3707,6 +3710,8 @@ void event_handler(const int fd, const short which, void *arg) {
return;
}
+ c->update_diag = "working";
+
drive_machine(c);
/* wait for next event */
View
14 memcached.h
@@ -491,6 +491,8 @@ struct conn {
char *peer_host; // this and the following two paramters are used for mcmux
unsigned int peer_protocol; // compatiblity mode
int peer_port;
+
+ const char *update_diag;
};
extern conn *listen_conn;
@@ -522,8 +524,16 @@ conn *conn_new(const int sfd, const enum conn_states init_state,
void conn_set_state(conn *c, enum conn_states state);
void add_bytes_read(conn *c, int bytes_read);
void out_string(conn *c, const char *str);
-bool update_event(conn *c, const int new_flags);
-bool update_event_timed(conn *c, const int new_flags, struct timeval *timeout);
+
+#define ___update_event_str(a) #a
+#define __update_event_str(a) ___update_event_str(a)
+
+#define update_event(c, new_flags) update_event_real(c, new_flags, (__FILE__ ":" __update_event_str(__LINE__)))
+#define update_event_timed(c, new_flags, timeout) update_event_timed_real(c, new_flags, timeout, (__FILE__ ":" __update_event_str(__LINE__)))
+
+bool update_event_real(conn *c, const int new_flags, const char *update_diag);
+bool update_event_timed_real(conn *c, const int new_flags, struct timeval *timeout, const char *update_diag);
+
int try_read_command(conn *c);
void process_command(conn *c, char *command);
void process_update_command(conn *c, token_t *tokens, const size_t ntokens, int comm, bool handle_cas);
Please sign in to comment.
Something went wrong with that request. Please try again.