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

Liu Yuan namei.unix at gmail.com
Tue Oct 22 08:14:28 CEST 2013


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
Yuan



More information about the sheepdog mailing list