diff options
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 4 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 35 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 14 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 109 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 5 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 161 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 20 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server.c | 45 | 
9 files changed, 366 insertions, 28 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 808459cfb7c..4e4b73bf493 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -2784,8 +2784,8 @@ rpcsvc_actor_t gd_svc_cli_actors[] = {          [GLUSTER_CLI_STATUS_VOLUME]  = {"STATUS_VOLUME", GLUSTER_CLI_STATUS_VOLUME, glusterd_handle_status_volume, NULL, NULL},          [GLUSTER_CLI_MOUNT]         = { "MOUNT", GLUSTER_CLI_MOUNT, glusterd_handle_mount, NULL, NULL},          [GLUSTER_CLI_UMOUNT]        = { "UMOUNT", GLUSTER_CLI_UMOUNT, glusterd_handle_umount, NULL, NULL}, -        [GLUSTER_CLI_HEAL_VOLUME]  = { "HEAL_VOLUME", GLUSTER_CLI_HEAL_VOLUME, glusterd_handle_cli_heal_volume, NULL, NULL} - +        [GLUSTER_CLI_HEAL_VOLUME]  = { "HEAL_VOLUME", GLUSTER_CLI_HEAL_VOLUME, glusterd_handle_cli_heal_volume, NULL, NULL}, +        [GLUSTER_CLI_STATEDUMP_VOLUME] = {"STATEDUMP_VOLUME", GLUSTER_CLI_STATEDUMP_VOLUME, glusterd_handle_cli_statedump_volume, NULL, NULL},  };  struct rpcsvc_program gd_svc_cli_prog = { diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 4271fe2460e..bb8cccfbfeb 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1544,6 +1544,7 @@ glusterd_op_build_payload (dict_t **req)                  case GD_OP_STATUS_VOLUME:                  case GD_OP_REBALANCE:                  case GD_OP_HEAL_VOLUME: +                case GD_OP_STATEDUMP_VOLUME:                          {                                  dict_t  *dict = ctx;                                  dict_copy (dict, req_dict); @@ -2321,6 +2322,11 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = glusterd_op_stage_heal_volume (dict, op_errstr);                          break; +                case GD_OP_STATEDUMP_VOLUME: +                        ret = glusterd_op_stage_statedump_volume (dict, +                                                                  op_errstr); +                        break; +                  default:                          gf_log ("", GF_LOG_ERROR, "Unknown op %d",                                  op); @@ -2400,21 +2406,25 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,                          ret = glusterd_op_quota (dict, op_errstr);                          break; -               case GD_OP_LOG_LEVEL: -                       ret = glusterd_op_log_level (dict); -                       break; +                case GD_OP_LOG_LEVEL: +                        ret = glusterd_op_log_level (dict); +                        break; + +                case GD_OP_STATUS_VOLUME: +                        ret = glusterd_op_status_volume (dict, op_errstr, rsp_dict); +                        break; -               case GD_OP_STATUS_VOLUME: -                       ret = glusterd_op_status_volume (dict, op_errstr, rsp_dict); -                       break; +                case GD_OP_REBALANCE: +                        ret = glusterd_op_rebalance (dict, op_errstr, rsp_dict); +                        break; -               case GD_OP_REBALANCE: -                       ret = glusterd_op_rebalance (dict, op_errstr, rsp_dict); -                       break; +                case GD_OP_HEAL_VOLUME: +                        ret = glusterd_op_heal_volume (dict, op_errstr); +                        break; -               case GD_OP_HEAL_VOLUME: -                       ret = glusterd_op_heal_volume (dict, op_errstr); -                       break; +                case GD_OP_STATEDUMP_VOLUME: +                        ret = glusterd_op_statedump_volume (dict); +                        break;                  default:                          gf_log ("", GF_LOG_ERROR, "Unknown op %d", @@ -3516,6 +3526,7 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx)                  case GD_OP_STATUS_VOLUME:                  case GD_OP_REBALANCE:                  case GD_OP_HEAL_VOLUME: +                case GD_OP_STATEDUMP_VOLUME:                          dict_unref (ctx);                          break;                  case GD_OP_DELETE_VOLUME: diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index 4d7e687f2e9..615446a6251 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -470,6 +470,20 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,                  break;          } +        case GD_OP_STATEDUMP_VOLUME: +        { +                gf1_cli_statedump_vol_rsp rsp = {0,}; +                rsp.op_ret = op_ret; +                rsp.op_errno = errno; +                rsp.volname = ""; +                if (op_errstr) +                        rsp.op_errstr = op_errstr; +                else +                        rsp.op_errstr = ""; +                cli_rsp = &rsp; +                xdrproc = (xdrproc_t) xdr_gf1_cli_statedump_vol_rsp; +                break; +        }          case GD_OP_NONE:          case GD_OP_MAX:          { diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 3681d4b9565..e27d2209f44 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -4161,3 +4161,112 @@ glusterd_is_volume_replicate (glusterd_volinfo_t *volinfo)                  replicates = _gf_true;          return replicates;  } + +int +glusterd_set_dump_options (char *dumpoptions_path, char *options, +                           int option_cnt) +{ +        int     ret = -1; +        char    *dup_options = NULL; +        char    *option = NULL; +        char    *tmpptr = NULL; +        FILE    *fp = NULL; + +        if (0 == option_cnt) { +                ret = 0; +                goto out; +        } + +        fp = fopen (dumpoptions_path, "w"); +        if (!fp) { +                ret = -1; +                goto out; +        } +        dup_options = gf_strdup (options); +        gf_log ("", GF_LOG_INFO, "Recieved following statedump options: %s", +                dup_options); +        option = strtok_r (dup_options, " ", &tmpptr); +        while (option) { +                fprintf (fp, "%s=yes\n", option); +                option = strtok_r (NULL, " ", &tmpptr); +        } + +out: +        if (fp) +                fclose (fp); +        return ret; +} + +int +glusterd_brick_statedump (glusterd_volinfo_t *volinfo, +                          glusterd_brickinfo_t *brickinfo, +                          char *options, int option_cnt) +{ +        int                     ret = -1; +        xlator_t                *this = NULL; +        glusterd_conf_t         *conf = NULL; +        char                    pidfile_path[PATH_MAX] = {0,}; +        char                    path[PATH_MAX] = {0,}; +        char                    dumpoptions_path[PATH_MAX] = {0,}; +        FILE                    *pidfile = NULL; +        pid_t                   pid = -1; + +        this = THIS; +        GF_ASSERT (this); +        conf = this->private; +        GF_ASSERT (conf); + +        if (uuid_is_null (brickinfo->uuid)) { +                ret = glusterd_resolve_brick (brickinfo); +                if (ret) { +                        gf_log ("glusterd", GF_LOG_ERROR, +                                "Cannot resolve brick %s:%s", +                                brickinfo->hostname, brickinfo->path); +                        goto out; +                } +        } + +        if (uuid_compare (brickinfo->uuid, conf->uuid)) { +                ret = 0; +                goto out; +        } + +        GLUSTERD_GET_VOLUME_DIR (path, volinfo, conf); +        GLUSTERD_GET_BRICK_PIDFILE (pidfile_path, path, brickinfo->hostname, +                                    brickinfo->path); + +        pidfile = fopen (pidfile_path, "r"); +        if (!pidfile) { +                gf_log ("", GF_LOG_ERROR, "Unable to open pidfile: %s", +                        pidfile_path); +                ret = -1; +                goto out; +        } + +        ret = fscanf (pidfile, "%d", &pid); +        if (ret <= 0) { +                gf_log ("", GF_LOG_ERROR, "Unable to get pid of brick process"); +                ret = -1; +                goto out; +        } + +        snprintf (dumpoptions_path, sizeof (dumpoptions_path), +                  "/tmp/glusterdump.%d.options", pid); +        glusterd_set_dump_options (dumpoptions_path, options, option_cnt); + + +        gf_log ("", GF_LOG_INFO, "Performing statedump on brick with pid %d", +                pid); + +        kill (pid, SIGUSR1); + +        sleep (1); +        unlink (dumpoptions_path); + +        ret = 0; +out: +        if (pidfile) +                fclose (pidfile); +        return ret; +} + diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index aca46eae120..3cc137e0579 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -352,6 +352,11 @@ glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo,  gf_boolean_t  glusterd_is_fuse_available (); +int +glusterd_brick_statedump (glusterd_volinfo_t *volinfo, +                          glusterd_brickinfo_t *brickinfo, +                          char *options, int option_cnt); +  gf_boolean_t  glusterd_is_volume_replicate (glusterd_volinfo_t *volinfo);  gf_boolean_t diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index e1934493a6b..13c1bffa090 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -193,6 +193,7 @@ static struct volopt_map_entry glusterd_volopt_map[] = {          {VKEY_FEATURES_QUOTA,                    "features/marker",           "quota", "off", NO_DOC, OPT_FLAG_FORCE},          {VKEY_FEATURES_LIMIT_USAGE,              "features/quota",            "limit-set", NULL, NO_DOC, 0},          {"features.quota-timeout",               "features/quota",            "timeout", "0", DOC, 0}, +        {"server.statedump-path",                "protocol/server",           "statedump-path", NULL, NO_DOC, 0},          {NULL,                                                                }  }; diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 816ef9b184e..21e7973863a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -447,6 +447,65 @@ out:          return ret;  } +int +glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req) +{ +        int32_t                         ret = -1; +        gf1_cli_statedump_vol_req       cli_req = {0,}; +        char                            *dup_volname = NULL; +        char                            *dup_options = NULL; +        dict_t                          *dict = NULL; + +        GF_ASSERT (req); + +        ret = -1; +        if (!xdr_to_generic (req->msg[0], &cli_req, +                             (xdrproc_t)xdr_gf1_cli_statedump_vol_req)) { +                req->rpc_err = GARBAGE_ARGS; +                goto out; +        } +        gf_log ("glusterd", GF_LOG_INFO, "Recieved statedump request for " +                "volume %s with options %s", cli_req.volname, cli_req.options); +        dict = dict_new (); + +        if (!dict) +                goto out; + +        dup_volname = gf_strdup (cli_req.volname); +        if (!dup_volname) +                goto out; +        ret = dict_set_dynstr (dict, "volname", dup_volname); +        if (ret) +                goto out; + +        dup_options = gf_strdup(cli_req.options); +        if (!dup_volname) +                goto out; +        ret = dict_set_dynstr (dict, "options", dup_options); +        if (ret) +                goto out; + +        ret = dict_set_int32 (dict, "option_cnt", cli_req.option_cnt); +        if (ret) +                goto out; + +        ret = glusterd_op_begin (req, GD_OP_STATEDUMP_VOLUME, dict); + +        gf_cmd_log ("statedump", "on volume %s %s", cli_req.volname, +                    ((0 == ret) ? "SUCCEEDED" : "FAILED")); + +out: +        if (ret && dict) +                dict_unref (dict); +        if (cli_req.volname) +                free (cli_req.volname); +        if (cli_req.options) +                free (cli_req.options); +        glusterd_friend_sm (); +        glusterd_op_sm(); + +        return ret; +}  /* op-sm */  int @@ -610,6 +669,37 @@ out:  }  int +glusterd_op_statedump_volume_args_get (dict_t *dict, char **volname, +                                       char **options, int *option_cnt) +{ +        int ret = -1; + +        if (!dict || !volname || !options || !option_cnt) +                goto out; + +        ret = dict_get_str (dict, "volname", volname); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to get volname"); +                goto out; +        } + +        ret = dict_get_str (dict, "options", options); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to get options"); +                goto out; +        } + +        ret = dict_get_int32 (dict, "option_cnt", option_cnt); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to get option count"); +                goto out; +        } + +out: +        return ret; +} + +int  glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr)  {          int                                     ret = 0; @@ -905,6 +995,46 @@ out:  }  int +glusterd_op_stage_statedump_volume (dict_t *dict, char **op_errstr) +{ +        int                     ret = -1; +        char                    *volname = NULL; +        char                    *options = NULL; +        int                     option_cnt = 0; +        gf_boolean_t            is_running = _gf_false; +        glusterd_volinfo_t      *volinfo = NULL; +        char                    msg[2408] = {0,}; + +        ret = glusterd_op_statedump_volume_args_get (dict, &volname, &options, +                                                     &option_cnt); +        if (ret) +                goto out; + +        ret = glusterd_volinfo_find (volname, &volinfo); +        if (ret) { +                snprintf (msg, sizeof(msg), "Volume %s does not exist", +                          volname); +                gf_log ("", GF_LOG_ERROR, "%s", msg); +                *op_errstr = gf_strdup (msg); +                goto out; +        } + +        is_running = glusterd_is_volume_started (volinfo); +        if (!is_running) { +                snprintf (msg, sizeof(msg), "Volume %s is not in a started" +                          " state", volname); +                gf_log ("", GF_LOG_ERROR, "%s", msg); +                *op_errstr = gf_strdup (msg); +                ret = -1; +                goto out; +        } + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int  glusterd_op_create_volume (dict_t *dict, char **op_errstr)  {          int                   ret        = 0; @@ -1204,3 +1334,34 @@ glusterd_op_heal_volume (dict_t *dict, char **op_errstr)          return ret;  } + +int +glusterd_op_statedump_volume (dict_t *dict) +{ +        int                     ret = 0; +        char                    *volname = NULL; +        char                    *options = NULL; +        int                     option_cnt = 0; +        glusterd_volinfo_t      *volinfo = NULL; +        glusterd_brickinfo_t    *brickinfo = NULL; + +        ret = glusterd_op_statedump_volume_args_get (dict, &volname, &options, +                                                     &option_cnt); +        if (ret) +                goto out; + +        ret = glusterd_volinfo_find (volname, &volinfo); +        if (ret) +                goto out; +        gf_log ("", GF_LOG_DEBUG, "Performing statedump on volume %s", volname); +        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                ret = glusterd_brick_statedump (volinfo, brickinfo, options, +                                                option_cnt); +                if (ret) +                        goto out; +        } + +out: +        return ret; +} + diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index f5a10189b0e..203f6e975c7 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -80,6 +80,7 @@ typedef enum glusterd_op_ {          GD_OP_STATUS_VOLUME,          GD_OP_REBALANCE,          GD_OP_HEAL_VOLUME, +        GD_OP_STATEDUMP_VOLUME,          GD_OP_MAX,  } glusterd_op_t; @@ -541,17 +542,9 @@ glusterd_handle_log_level (rpcsvc_request_t *req);  /* handler functions */  int32_t glusterd_op_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx); -int glusterd_handle_gsync_set (rpcsvc_request_t *req); -int glusterd_handle_quota (rpcsvc_request_t *req); -int glusterd_handle_replace_brick (rpcsvc_request_t *req); -int glusterd_handle_log_filename (rpcsvc_request_t *req); -int glusterd_handle_log_locate (rpcsvc_request_t *req); -int glusterd_handle_log_level (rpcsvc_request_t *req); -int glusterd_handle_log_rotate (rpcsvc_request_t *req); -int glusterd_handle_create_volume (rpcsvc_request_t *req); -int glusterd_handle_cli_start_volume (rpcsvc_request_t *req); -int glusterd_handle_cli_stop_volume (rpcsvc_request_t *req); -int glusterd_handle_cli_delete_volume (rpcsvc_request_t *req); +/* removed other definitions as they have been defined elsewhere in this file*/ + +int glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req);  int glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr,                                    size_t len, int cmd, defrag_cbk_fn_t cbk); @@ -590,12 +583,15 @@ int glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr);  int glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr);  int glusterd_op_rebalance (dict_t *dict, char **op_errstr, dict_t *rsp_dict); +int glusterd_op_stage_statedump_volume (dict_t *dict, char **op_errstr); +int glusterd_op_statedump_volume (dict_t *dict);  /* misc */  void glusterd_do_replace_brick (void *data);  int glusterd_op_perform_remove_brick (glusterd_volinfo_t  *volinfo, char *brick,                                        int force, int *need_migrate);  int glusterd_op_stop_volume_args_get (dict_t *dict, char** volname, int *flags); - +int glusterd_op_statedump_volume_args_get (dict_t *dict, char **volname, +                                           char **options, int *option_cnt);  #endif diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index ec91ba7c21a..3b1f46ad397 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -508,7 +508,7 @@ reconfigure (xlator_t *this, dict_t *options)          gf_boolean_t              trace;          data_t                   *data;          int                       ret = 0; - +        char                     *statedump_path = NULL;          conf = this->private;          if (!conf) { @@ -536,6 +536,27 @@ reconfigure (xlator_t *this, dict_t *options)  			" to %d", conf->trace);  	} + +        /*ret = dict_get_str (options, "statedump-path", &statedump_path); +        if (!ret) { +                gf_path_strip_trailing_slashes (statedump_path); +                if (this->ctx->statedump_path) +                        GF_FREE (this->ctx->statedump_path); +                this->ctx->statedump_path = gf_strdup (statedump_path); +        }*/ +        GF_OPTION_RECONF ("statedump-path", statedump_path, +                          options, path, out); +        if (!statedump_path) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Error while reconfiguring statedump path"); +                ret = -1; +                goto out; +        } +        gf_path_strip_trailing_slashes (statedump_path); +        if (this->ctx->statedump_path) +                GF_FREE (this->ctx->statedump_path); +        this->ctx->statedump_path = gf_strdup (statedump_path); +          if (!conf->auth_modules)                  conf->auth_modules = dict_new (); @@ -582,7 +603,7 @@ init (xlator_t *this)          int32_t            ret      = -1;          server_conf_t     *conf     = NULL;          rpcsvc_listener_t *listener = NULL; - +        char              *statedump_path = NULL;          GF_VALIDATE_OR_GOTO ("init", this, out);          if (this->children == NULL) { @@ -614,6 +635,22 @@ init (xlator_t *this)          if (ret)                  conf->conf_dir = CONFDIR; +        /*ret = dict_get_str (this->options, "statedump-path", &statedump_path); +        if (!ret) { +                gf_path_strip_trailing_slashes (statedump_path); +                this->ctx->statedump_path = statedump_path; +        }*/ +        GF_OPTION_INIT ("statedump-path", statedump_path, path, out); +        if (statedump_path) { +                gf_path_strip_trailing_slashes (statedump_path); +                this->ctx->statedump_path = gf_strdup (statedump_path); +        } else { +                gf_log (this->name, GF_LOG_ERROR, +                        "Error setting statedump path"); +                ret = -1; +                goto out; +        } +          /* Authentication modules */          conf->auth_modules = dict_new ();          GF_VALIDATE_OR_GOTO(this->name, conf->auth_modules, out); @@ -818,5 +855,9 @@ struct volume_options options[] = {          { .key   = {"rpc-auth-allow-insecure"},            .type  = GF_OPTION_TYPE_BOOL,          }, +        { .key           = {"statedump-path"}, +          .type          = GF_OPTION_TYPE_PATH, +          .default_value = "/tmp" +        },          { .key   = {NULL} },  };  | 
