`shepherd info -t cluster` will show cluster status and current epoch information. Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp> --- shepherd/shepherd.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 93 insertions(+), 1 deletions(-) diff --git a/shepherd/shepherd.c b/shepherd/shepherd.c index 52383bd..53c9b44 100644 --- a/shepherd/shepherd.c +++ b/shepherd/shepherd.c @@ -58,6 +58,7 @@ enum info_type { INFO_SHEEP, INFO_OBJ, INFO_VM, + INFO_CLUSTER, INFO_NONE, }; @@ -78,7 +79,7 @@ static void usage(int status) \n\ Command syntax:\n\ mkfs [--copies=N]\n\ - info -t (vdi|dog|sheep|obj) [-f (list|tree|graph)] [-H (on|off)] [-R (on|off)] [-i N] [-e N] [vdiname]\n\ + info -t (vdi|dog|sheep|obj|cluster) [-f (list|tree|graph)] [-H (on|off)] [-R (on|off)] [-i N] [-e N] [vdiname]\n\ debug -o node_version\n\ shutdown\n\ \n\ @@ -998,6 +999,95 @@ rerun: ret = parse_vdi(print_vm_list, &vli); break; } + case INFO_CLUSTER: + { + int fd; + struct sd_vdi_req hdr; + struct sd_vdi_rsp *rsp = (struct sd_vdi_rsp *)&hdr; + unsigned rlen, wlen; + struct epoch_log logs[8]; + int nr_logs; + 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_STAT_CLUSTER; + hdr.epoch = node_list_version; + hdr.data_length = sizeof(logs); + + rlen = hdr.data_length; + wlen = 0; + ret = exec_req(fd, (struct sd_req *)&hdr, logs, &wlen, &rlen); + close(fd); + + if (ret != 0) + break; + + if (rsp->result != SD_RES_SUCCESS) { + fprintf(stderr, "failed to get cluster status, %x\n", rsp->result); + break; + } + switch (rsp->rsvd) { + case SD_STATUS_OK: + printf("running\n"); + break; + case SD_STATUS_NO_EPOCH: + printf("There is no epoch info\n"); + printf("Please run `shepherd mkfs`\n"); + break; + case SD_STATUS_MULTIPLE_EPOCH_TREES: + printf("Too many epoch tree\n"); + break; + case SD_STATUS_NO_UPDATED_EPOCH: + printf("There is no updated epoch\n"); + printf("Please run `shepherd mkfs` or wait until other nodes come in\n"); + break; + case SD_STATUS_MISSING_NODES: + printf("Too few nodes to start sheepdog\n"); + printf("Please wait until other nodes come in\n"); + break; + case SD_STATUS_EPOCH_CONFLICT: + printf("Cannot resolve where to start\n"); + printf("Objects seemed to be updated when split brain was occurred\n"); + break; + case SD_STATUS_UNKNOWN_ERROR: + printf("Unknown error has occurred\n"); + break; + case SD_STATUS_SHUTDOWN: + printf("shutdown\n"); + break; + } + printf("\n"); + printf("Ctime Epoch Id Nodes\n"); + nr_logs = rsp->data_length / sizeof(struct epoch_log); + for (i = 0; i < nr_logs; i++) { + int j; + char name[128]; + struct sheepdog_node_list_entry *entry; + + ti = logs[i].ctime >> 32; + localtime_r(&ti, &tm); + strftime(time, sizeof(time), "%y-%m-%d %H:%M:%S", &tm); + + printf("%s %6d %016" PRIx64, time, logs[i].epoch, logs[i].hval); + printf(" ["); + for (j = 0; j < logs[i].nr_nodes; j++) { + entry = logs[i].nodes + j; + printf("%s%s", + (j == 0) ? "" : ", ", + addr_to_str(name, sizeof(name), + entry->addr, entry->port)); + } + printf("]\n"); + } + break; + } default: ret = -1; break; @@ -1081,6 +1171,8 @@ int main(int argc, char **argv) type = INFO_OBJ; else if (!strcasecmp(optarg, "vm")) type = INFO_VM; + else if (!strcasecmp(optarg, "cluster")) + type = INFO_CLUSTER; else usage(1); break; -- 1.5.6.5 |