diff options
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 9 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 4 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 30 | ||||
| -rw-r--r-- | xlators/debug/io-stats/src/io-stats.c | 193 | 
4 files changed, 161 insertions, 75 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 2dde1674..6c8d374e 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1672,7 +1672,7 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,          char    *delimiter      = NULL;          char    *opwords[]      = { "open", "read", "write", "opendir",                                      "readdir", "read-perf", "write-perf", -                                    NULL }; +                                    "clear", NULL };          char    *w = NULL;          GF_ASSERT (words); @@ -1717,6 +1717,13 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,          } else if (strcmp (w, "write-perf") == 0) {                  top_op = GF_CLI_TOP_WRITE_PERF;                  perf = 1; +        } else if (strcmp (w, "clear") == 0) { +                ret = dict_set_int32 (dict, "clear-stats", 1); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, +                                "Could not set clear-stats in dict"); +                        goto out; +                }          } else                  GF_ASSERT (!"opword mismatch");          ret = dict_set_int32 (dict, "top-op", (int32_t)top_op); diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index bad9351f..704f9ddd 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1890,8 +1890,8 @@ struct cli_cmd volume_cmds[] = {            "quota translator specific operations"},           { "volume top <VOLNAME> {[open|read|write|opendir|readdir [nfs]] " -           "|[read-perf|write-perf [nfs|{bs <size> count <count>}]]} " -           " [brick <brick>] [list-cnt <count>]", +           "|[read-perf|write-perf [nfs|{bs <size> count <count>}]]" +           "|[clear [nfs]]} [brick <brick>] [list-cnt <count>]",             cli_cmd_volume_top_cbk,             "volume top operations"}, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index e54d4d21..9737e13f 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -4048,7 +4048,7 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,          gf_cli_rsp                        rsp   = {0,};          int                               ret   = -1;          dict_t                            *dict = NULL; -        gf1_cli_stats_op                op = GF_CLI_STATS_NONE; +        gf1_cli_stats_op                  op = GF_CLI_STATS_NONE;          char                              key[256] = {0};          int                               i = 0;          int32_t                           brick_count = 0; @@ -4056,7 +4056,7 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,          int32_t                           members = 0;          char                              *filename;          char                              *bricks; -        uint64_t                           value = 0; +        uint64_t                          value = 0;          int32_t                           j = 0;          gf1_cli_top_op                    top_op = GF_CLI_TOP_NONE;          uint64_t                          nr_open = 0; @@ -4064,10 +4064,13 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,          double                            throughput = 0;          double                            time = 0;          long int                          time_sec = 0; -        long int                           time_usec = 0; +        long int                          time_usec = 0;          struct tm                         *tm = NULL;          char                              timestr[256] = {0, };          char                              *openfd_str = NULL; +        gf_boolean_t                      nfs = _gf_false; +        gf_boolean_t                      clear_stats = _gf_false; +        int                               stats_cleared = 0;          if (-1 == req->rpc_status) {                  goto out; @@ -4132,14 +4135,31 @@ gf_cli3_1_top_volume_cbk (struct rpc_req *req, struct iovec *iov,          ret = dict_get_int32 (dict, key, (int32_t*)&top_op);          if (ret)                  goto out; + +        clear_stats = dict_get_str_boolean (dict, "clear-stats", _gf_false); +          while (i < brick_count) {                  i++;                  snprintf (brick, sizeof (brick), "%d-brick", i);                  ret = dict_get_str (dict, brick, &bricks);                  if (ret)                          goto out; -                ret = dict_get_str_boolean (dict, "nfs", _gf_false); -                if (ret) + +                nfs = dict_get_str_boolean (dict, "nfs", _gf_false); + +                if (clear_stats) { +                        memset (key, 0, sizeof (key)); +                        snprintf (key, sizeof (key), "%d-stats-cleared", i); +                        ret = dict_get_int32 (dict, key, &stats_cleared); +                        if (ret) +                                goto out; +                        cli_out (stats_cleared ? "Cleared stats for %s %s" : +                                 "Failed to clear stats for %s %s", +                                 nfs ? "NFS server on" : "brick", bricks); +                        continue; +                } + +                if (nfs)                          cli_out ("NFS Server : %s", bricks);                  else                          cli_out ("Brick: %s", bricks); diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c index 7466f82e..be465620 100644 --- a/xlators/debug/io-stats/src/io-stats.c +++ b/xlators/debug/io-stats/src/io-stats.c @@ -58,7 +58,7 @@ typedef enum {          IOS_STATS_TYPE_READDIRP,          IOS_STATS_TYPE_READ_THROUGHPUT,          IOS_STATS_TYPE_WRITE_THROUGHPUT, -        IOS_STATS_TYPE_MAX, +        IOS_STATS_TYPE_MAX  }ios_stats_type_t;  typedef enum { @@ -1270,6 +1270,16 @@ io_stats_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          ios_fd_ctx_set (fd, this, iosfd);          ios_inode_ctx_get (fd->inode, this, &iosstat); +        if (!iosstat) { +                iosstat = GF_CALLOC (1, sizeof (*iosstat), +                                     gf_io_stats_mt_ios_stat); +                if (iosstat) { +                        iosstat->filename = gf_strdup (path); +                        uuid_copy (iosstat->gfid, fd->inode->gfid); +                        LOCK_INIT (&iosstat->lock); +                        ios_inode_ctx_set (fd->inode, this, iosstat); +                } +        }          LOCK (&conf->lock);          { @@ -2442,6 +2452,95 @@ io_stats_forget (xlator_t *this, inode_t *inode)          return 0;  } +static int +ios_init_top_stats (struct ios_conf *conf) +{ +        int     i = 0; + +        GF_ASSERT (conf); + +        for (i = 0; i <IOS_STATS_TYPE_MAX; i++) { +                conf->list[i].iosstats = GF_CALLOC (1, +                                         sizeof(*conf->list[i].iosstats), +                                         gf_io_stats_mt_ios_stat); + +                if (!conf->list[i].iosstats) +                        return -1; + +                INIT_LIST_HEAD(&conf->list[i].iosstats->list); +                LOCK_INIT (&conf->list[i].lock); +        } + +	for (i = 0; i < IOS_STATS_THRU_MAX; i ++) { +		conf->thru_list[i].iosstats = GF_CALLOC (1, +		                 sizeof (*conf->thru_list[i].iosstats), +				 gf_io_stats_mt_ios_stat); + +	        if (!conf->thru_list[i].iosstats) +                        return -1; + +		INIT_LIST_HEAD(&conf->thru_list[i].iosstats->list); +		LOCK_INIT (&conf->thru_list[i].lock); +        } + +        return 0; +} + +static void +ios_destroy_top_stats (struct ios_conf *conf) +{ +        int                     i = 0; +        struct ios_stat_head    *list_head = NULL; +        struct ios_stat_list    *entry     = NULL; +        struct ios_stat_list    *tmp       = NULL; +        struct ios_stat_list    *list      = NULL; +        struct ios_stat         *stat      = NULL; + +        GF_ASSERT (conf); + +        LOCK (&conf->lock); + +        conf->cumulative.nr_opens = 0; +        conf->cumulative.max_nr_opens = 0; +        conf->cumulative.max_openfd_time.tv_sec = 0; +        conf->cumulative.max_openfd_time.tv_usec = 0; + +        for (i = 0; i < IOS_STATS_TYPE_MAX; i++) { +                list_head = &conf->list[i]; +                if (!list_head) +                        continue; +                list_for_each_entry_safe (entry, tmp, +                                          &list_head->iosstats->list, list) { +                        list = entry; +                        stat = list->iosstat; +                        ios_stat_unref (stat); +                        list_del (&list->list); +                        if (list) +                                GF_FREE (list); +                        list_head->members--; +                } +        } + +        for (i = 0; i < IOS_STATS_THRU_MAX; i++) { +                list_head = &conf->thru_list[i]; +                if (!list_head) +                        continue; +                list_for_each_entry_safe (entry, tmp, +                                          &list_head->iosstats->list, list) { +                        list = entry; +                        stat = list->iosstat; +                        ios_stat_unref (stat); +                        list_del (&list->list); +                        if (list) +                                GF_FREE (list); +                        list_head->members--; +                } +        } + +        UNLOCK (&conf->lock); + +        return; +}  int  reconfigure (xlator_t *this, dict_t *options) @@ -2509,7 +2608,6 @@ int  init (xlator_t *this)  {          struct ios_conf    *conf = NULL; -        int                 i = 0;          char               *sys_log_str = NULL;          int                 sys_log_level = -1;          char               *log_str = NULL; @@ -2546,35 +2644,9 @@ init (xlator_t *this)          gettimeofday (&conf->cumulative.started_at, NULL);          gettimeofday (&conf->incremental.started_at, NULL); -        for (i = 0; i <IOS_STATS_TYPE_MAX; i++) { -                conf->list[i].iosstats = GF_CALLOC (1, -                                         sizeof(*conf->list[i].iosstats), -                                         gf_io_stats_mt_ios_stat); - -                if (!conf->list[i].iosstats) { -                        gf_log (this->name, GF_LOG_ERROR, -                               "Out of memory"); -                        return -1; -                } - -                INIT_LIST_HEAD(&conf->list[i].iosstats->list); -                LOCK_INIT (&conf->list[i].lock); -        } - -	for (i = 0; i < IOS_STATS_THRU_MAX; i ++) { -		conf->thru_list[i].iosstats = GF_CALLOC (1, -		                 sizeof (*conf->thru_list[i].iosstats), -				 gf_io_stats_mt_ios_stat); - -	        if (!conf->thru_list[i].iosstats) { -        	        gf_log (this->name, GF_LOG_ERROR, -                        "Out of memory"); -                	return -1; -        	} - -		INIT_LIST_HEAD(&conf->thru_list[i].iosstats->list); -		LOCK_INIT (&conf->thru_list[i].lock); -        } +        ret = ios_init_top_stats (conf); +        if (ret) +                return -1;          GF_OPTION_INIT ("dump-fd-stats", conf->dump_fd_stats, bool, out); @@ -2606,12 +2678,6 @@ void  fini (xlator_t *this)  {          struct ios_conf *conf = NULL; -        struct ios_stat_head *list_head = NULL; -        struct ios_stat_list *entry     = NULL; -        struct ios_stat_list *tmp       = NULL; -        struct ios_stat_list *list      = NULL; -        struct ios_stat      *stat      = NULL; -        int    i                        = 0;          if (!this)                  return; @@ -2622,35 +2688,7 @@ fini (xlator_t *this)                  return;          this->private = NULL; -        for (i = 0; i < IOS_STATS_TYPE_MAX; i++) { -                list_head = &conf->list[i]; -                if (!list_head) -                        continue; -                list_for_each_entry_safe (entry, tmp, -                                          &list_head->iosstats->list, list) { -                        list = entry; -                        stat = list->iosstat; -                        ios_stat_unref (stat); -                        list_del (&list->list); -                        if (list) -                                GF_FREE (list); -                } -        } - -        for (i = 0; i < IOS_STATS_THRU_MAX; i++) { -                list_head = &conf->thru_list[i]; -                if (!list_head) -                        continue; -                list_for_each_entry_safe (entry, tmp, -                                          &list_head->iosstats->list, list) { -                        list = entry; -                        stat = list->iosstat; -                        ios_stat_unref (stat); -                        list_del (&list->list); -                        if (list) -                                GF_FREE (list); -                } -        } +        ios_destroy_top_stats (conf);          if (conf)                  GF_FREE(conf); @@ -2660,7 +2698,6 @@ fini (xlator_t *this)          return;  } -  int  notify (xlator_t *this, int32_t event, void *data, ...)  { @@ -2680,6 +2717,28 @@ notify (xlator_t *this, int32_t event, void *data, ...)          va_end (ap);          switch (event) {          case GF_EVENT_TRANSLATOR_INFO: +                ret = dict_get_str_boolean (dict, "clear-stats", _gf_false); +                if (ret) { +                         ret = dict_set_int32 (output, "top-op", top_op); +                        if (ret) { +                                gf_log (this->name, GF_LOG_ERROR, +                                        "Failed to set top-op in dict"); +                                goto out; +                        } +                        ios_destroy_top_stats (this->private); +                        ret = ios_init_top_stats (this->private); +                        if (ret) +                                gf_log (this->name, GF_LOG_ERROR, +                                        "Failed to reset top stats"); +                        ret = dict_set_int32 (output, "stats-cleared", +                                              ret ? 0 : 1); +                        if (ret) +                                gf_log (this->name, GF_LOG_ERROR, +                                        "Failed to set stats-cleared" +                                        " in dict"); +                        goto out; +                } +                  ret = dict_get_int32 (dict, "top-op", &top_op);                  if (!ret) {                          ret = dict_get_int32 (dict, "list-cnt", &list_cnt);  | 
