static int hammer2_lnk_span_reply(kdmsg_state_t *state, kdmsg_msg_t *msg) { if ((state->txcmd & DMSGF_DELETE) == 0 && (msg->any.head.cmd & DMSGF_DELETE)) { kdmsg_msg_reply(msg, 0); } return 0; }
int hammer2_msg_dbg_rcvmsg(kdmsg_msg_t *msg) { switch(msg->any.head.cmd & DMSGF_CMDSWMASK) { case DMSG_DBG_SHELL: /* * Execute shell command (not supported atm) * * This is a one-way packet but if not (e.g. if part of * a streaming transaction), we will have already closed * our end. */ kdmsg_msg_reply(msg, DMSG_ERR_NOSUPP); break; case DMSG_DBG_SHELL | DMSGF_REPLY: /* * Receive one or more replies to a shell command that we * sent. * * This is a one-way packet but if not (e.g. if part of * a streaming transaction), we will have already closed * our end. */ if (msg->aux_data) { msg->aux_data[msg->aux_size - 1] = 0; kprintf("DEBUGMSG: %s\n", msg->aux_data); } break; default: /* * We don't understand what is going on, issue a reply. * This will take care of all left-over cases whether it * is a transaction or one-way. */ kdmsg_msg_reply(msg, DMSG_ERR_NOSUPP); break; } return(0); }
static int hammer2_rcvdmsg(kdmsg_msg_t *msg) { kprintf("RCVMSG %08x\n", msg->tcmd); switch(msg->tcmd) { case DMSG_DBG_SHELL: /* * (non-transaction) * Execute shell command (not supported atm) */ kdmsg_msg_result(msg, DMSG_ERR_NOSUPP); break; case DMSG_DBG_SHELL | DMSGF_REPLY: /* * (non-transaction) */ if (msg->aux_data) { msg->aux_data[msg->aux_size - 1] = 0; kprintf("HAMMER2 DBG: %s\n", msg->aux_data); } break; default: /* * Unsupported message received. We only need to * reply if it's a transaction in order to close our end. * Ignore any one-way messages or any further messages * associated with the transaction. * * NOTE: This case also includes DMSG_LNK_ERROR messages * which might be one-way, replying to those would * cause an infinite ping-pong. */ if (msg->any.head.cmd & DMSGF_CREATE) kdmsg_msg_reply(msg, DMSG_ERR_NOSUPP); break; } return(0); }
static void hammer2_autodmsg(kdmsg_msg_t *msg) { hammer2_dev_t *hmp = msg->state->iocom->handle; int copyid; switch(msg->tcmd) { case DMSG_LNK_CONN | DMSGF_CREATE: case DMSG_LNK_CONN | DMSGF_CREATE | DMSGF_DELETE: case DMSG_LNK_CONN | DMSGF_DELETE: /* * NOTE: kern_dmsg will automatically issue a result, * leaving the transaction open, for CREATEs, * and will automatically issue a terminating reply * for DELETEs. */ break; case DMSG_LNK_CONN | DMSGF_CREATE | DMSGF_REPLY: case DMSG_LNK_CONN | DMSGF_CREATE | DMSGF_DELETE | DMSGF_REPLY: /* * Do a volume configuration dump when we receive a reply * to our auto-CONN (typically leaving the transaction open). */ if (msg->any.head.cmd & DMSGF_CREATE) { kprintf("HAMMER2: VOLDATA DUMP\n"); /* * Dump the configuration stored in the volume header. * This will typically be import/export access rights, * master encryption keys (encrypted), etc. */ hammer2_voldata_lock(hmp); copyid = 0; while (copyid < HAMMER2_COPYID_COUNT) { if (hmp->voldata.copyinfo[copyid].copyid) hammer2_volconf_update(hmp, copyid); ++copyid; } hammer2_voldata_unlock(hmp); kprintf("HAMMER2: INITIATE SPANs\n"); hammer2_update_spans(hmp, msg->state); } if ((msg->any.head.cmd & DMSGF_DELETE) && msg->state && (msg->state->txcmd & DMSGF_DELETE) == 0) { kprintf("HAMMER2: CONN WAS TERMINATED\n"); } break; case DMSG_LNK_SPAN | DMSGF_CREATE: /* * Monitor SPANs and issue a result, leaving the SPAN open * if it is something we can use now or in the future. */ if (msg->any.lnk_span.peer_type != DMSG_PEER_HAMMER2) { kdmsg_msg_reply(msg, 0); break; } if (msg->any.lnk_span.proto_version != DMSG_SPAN_PROTO_1) { kdmsg_msg_reply(msg, 0); break; } DMSG_TERMINATE_STRING(msg->any.lnk_span.peer_label); kprintf("H2 +RXSPAN cmd=%08x (%-20s) cl=", msg->any.head.cmd, msg->any.lnk_span.peer_label); printf_uuid(&msg->any.lnk_span.peer_id); kprintf(" fs="); printf_uuid(&msg->any.lnk_span.pfs_id); kprintf(" type=%d\n", msg->any.lnk_span.pfs_type); kdmsg_msg_result(msg, 0); break; case DMSG_LNK_SPAN | DMSGF_DELETE: /* * NOTE: kern_dmsg will automatically reply to DELETEs. */ kprintf("H2 -RXSPAN\n"); break; default: break; } }