[sheepdog] [PATCH v2 1/2] sheep, dog: runtime loglevel changing

Hitoshi Mitake mitake.hitoshi at gmail.com
Thu Oct 24 05:07:59 CEST 2013


On Tue, Oct 22, 2013 at 4:19 PM, Hitoshi Mitake
<mitake.hitoshi at gmail.com> wrote:
> At Tue, 22 Oct 2013 14:14:28 +0800,
> Liu Yuan wrote:
>>
>> 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.hitoshi at 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 for your pointing. I'll merge the two switch statements into one in v3.
>

On the second thought, these two switches are hard to merge (merging
will produce needless complexity). I'll leave them as is.

Thanks,
Hitoshi



More information about the sheepdog mailing list