From: Matthew Dillon Date: Wed, 8 Aug 2012 22:04:50 +0000 (-0700) Subject: hammer2 - userland API / span work X-Git-Tag: v3.4.0rc~1038 X-Git-Url: http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/81666e1b4808c520191163b4afd1425156d8632e hammer2 - userland API / span work * Fix a stall bug in the streaming write code * Add some pretty-printing support for debug output. Also remove a ton of debug messages. * Add a remote shell 'tree' command to dump the spanning tree. * Cleanup some of the state handling and error codes. --- diff --git a/sbin/hammer2/cmd_debug.c b/sbin/hammer2/cmd_debug.c index d400714..0c098a6 100644 --- a/sbin/hammer2/cmd_debug.c +++ b/sbin/hammer2/cmd_debug.c @@ -82,37 +82,57 @@ static void shell_rcvmsg(hammer2_iocom_t *iocom, hammer2_msg_t *msg) { - switch(msg->any.head.cmd & HAMMER2_MSGF_CMDSWMASK) { + switch(msg->any.head.cmd & HAMMER2_MSGF_TRANSMASK) { case HAMMER2_LNK_ERROR: case HAMMER2_LNK_ERROR | HAMMER2_MSGF_REPLY: + /* + * One-way non-transactional LNK_ERROR messages typically + * indicate a connection failure. Error code 0 is used by + * the debug shell to indicate no more results from last cmd. + */ if (msg->any.head.error) { - fprintf(stderr, - "Link Error: %d\n", - msg->any.head.error); + fprintf(stderr, "Stream failure: %s\n", + hammer2_msg_str(msg)); } else { write(1, "debug> ", 7); } break; + case HAMMER2_LNK_ERROR | HAMMER2_MSGF_DELETE: + /* ignore termination of LNK_CONN */ + break; case HAMMER2_DBG_SHELL: /* * We send the commands, not accept them. + * (one-way message, not transactional) */ - hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_UNKNOWN); + hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_NOSUPP); break; case HAMMER2_DBG_SHELL | HAMMER2_MSGF_REPLY: /* * A reply from the remote is data we copy to stdout. + * (one-way message, not transactional) */ if (msg->aux_size) { msg->aux_data[msg->aux_size - 1] = 0; write(1, msg->aux_data, strlen(msg->aux_data)); } break; + case HAMMER2_LNK_CONN | HAMMER2_MSGF_CREATE: + fprintf(stderr, "Debug Shell is ignoring received LNK_CONN\n"); + hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_NOSUPP); + break; + case HAMMER2_LNK_CONN | HAMMER2_MSGF_DELETE: + break; default: - fprintf(stderr, "Unknown message: %08x\n", - msg->any.head.cmd); - assert((msg->any.head.cmd & HAMMER2_MSGF_REPLY) == 0); - hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_UNKNOWN); + /* + * Ignore any unknown messages, Terminate any unknown + * transactions with an error. + */ + fprintf(stderr, "Unknown message: %s\n", hammer2_msg_str(msg)); + if (msg->any.head.cmd & HAMMER2_MSGF_CREATE) + hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_NOSUPP); + if (msg->any.head.cmd & HAMMER2_MSGF_DELETE) + hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_NOSUPP); break; } } @@ -174,11 +194,14 @@ hammer2_msg_dbg(hammer2_iocom_t *iocom, hammer2_msg_t *msg) write(2, msg->aux_data, strlen(msg->aux_data)); break; default: - hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_UNKNOWN); + hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_NOSUPP); break; } } +static void shell_span(hammer2_iocom_t *iocom, char *cmdbuf); +/*static void shell_tree(hammer2_iocom_t *iocom, char *cmdbuf);*/ + static void hammer2_shell_parse(hammer2_iocom_t *iocom, hammer2_msg_t *msg) { @@ -188,36 +211,44 @@ hammer2_shell_parse(hammer2_iocom_t *iocom, hammer2_msg_t *msg) if (cmd == NULL || *cmd == 0) { ; } else if (strcmp(cmd, "span") == 0) { - const char *hostname = strsep(&cmdbuf, " \t"); - pthread_t thread; - int fd; + shell_span(iocom, cmdbuf); + } else if (strcmp(cmd, "tree") == 0) { + shell_tree(iocom, cmdbuf); + } else if (strcmp(cmd, "help") == 0 || strcmp(cmd, "?") == 0) { + iocom_printf(iocom, "help Command help\n"); + iocom_printf(iocom, "span Span to target host\n"); + iocom_printf(iocom, "tree Dump spanning tree\n"); + } else { + iocom_printf(iocom, "Unrecognized command: %s\n", cmd); + } +} - /* - * Connect to the target - */ - if (hostname == NULL) { - fd = -1; - } else { - fd = hammer2_connect(hostname); - } +static void +shell_span(hammer2_iocom_t *iocom, char *cmdbuf) +{ + const char *hostname = strsep(&cmdbuf, " \t"); + pthread_t thread; + int fd; - /* - * Start master service - */ - if (fd < 0) { - iocom_printf(iocom, 0, "Connection to %s failed\n", - hostname); - } else { - iocom_printf(iocom, 0, "Connected to %s\n", hostname); - pthread_create(&thread, NULL, - master_service, (void *)(intptr_t)fd); - /*pthread_join(thread, &res);*/ - } - } else if (strcmp(cmd, "help") == 0 || strcmp(cmd, "?") == 0) { - iocom_printf(iocom, 0, "help Command help\n"); - iocom_printf(iocom, 0, "span Span to target host\n"); + /* + * Connect to the target + */ + if (hostname == NULL) { + fd = -1; } else { - iocom_printf(iocom, 0, "Unrecognized command: %s\n", cmd); + fd = hammer2_connect(hostname); + } + + /* + * Start master service + */ + if (fd < 0) { + iocom_printf(iocom, "Connection to %s failed\n", hostname); + } else { + iocom_printf(iocom, "Connected to %s\n", hostname); + pthread_create(&thread, NULL, + master_service, (void *)(intptr_t)fd); + /*pthread_join(thread, &res);*/ } } @@ -230,16 +261,13 @@ hammer2_shell_parse(hammer2_iocom_t *iocom, hammer2_msg_t *msg) * to the iocom_printf(). We filter out DBG messages. */ void -iocom_printf(hammer2_iocom_t *iocom, uint32_t cmd, const char *ctl, ...) +iocom_printf(hammer2_iocom_t *iocom, const char *ctl, ...) { hammer2_msg_t *rmsg; va_list va; char buf[1024]; size_t len; - if ((cmd & HAMMER2_MSGF_PROTOS) == HAMMER2_MSG_PROTO_DBG) - return; - va_start(va, ctl); vsnprintf(buf, sizeof(buf), ctl, va); va_end(va); diff --git a/sbin/hammer2/cmd_service.c b/sbin/hammer2/cmd_service.c index 2ccfad4..4b7207c 100644 --- a/sbin/hammer2/cmd_service.c +++ b/sbin/hammer2/cmd_service.c @@ -251,17 +251,10 @@ master_link_rxmsg(hammer2_iocom_t *iocom, hammer2_msg_t *msg) * might have REPLY set. */ state = msg->state; - if (state) { - cmd = state->msg->any.head.cmd; - fprintf(stderr, - "MSGRX persist=%08x cmd=%08x error %d\n", - cmd, msg->any.head.cmd, msg->any.head.error); - } else { - cmd = msg->any.head.cmd; - fprintf(stderr, - "MSGRX persist=-------- cmd=%08x error %d\n", - cmd, msg->any.head.error); - } + cmd = state ? state->msg->any.head.cmd : msg->any.head.cmd; + + fprintf(stderr, "service-receive: %s\n", hammer2_msg_str(msg)); + if (state && state->func) { assert(state->func != NULL); state->func(state, msg); @@ -274,8 +267,7 @@ master_link_rxmsg(hammer2_iocom_t *iocom, hammer2_msg_t *msg) hammer2_msg_dbg(iocom, msg); break; default: - hammer2_msg_reply(iocom, msg, - HAMMER2_MSG_ERR_UNKNOWN); + hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_NOSUPP); break; } } diff --git a/sbin/hammer2/hammer2.h b/sbin/hammer2/hammer2.h index 0445365..ae261f3 100644 --- a/sbin/hammer2/hammer2.h +++ b/sbin/hammer2/hammer2.h @@ -183,11 +183,15 @@ const char *hammer2_uuid_to_str(uuid_t *uuid, char **strp); const char *hammer2_iptype_to_str(uint8_t type); const char *hammer2_pfstype_to_str(uint8_t type); const char *sizetostr(hammer2_off_t size); +const char * hammer2_basecmd_str(uint32_t cmd); +const char *hammer2_msg_str(hammer2_msg_t *msg); int hammer2_connect(const char *hostname); +void shell_tree(hammer2_iocom_t *iocom, char *cmdbuf); + void *master_service(void *data); void hammer2_msg_debug(hammer2_iocom_t *iocom, hammer2_msg_t *msg); -void iocom_printf(hammer2_iocom_t *iocom, uint32_t cmd, const char *ctl, ...); +void iocom_printf(hammer2_iocom_t *iocom, const char *ctl, ...); void *hammer2_alloc(size_t bytes); void hammer2_free(void *ptr); diff --git a/sbin/hammer2/msg.c b/sbin/hammer2/msg.c index 29a13e0..c4480ba 100644 --- a/sbin/hammer2/msg.c +++ b/sbin/hammer2/msg.c @@ -383,10 +383,10 @@ hammer2_iocom_core(hammer2_iocom_t *iocom) if (iocom->flags & HAMMER2_IOCOMF_RWORK) { while ((iocom->flags & HAMMER2_IOCOMF_EOF) == 0 && (msg = hammer2_ioq_read(iocom)) != NULL) { - fprintf(stderr, - "receive msg cmd=%08x msgid=%016jx\n", - msg->any.head.cmd, - (intmax_t)msg->any.head.msgid); + if (DebugOpt) { + fprintf(stderr, "receive %s\n", + hammer2_msg_str(msg)); + } iocom->rcvmsg_callback(iocom, msg); hammer2_state_cleanuprx(iocom, msg); } @@ -603,8 +603,9 @@ again: head->hdr_crc = 0; if (hammer2_icrc32(head, ioq->hbytes) != xcrc32) { ioq->error = HAMMER2_IOQ_ERROR_XCRC; - fprintf(stderr, "XCRC FAILED %08x %08x\n", - xcrc32, hammer2_icrc32(head, ioq->hbytes)); + fprintf(stderr, "BAD-XCRC(%08x,%08x) %s\n", + xcrc32, hammer2_icrc32(head, ioq->hbytes), + hammer2_msg_str(msg)); assert(0); break; } @@ -800,18 +801,15 @@ again: msg->any.head.error = ioq->error; pthread_mutex_lock(&iocom->mtx); - fprintf(stderr, "CHECK REMAINING RXMSGS\n"); if ((state = RB_ROOT(&iocom->staterd_tree)) != NULL) { /* * Active remote transactions are still present. * Simulate the other end sending us a DELETE. */ if (state->rxcmd & HAMMER2_MSGF_DELETE) { - fprintf(stderr, "SIMULATE DELETION RCONT %p\n", state); hammer2_msg_free(iocom, msg); msg = NULL; } else { - fprintf(stderr, "SIMULATE DELETION %p RD RXCMD %08x\n", state, state->rxcmd); /*state->txcmd |= HAMMER2_MSGF_DELETE;*/ msg->state = state; msg->any.head.spanid = state->spanid; @@ -825,12 +823,9 @@ again: * Simulate the other end sending us a DELETE. */ if (state->rxcmd & HAMMER2_MSGF_DELETE) { - fprintf(stderr, "SIMULATE DELETION WCONT STATE->txcmd = %08x rxcmd = %08x msgid=%016jx\n", state->txcmd, state->rxcmd, state->msgid ); hammer2_msg_free(iocom, msg); msg = NULL; } else { - fprintf(stderr, "SIMULATE DELETION WD RXCMD %08x\n", state->txcmd); - /*state->txcmd |= HAMMER2_MSGF_DELETE;*/ msg->state = state; msg->any.head.spanid = state->spanid; msg->any.head.msgid = state->msgid; @@ -849,7 +844,7 @@ again: */ msg->state = NULL; iocom->flags |= HAMMER2_IOCOMF_EOF; - fprintf(stderr, "EOF ON SOCKET\n"); + fprintf(stderr, "EOF ON SOCKET %d\n", iocom->sock_fd); } pthread_mutex_unlock(&iocom->mtx); @@ -1084,8 +1079,6 @@ hammer2_iocom_flush2(hammer2_iocom_t *iocom) hammer2_crypto_encrypt_wrote(iocom, ioq, nact); if (nact != nmax) iocom->flags |= HAMMER2_IOCOMF_WREQ; - else if (nmax != omax) - iocom->flags |= HAMMER2_IOCOMF_WWORK; /* * Clean out the transmit queue based on what we successfully @@ -1118,6 +1111,13 @@ hammer2_iocom_flush2(hammer2_iocom_t *iocom) hammer2_state_cleanuptx(iocom, msg); } + + /* + * If more messages are pending on WREQ wasn't set we must + * ensure that WWORK gets set. + */ + if (msg && (iocom->flags & HAMMER2_IOCOMF_WREQ) == 0) + iocom->flags |= HAMMER2_IOCOMF_WWORK; assert(nact == 0); if (ioq->error) { hammer2_iocom_drain(iocom); @@ -1482,8 +1482,8 @@ hammer2_state_msgrx(hammer2_iocom_t *iocom, hammer2_msg_t *msg) * New persistant command received. */ if (state) { - fprintf(stderr, "hammer2_state_msgrx: " - "duplicate transaction\n"); + fprintf(stderr, "duplicate-trans %s\n", + hammer2_msg_str(msg)); error = HAMMER2_IOQ_ERROR_TRANS; break; } @@ -1512,8 +1512,8 @@ hammer2_state_msgrx(hammer2_iocom_t *iocom, hammer2_msg_t *msg) if (msg->any.head.cmd & HAMMER2_MSGF_ABORT) { error = HAMMER2_IOQ_ERROR_EALREADY; } else { - fprintf(stderr, "hammer2_state_msgrx: " - "no state for DELETE\n"); + fprintf(stderr, "missing-state %s\n", + hammer2_msg_str(msg)); error = HAMMER2_IOQ_ERROR_TRANS; } break; @@ -1527,8 +1527,8 @@ hammer2_state_msgrx(hammer2_iocom_t *iocom, hammer2_msg_t *msg) if (msg->any.head.cmd & HAMMER2_MSGF_ABORT) { error = HAMMER2_IOQ_ERROR_EALREADY; } else { - fprintf(stderr, "hammer2_state_msgrx: " - "state reused for DELETE\n"); + fprintf(stderr, "reused-state %s\n", + hammer2_msg_str(msg)); error = HAMMER2_IOQ_ERROR_TRANS; } break; @@ -1556,11 +1556,8 @@ hammer2_state_msgrx(hammer2_iocom_t *iocom, hammer2_msg_t *msg) * persistent state message should already exist. */ if (state == NULL) { - fprintf(stderr, - "hammer2_state_msgrx: no state match for REPLY" - " cmd=%08x msgid=%016jx\n", - msg->any.head.cmd, - (intmax_t)msg->any.head.msgid); + fprintf(stderr, "no-state(r) %s\n", + hammer2_msg_str(msg)); error = HAMMER2_IOQ_ERROR_TRANS; break; } @@ -1578,9 +1575,8 @@ hammer2_state_msgrx(hammer2_iocom_t *iocom, hammer2_msg_t *msg) if (msg->any.head.cmd & HAMMER2_MSGF_ABORT) { error = HAMMER2_IOQ_ERROR_EALREADY; } else { - fprintf(stderr, "hammer2_state_msgrx: " - "no state match for " - "REPLY|DELETE\n"); + fprintf(stderr, "no-state(r,d) %s\n", + hammer2_msg_str(msg)); error = HAMMER2_IOQ_ERROR_TRANS; } break; @@ -1595,9 +1591,8 @@ hammer2_state_msgrx(hammer2_iocom_t *iocom, hammer2_msg_t *msg) if (msg->any.head.cmd & HAMMER2_MSGF_ABORT) { error = HAMMER2_IOQ_ERROR_EALREADY; } else { - fprintf(stderr, "hammer2_state_msgrx: " - "state reused for " - "REPLY|DELETE\n"); + fprintf(stderr, "reused-state(r,d) %s\n", + hammer2_msg_str(msg)); error = HAMMER2_IOQ_ERROR_TRANS; } break; @@ -1714,8 +1709,10 @@ hammer2_state_free(hammer2_state_t *state) hammer2_msg_t *msg; char dummy; - fprintf(stderr, "STATE FREE %p\n", state); - + if (DebugOpt) { + fprintf(stderr, "terminate state id=%08x\n", + (uint32_t)state->msgid); + } assert(state->any.any == NULL); msg = state->msg; state->msg = NULL; @@ -1757,3 +1754,215 @@ hammer2_state_cmp(hammer2_state_t *state1, hammer2_state_t *state2) return(1); return(0); } + +const char * +hammer2_basecmd_str(uint32_t cmd) +{ + static char buf[64]; + char protobuf[32]; + char cmdbuf[32]; + const char *protostr; + const char *cmdstr; + + switch(cmd & HAMMER2_MSGF_PROTOS) { + case HAMMER2_MSG_PROTO_LNK: + protostr = "LNK_"; + break; + case HAMMER2_MSG_PROTO_DBG: + protostr = "DBG_"; + break; + case HAMMER2_MSG_PROTO_DOM: + protostr = "DOM_"; + break; + case HAMMER2_MSG_PROTO_CAC: + protostr = "CAC_"; + break; + case HAMMER2_MSG_PROTO_QRM: + protostr = "QRM_"; + break; + case HAMMER2_MSG_PROTO_BLK: + protostr = "BLK_"; + break; + case HAMMER2_MSG_PROTO_VOP: + protostr = "VOP_"; + break; + default: + snprintf(protobuf, sizeof(protobuf), "%x_", + (cmd & HAMMER2_MSGF_PROTOS) >> 20); + protostr = protobuf; + break; + } + + switch(cmd & (HAMMER2_MSGF_PROTOS | + HAMMER2_MSGF_CMDS | + HAMMER2_MSGF_SIZE)) { + case HAMMER2_LNK_PAD: + cmdstr = "PAD"; + break; + case HAMMER2_LNK_PING: + cmdstr = "PING"; + break; + case HAMMER2_LNK_AUTH: + cmdstr = "AUTH"; + break; + case HAMMER2_LNK_CONN: + cmdstr = "CONN"; + break; + case HAMMER2_LNK_SPAN: + cmdstr = "SPAN"; + break; + case HAMMER2_LNK_ERROR: + if (cmd & HAMMER2_MSGF_DELETE) + cmdstr = "RETURN"; + else + cmdstr = "RESULT"; + break; + case HAMMER2_DBG_SHELL: + cmdstr = "SHELL"; + break; + default: + snprintf(cmdbuf, sizeof(cmdbuf), + "%06x", (cmd & (HAMMER2_MSGF_PROTOS | + HAMMER2_MSGF_CMDS | + HAMMER2_MSGF_SIZE))); + cmdstr = cmdbuf; + break; + } + snprintf(buf, sizeof(buf), "%s%s", protostr, cmdstr); + return (buf); +} + +const char * +hammer2_msg_str(hammer2_msg_t *msg) +{ + hammer2_state_t *state; + static char buf[256]; + char errbuf[16]; + char statebuf[64]; + char flagbuf[64]; + const char *statestr; + const char *errstr; + uint32_t basecmd; + int i; + + /* + * Parse the state + */ + if ((state = msg->state) != NULL) { + basecmd = (state->rxcmd & HAMMER2_MSGF_REPLY) ? + state->txcmd : state->rxcmd; + snprintf(statebuf, sizeof(statebuf), + " %s=%s,L=%s%s,R=%s%s", + ((state->txcmd & HAMMER2_MSGF_REPLY) ? + "rcvcmd" : "sndcmd"), + hammer2_basecmd_str(basecmd), + ((state->txcmd & HAMMER2_MSGF_CREATE) ? "C" : ""), + ((state->txcmd & HAMMER2_MSGF_DELETE) ? "D" : ""), + ((state->rxcmd & HAMMER2_MSGF_CREATE) ? "C" : ""), + ((state->rxcmd & HAMMER2_MSGF_DELETE) ? "D" : "") + ); + statestr = statebuf; + } else { + statestr = ""; + } + + /* + * Parse the error + */ + switch(msg->any.head.error) { + case 0: + errstr = ""; + break; + case HAMMER2_IOQ_ERROR_SYNC: + errstr = "err=IOQ:NOSYNC"; + break; + case HAMMER2_IOQ_ERROR_EOF: + errstr = "err=IOQ:STREAMEOF"; + break; + case HAMMER2_IOQ_ERROR_SOCK: + errstr = "err=IOQ:SOCKERR"; + break; + case HAMMER2_IOQ_ERROR_FIELD: + errstr = "err=IOQ:BADFIELD"; + break; + case HAMMER2_IOQ_ERROR_HCRC: + errstr = "err=IOQ:BADHCRC"; + break; + case HAMMER2_IOQ_ERROR_XCRC: + errstr = "err=IOQ:BADXCRC"; + break; + case HAMMER2_IOQ_ERROR_ACRC: + errstr = "err=IOQ:BADACRC"; + break; + case HAMMER2_IOQ_ERROR_STATE: + errstr = "err=IOQ:BADSTATE"; + break; + case HAMMER2_IOQ_ERROR_NOPEER: + errstr = "err=IOQ:PEERCONFIG"; + break; + case HAMMER2_IOQ_ERROR_NORKEY: + errstr = "err=IOQ:BADRKEY"; + break; + case HAMMER2_IOQ_ERROR_NOLKEY: + errstr = "err=IOQ:BADLKEY"; + break; + case HAMMER2_IOQ_ERROR_KEYXCHGFAIL: + errstr = "err=IOQ:BADKEYXCHG"; + break; + case HAMMER2_IOQ_ERROR_KEYFMT: + errstr = "err=IOQ:BADFMT"; + break; + case HAMMER2_IOQ_ERROR_BADURANDOM: + errstr = "err=IOQ:BADRANDOM"; + break; + case HAMMER2_IOQ_ERROR_MSGSEQ: + errstr = "err=IOQ:BADSEQ"; + break; + case HAMMER2_IOQ_ERROR_EALREADY: + errstr = "err=IOQ:DUPMSG"; + break; + case HAMMER2_IOQ_ERROR_TRANS: + errstr = "err=IOQ:BADTRANS"; + break; + case HAMMER2_MSG_ERR_NOSUPP: + errstr = "err=NOSUPPORT"; + break; + default: + snprintf(errbuf, sizeof(errbuf), + " err=%d", msg->any.head.error); + errstr = errbuf; + break; + } + + /* + * Message flags + */ + i = 0; + if (msg->any.head.cmd & (HAMMER2_MSGF_CREATE | HAMMER2_MSGF_DELETE | + HAMMER2_MSGF_ABORT | HAMMER2_MSGF_REPLY)) { + flagbuf[i++] = '|'; + if (msg->any.head.cmd & HAMMER2_MSGF_CREATE) + flagbuf[i++] = 'C'; + if (msg->any.head.cmd & HAMMER2_MSGF_DELETE) + flagbuf[i++] = 'D'; + if (msg->any.head.cmd & HAMMER2_MSGF_REPLY) + flagbuf[i++] = 'R'; + if (msg->any.head.cmd & HAMMER2_MSGF_ABORT) + flagbuf[i++] = 'A'; + } + flagbuf[i] = 0; + + /* + * Generate the buf + */ + snprintf(buf, sizeof(buf), + "msg=%s%s %s id=%08x span=%08x %s", + hammer2_basecmd_str(msg->any.head.cmd), + flagbuf, + errstr, + (uint32_t)(intmax_t)msg->any.head.msgid, /* for brevity */ + (uint32_t)(intmax_t)msg->any.head.spanid, /* for brevity */ + statestr); + + return(buf); +} diff --git a/sbin/hammer2/msg_lnk.c b/sbin/hammer2/msg_lnk.c index 80d578a..7e868d7 100644 --- a/sbin/hammer2/msg_lnk.c +++ b/sbin/hammer2/msg_lnk.c @@ -207,6 +207,7 @@ struct h2span_node { struct h2span_link_tree tree; struct h2span_cluster *cls; uuid_t pfs_fsid; /* unique fsid */ + char label[64]; }; struct h2span_link { @@ -345,7 +346,7 @@ hammer2_msg_lnk(hammer2_iocom_t *iocom, hammer2_msg_t *msg) default: fprintf(stderr, "MSG_PROTO_LNK: Unknown msg %08x\n", msg->any.head.cmd); - hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_UNKNOWN); + hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_NOSUPP); /* state invalid after reply */ break; } @@ -368,8 +369,8 @@ hammer2_lnk_conn(hammer2_state_t *state, hammer2_msg_t *msg) if (msg->any.head.cmd & HAMMER2_MSGF_CREATE) { state->func = hammer2_lnk_conn; - fprintf(stderr, "LNK_CONN(%016jx): %s/%s\n", - (intmax_t)msg->any.head.msgid, + fprintf(stderr, "LNK_CONN(%08x): %s/%s\n", + (uint32_t)msg->any.head.msgid, hammer2_uuid_to_str(&msg->any.lnk_conn.pfs_clid, &alloc), msg->any.lnk_conn.label); @@ -440,10 +441,13 @@ hammer2_lnk_span(hammer2_state_t *state, hammer2_msg_t *msg) if (msg->any.head.cmd & HAMMER2_MSGF_CREATE) { state->func = hammer2_lnk_span; - fprintf(stderr, "LNK_SPAN: %s/%s\n", + msg->any.lnk_span.label[sizeof(msg->any.lnk_span.label)-1] = 0; + + fprintf(stderr, "LNK_SPAN: %s/%s dist=%d\n", hammer2_uuid_to_str(&msg->any.lnk_span.pfs_clid, &alloc), - msg->any.lnk_span.label); + msg->any.lnk_span.label, + msg->any.lnk_span.dist); free(alloc); /* @@ -469,6 +473,8 @@ hammer2_lnk_span(hammer2_state_t *state, hammer2_msg_t *msg) node->cls = cls; RB_INIT(&node->tree); RB_INSERT(h2span_node_tree, &cls->tree, node); + snprintf(node->label, sizeof(node->label), + "%s", msg->any.lnk_span.label); } /* @@ -667,7 +673,8 @@ hammer2_relay_scan_specific(h2span_node_t *node, h2span_connect_t *conn) hammer2_relay_scan_cmp, hammer2_relay_scan_callback, &info); relay = info.relay; - fprintf(stderr, "relay scan for connection %p\n", conn); + if (DebugOpt > 8) + fprintf(stderr, "relay scan for connection %p\n", conn); /* * Iterate the node's links (received SPANs) in distance order, @@ -705,7 +712,8 @@ hammer2_relay_scan_specific(h2span_node_t *node, h2span_connect_t *conn) hammer2_msg_write(conn->state->iocom, msg, hammer2_lnk_relay, relay, &relay->state); - fprintf(stderr, "RELAY SPAN ON CLS=%p NODE=%p FD %d state %p\n", + fprintf(stderr, + "RELAY SPAN ON CLS=%p NODE=%p FD %d state %p\n", node->cls, node, conn->state->iocom->sock_fd, relay->state); @@ -739,7 +747,8 @@ static void hammer2_relay_delete(h2span_relay_t *relay) { - fprintf(stderr, "RELAY DELETE ON CLS=%p NODE=%p FD %d STATE %p\n", + fprintf(stderr, + "RELAY DELETE ON CLS=%p NODE=%p FD %d STATE %p\n", relay->link->node->cls, relay->link->node, relay->conn->state->iocom->sock_fd, relay->state); fprintf(stderr, "RELAY TX %08x RX %08x\n", relay->state->txcmd, relay->state->rxcmd); @@ -757,3 +766,38 @@ hammer2_relay_delete(h2span_relay_t *relay) relay->link = NULL; hammer2_free(relay); } + +/* + * Dumps the spanning tree + */ +void +shell_tree(hammer2_iocom_t *iocom, char *cmdbuf __unused) +{ + h2span_cluster_t *cls; + h2span_node_t *node; + h2span_link_t *slink; + char *uustr = NULL; + + pthread_mutex_lock(&cluster_mtx); + RB_FOREACH(cls, h2span_cluster_tree, &cluster_tree) { + iocom_printf(iocom, "Cluster %s\n", + hammer2_uuid_to_str(&cls->pfs_clid, &uustr)); + RB_FOREACH(node, h2span_node_tree, &cls->tree) { + iocom_printf(iocom, " Node %s (%s)\n", + hammer2_uuid_to_str(&node->pfs_fsid, &uustr), + node->label); + RB_FOREACH(slink, h2span_link_tree, &node->tree) { + iocom_printf(iocom, "\tLink dist=%d via %d\n", + slink->dist, + slink->state->iocom->sock_fd); + } + } + } + pthread_mutex_unlock(&cluster_mtx); + if (uustr) + free(uustr); +#if 0 + TAILQ_FOREACH(conn, &connq, entry) { + } +#endif +} diff --git a/sys/vfs/hammer2/hammer2_msgops.c b/sys/vfs/hammer2/hammer2_msgops.c index d3b8421..f791998 100644 --- a/sys/vfs/hammer2/hammer2_msgops.c +++ b/sys/vfs/hammer2/hammer2_msgops.c @@ -61,7 +61,7 @@ hammer2_msg_dbg_rcvmsg(hammer2_pfsmount_t *pmp, hammer2_msg_t *msg) /* * Execute shell command (not supported atm) */ - hammer2_msg_reply(pmp, msg, HAMMER2_MSG_ERR_UNKNOWN); + hammer2_msg_reply(pmp, msg, HAMMER2_MSG_ERR_NOSUPP); break; case HAMMER2_DBG_SHELL | HAMMER2_MSGF_REPLY: if (msg->aux_data) { @@ -70,7 +70,7 @@ hammer2_msg_dbg_rcvmsg(hammer2_pfsmount_t *pmp, hammer2_msg_t *msg) } break; default: - hammer2_msg_reply(pmp, msg, HAMMER2_MSG_ERR_UNKNOWN); + hammer2_msg_reply(pmp, msg, HAMMER2_MSG_ERR_NOSUPP); break; } return(0); diff --git a/sys/vfs/hammer2/hammer2_network.h b/sys/vfs/hammer2/hammer2_network.h index fb7b370..c56dc1e 100644 --- a/sys/vfs/hammer2/hammer2_network.h +++ b/sys/vfs/hammer2/hammer2_network.h @@ -358,6 +358,11 @@ typedef struct hammer2_msg_hdr hammer2_msg_hdr_t; * not be executed on the connection, nor is this message a promise that the * sending end is a client or node of a cluster. */ +struct hammer2_lnk_auth { + hammer2_msg_hdr_t head; + char dummy[64]; +}; + struct hammer2_lnk_conn { hammer2_msg_hdr_t head; uuid_t pfs_clid; /* rendezvous pfs uuid */ @@ -524,7 +529,7 @@ typedef struct hammer2_dbg_shell hammer2_dbg_shell_t; * 0x00 - 0x1F Local iocomm errors * 0x20 - 0x2F Global errors */ -#define HAMMER2_MSG_ERR_UNKNOWN 0x20 +#define HAMMER2_MSG_ERR_NOSUPP 0x20 union hammer2_msg_any { char buf[HAMMER2_MSGHDR_MAX];