`shepherd info -t epoch` shows all the local epoch information at the target node. Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp> --- shepherd/shepherd.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 101 insertions(+), 1 deletions(-) diff --git a/shepherd/shepherd.c b/shepherd/shepherd.c index 53c9b44..77c1c00 100644 --- a/shepherd/shepherd.c +++ b/shepherd/shepherd.c @@ -59,6 +59,7 @@ enum info_type { INFO_OBJ, INFO_VM, INFO_CLUSTER, + INFO_EPOCH, INFO_NONE, }; @@ -79,7 +80,7 @@ static void usage(int status) \n\ Command syntax:\n\ mkfs [--copies=N]\n\ - info -t (vdi|dog|sheep|obj|cluster) [-f (list|tree|graph)] [-H (on|off)] [-R (on|off)] [-i N] [-e N] [vdiname]\n\ + info -t (vdi|dog|sheep|obj|cluster|epoch) [-f (list|tree|graph)] [-H (on|off)] [-R (on|off)] [-i N] [-e N] [vdiname]\n\ debug -o node_version\n\ shutdown\n\ \n\ @@ -1088,6 +1089,103 @@ rerun: } break; } + case INFO_EPOCH: + { + int fd; + struct sd_epoch_req hdr; + struct sd_epoch_rsp *rsp = (struct sd_epoch_rsp *)&hdr; + unsigned rlen, wlen; + int i, j, n; + uint32_t *epoch_list; + struct sheepdog_node_list_entry pre_entries[SD_MAX_NODES]; + struct sheepdog_node_list_entry entries[SD_MAX_NODES]; + int pre_size, size; + char added_node[128], removed_node[128]; + time_t ti; + struct tm tm; + char time[128]; + + fd = connect_to("localhost", sdport); + if (fd < 0) + break; + + memset(&hdr, 0, sizeof(hdr)); + + hdr.opcode = SD_OP_GET_EPOCH_LIST; + hdr.epoch = node_list_version; + hdr.data_length = SD_DATA_OBJ_SIZE; + epoch_list = zalloc(hdr.data_length); + if (!epoch_list) + return 1; + + rlen = hdr.data_length; + wlen = 0; + ret = exec_req(fd, (struct sd_req *)&hdr, epoch_list, &wlen, &rlen); + + if (ret != 0) + break; + + if (rsp->result != SD_RES_SUCCESS) { + fprintf(stderr, "failed to get epoch list, %x\n", rsp->result); + break; + } + + n = rlen / sizeof(uint32_t); + + printf(" Ctime Epoch Id Nodes\n"); + pre_size = 0; + + memset(&hdr, 0, sizeof(hdr)); + hdr.opcode = SD_OP_READ_EPOCH; + hdr.epoch = node_list_version; + for (i = 0; i < n; i++) { + hdr.data_length = sizeof(entries); + hdr.request_epoch = epoch_list[i]; + rlen = hdr.data_length; + + ret = exec_req(fd, (struct sd_req *)&hdr, entries, &wlen, &rlen); + + if (ret != 0) + break; + + if (rsp->result != SD_RES_SUCCESS) { + fprintf(stderr, "failed to read epoch, %x\n", rsp->result); + break; + } + + size = rlen; + if (size <= 0) { + pre_size = 0; + continue; + } + size /= sizeof(*entries); + added_node[0] = '\0'; + removed_node[0] = '\0'; + if (pre_size == 0 && epoch_list[i] != 1) + printf(" *\n"); + + ti = rsp->ctime >> 32; + localtime_r(&ti, &tm); + strftime(time, sizeof(time), "%y-%m-%d %H:%M:%S", &tm); + + printf("%c %s %6d %016" PRIx64, + rsp->is_updated ? 'U' : ' ', time, epoch_list[i], + rsp->hval); + printf(" ["); + for (j = 0; j < size; j++) { + printf("%s%s", + (j == 0) ? "" : ", ", + addr_to_str(added_node, sizeof(added_node), + entries[j].addr, entries[j].port)); + } + printf("]\n"); + pre_size = size; + memcpy(pre_entries, entries, size); + } + + close(fd); + break; + } default: ret = -1; break; @@ -1173,6 +1271,8 @@ int main(int argc, char **argv) type = INFO_VM; else if (!strcasecmp(optarg, "cluster")) type = INFO_CLUSTER; + else if (!strcasecmp(optarg, "epoch")) + type = INFO_EPOCH; else usage(1); break; -- 1.5.6.5 |