On Sat, Oct 19, 2013 at 11:35:33PM +0900, Hitoshi Mitake wrote: > This patch adds two new opcode for runtime loglevel changes and let > dog support the changing from command line. This is useful for making > sheep process verbose temporally and can make troubleshooting easier. > > Example of usage: > > $ dog node loglevel list > emerg (0) > alert (1) > crit (2) > err (3) > warning (4) > notice (5) > info (6) > debug (7) > $ dog node loglevel get > info (6) > $ dog node loglevel set debug # <- change loglevel from info to debug > $ dog node loglevel get > debug (7) > > Signed-off-by: Hitoshi Mitake <mitake.hito...@lab.ntt.co.jp> > --- > CHANGELOG.md | 8 +++-- > dog/common.c | 84 > ++++++++++++++++++++++++++++++++++++++++++++++++ > dog/dog.h | 5 +++ > dog/node.c | 79 ++++++++++++++++++++++++++++++++++++++++++++- > include/internal_proto.h | 2 ++ > include/logger.h | 3 ++ > lib/logger.c | 12 +++++++ > sheep/ops.c | 43 +++++++++++++++++++++++++ > 8 files changed, 233 insertions(+), 3 deletions(-) > > diff --git a/CHANGELOG.md b/CHANGELOG.md > index 98d221e..771d69b 100644 > --- a/CHANGELOG.md > +++ b/CHANGELOG.md > @@ -3,9 +3,13 @@ > > DOG COMMAND INTERFACE: > - new subcommand "vdi cache purge" for cleaning stale object cache > - -- "vdi cache purge" cleans stale cache of all images > - -- "vdi cache purge <image>" cleans stale cache of the specified image > + - "vdi cache purge" cleans stale cache of all images > + - "vdi cache purge <image>" cleans stale cache of the specified image > - new subcommand "node stat" for showing I/O status of the node > + - new subcommand "node loglevel" for changing log level at runtime > + - "node loglevel set" sets loglevel of running sheep process > + - "node loglevel get" gets loglevel from running sheep process > + - "node loglevel list" lists avialable loglevels > > SHEEP COMMAND INTERFACE: > - improvements of help messages > diff --git a/dog/common.c b/dog/common.c > index 5e7ce2e..44e116d 100644 > --- a/dog/common.c > +++ b/dog/common.c > @@ -351,3 +351,87 @@ bool is_erasure_oid(uint64_t oid, uint8_t policy) > return false; > return true; > } > + > +static const char *loglevel_table[] = { > + "emerg", > + "alert", > + "crit", > + "err", > + "warning", > + "notice", > + "info", > + "debug", > +}; /* index is log level */ > + > +int do_loglevel_set(const struct node_id *nid, const char *loglevel_str) > +{ > + int32_t loglevel = -1; > + int ret; > + struct sd_req hdr; > + struct sd_rsp *rsp = (struct sd_rsp *)&hdr; > + > + for (int i = 0; i < ARRAY_SIZE(loglevel_table); i++) { > + if (!strcmp(loglevel_table[i], loglevel_str)) { > + loglevel = i; > + break; > + } > + } > + > + if (loglevel == -1) > + return EXIT_USAGE; > + > + sd_init_req(&hdr, SD_OP_SET_LOGLEVEL); > + hdr.flags = SD_FLAG_CMD_WRITE; > + hdr.data_length = sizeof(loglevel); > + > + ret = dog_exec_req(nid, &hdr, &loglevel); > + if (ret < 0) > + return EXIT_SYSFAIL; > + > + if (rsp->result != SD_RES_SUCCESS) > + return EXIT_FAILURE; > + > + return EXIT_SUCCESS; > +} > + > +int do_loglevel_get(const struct node_id *nid, int32_t *ret_loglevel) > +{ > + int32_t loglevel = -1; > + int ret; > + struct sd_req hdr; > + struct sd_rsp *rsp = (struct sd_rsp *)&hdr; > + > + sd_init_req(&hdr, SD_OP_GET_LOGLEVEL); > + hdr.data_length = sizeof(loglevel); > + > + ret = dog_exec_req(nid, &hdr, &loglevel); > + if (ret < 0) > + return EXIT_SYSFAIL; > + > + if (rsp->result != SD_RES_SUCCESS) > + return EXIT_FAILURE; > + > + *ret_loglevel = loglevel; > + > + return EXIT_SUCCESS; > +} > + > +const char *loglevel_to_str(int loglevel) > +{ > + for (int i = 0; i < ARRAY_SIZE(loglevel_table); i++) { > + if (i == loglevel) > + return loglevel_table[i]; > + } > + > + return "unknown loglevel"; > +} > + > +void dump_loglevels(bool err) > +{ > + for (int i = 0; i < ARRAY_SIZE(loglevel_table); i++) { > + if (err) > + sd_err("%s\t(%d)", loglevel_table[i], i); > + else > + sd_info("%s\t(%d)", loglevel_table[i], i); > + } > +} > diff --git a/dog/dog.h b/dog/dog.h > index 769fc6c..28c36a1 100644 > --- a/dog/dog.h > +++ b/dog/dog.h > @@ -95,4 +95,9 @@ extern struct command cluster_command; > #define trace_command {} > #endif /* HAVE_TRACE */ > > +int do_loglevel_set(const struct node_id *nid, const char *loglevel_str); > +int do_loglevel_get(const struct node_id *nid, int32_t *ret_loglevel); > +const char *loglevel_to_str(int loglevel); > +void dump_loglevels(bool err); > + > #endif > diff --git a/dog/node.c b/dog/node.c > index 052739c..5f1b070 100644 > --- a/dog/node.c > +++ b/dog/node.c > @@ -420,7 +420,6 @@ static int node_md(int argc, char **argv) > return do_generic_subcommand(node_md_cmd, argc, argv); > } > > - > static int node_parser(int ch, const char *opt) > { > switch (ch) { > @@ -444,6 +443,82 @@ static struct sd_option node_options[] = { > { 0, NULL, false, NULL }, > }; > > +static int node_loglevel_set(int argc, char **argv) > +{ > + int ret = 0; > + char *loglevel_str = argv[optind]; > + > + ret = do_loglevel_set(&sd_nid, loglevel_str); > + switch (ret) { > + case EXIT_USAGE: > + sd_err("invalid loglevel: %s", loglevel_str); > + sd_err("available loglevels:"); > + dump_loglevels(true); > + > + ret = -1; > + break; > + case EXIT_FAILURE: > + case EXIT_SYSFAIL: > + sd_err("Failed to execute request"); > + ret = -1; > + break; > + case EXIT_SUCCESS: > + /* do nothing */ > + break; > + default: > + sd_err("unknown return code of do_loglevel_set(): %d", ret); > + ret = -1; > + break; > + }
I think set/get can share the same switch case handling. Thanks Yuan -- sheepdog mailing list sheepdog@lists.wpkg.org http://lists.wpkg.org/mailman/listinfo/sheepdog