hammer2 - userland API / span work
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 8 Aug 2012 22:04:50 +0000 (15:04 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 8 Aug 2012 22:04:50 +0000 (15:04 -0700)
* 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.

sbin/hammer2/cmd_debug.c
sbin/hammer2/cmd_service.c
sbin/hammer2/hammer2.h
sbin/hammer2/msg.c
sbin/hammer2/msg_lnk.c
sys/vfs/hammer2/hammer2_msgops.c
sys/vfs/hammer2/hammer2_network.h

index d400714..0c098a6 100644 (file)
@@ -82,37 +82,57 @@ static
 void
 shell_rcvmsg(hammer2_iocom_t *iocom, hammer2_msg_t *msg)
 {
 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:
        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) {
                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;
                } 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.
        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.
                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;
                 */
                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:
        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;
        }
 }
                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:
                        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;
        }
 }
 
                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)
 {
 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) {
        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 <host>     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 <host> Span to target host\n");
+       /*
+        * Connect to the target
+        */
+       if (hostname == NULL) {
+               fd = -1;
        } else {
        } 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
  * 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;
 
 {
        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);
        va_start(va, ctl);
        vsnprintf(buf, sizeof(buf), ctl, va);
        va_end(va);
index 2ccfad4..4b7207c 100644 (file)
@@ -251,17 +251,10 @@ master_link_rxmsg(hammer2_iocom_t *iocom, hammer2_msg_t *msg)
         * might have REPLY set.
         */
        state = msg->state;
         * 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);
        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_dbg(iocom, msg);
                        break;
                default:
-                       hammer2_msg_reply(iocom, msg,
-                                         HAMMER2_MSG_ERR_UNKNOWN);
+                       hammer2_msg_reply(iocom, msg, HAMMER2_MSG_ERR_NOSUPP);
                        break;
                }
        }
                        break;
                }
        }
index 0445365..ae261f3 100644 (file)
@@ -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_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);
 
 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 *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);
 void *hammer2_alloc(size_t bytes);
 void hammer2_free(void *ptr);
index 29a13e0..c4480ba 100644 (file)
@@ -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) {
                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);
                        }
                                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;
                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;
                }
                        assert(0);
                        break;
                }
@@ -800,18 +801,15 @@ again:
                msg->any.head.error = ioq->error;
 
                pthread_mutex_lock(&iocom->mtx);
                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) {
                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 {
                                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;
                                /*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) {
                         * 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 {
                                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;
                                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;
                         */
                        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);
 
                }
                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;
        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
 
        /*
         * 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);
        }
 
                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);
        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) {
                 * 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;
                }
                        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 {
                        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;
                                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 {
                        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;
                                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) {
                 * 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;
                }
                        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 {
                        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;
                                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 {
                        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;
                                error = HAMMER2_IOQ_ERROR_TRANS;
                        }
                        break;
@@ -1714,8 +1709,10 @@ hammer2_state_free(hammer2_state_t *state)
        hammer2_msg_t *msg;
        char dummy;
 
        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;
        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);
 }
                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);
+}
index 80d578a..7e868d7 100644 (file)
@@ -207,6 +207,7 @@ struct h2span_node {
        struct h2span_link_tree tree;
        struct h2span_cluster *cls;
        uuid_t  pfs_fsid;               /* unique fsid */
        struct h2span_link_tree tree;
        struct h2span_cluster *cls;
        uuid_t  pfs_fsid;               /* unique fsid */
+       char label[64];
 };
 
 struct h2span_link {
 };
 
 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);
        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;
        }
                /* 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;
 
        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);
                        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;
 
        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),
                        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);
 
                /*
                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);
                        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;
 
                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,
 
        /*
         * 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);
                        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);
 
                                node->cls, node,
                                conn->state->iocom->sock_fd, relay->state);
 
@@ -739,7 +747,8 @@ static
 void
 hammer2_relay_delete(h2span_relay_t *relay)
 {
 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);
                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);
 }
        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
+}
index d3b8421..f791998 100644 (file)
@@ -61,7 +61,7 @@ hammer2_msg_dbg_rcvmsg(hammer2_pfsmount_t *pmp, hammer2_msg_t *msg)
                /*
                 * Execute shell command (not supported atm)
                 */
                /*
                 * 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) {
                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:
                }
                break;
        default:
-               hammer2_msg_reply(pmp, msg, HAMMER2_MSG_ERR_UNKNOWN);
+               hammer2_msg_reply(pmp, msg, HAMMER2_MSG_ERR_NOSUPP);
                break;
        }
        return(0);
                break;
        }
        return(0);
index fb7b370..c56dc1e 100644 (file)
@@ -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.
  */
  * 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 */
 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
  */
  *     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];
 
 union hammer2_msg_any {
        char                    buf[HAMMER2_MSGHDR_MAX];