diff options
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 7 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 278 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 188 | 
3 files changed, 247 insertions, 226 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 287943777df..5e619f3cd17 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -3532,12 +3532,13 @@ cli_snap_status_parse (dict_t *dict, const char **words, int wordcount)  out:          if (ret == 0) { -                ret = dict_set_int32 (dict, "cmd", cmd); +                ret = dict_set_int32 (dict, "status-cmd", cmd);                  if (ret) {                          gf_log ("cli", GF_LOG_ERROR, "Could not save cmd "                                  "of snapshot status");                  }          } +          return ret;  } @@ -3812,7 +3813,9 @@ cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,          } else if (!strcmp (w, "deactivate")) {                  type = GF_SNAP_OPTION_TYPE_DEACTIVATE;          } -        if (type != GF_SNAP_OPTION_TYPE_CONFIG) { + +        if (type != GF_SNAP_OPTION_TYPE_CONFIG && +            type != GF_SNAP_OPTION_TYPE_STATUS) {                  ret = dict_set_int32 (dict, "hold_snap_locks", _gf_true);                  if (ret) {                          gf_log ("cli", GF_LOG_ERROR, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 9312f15dc20..37424c68559 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -82,6 +82,9 @@ char *cli_vol_task_status_str[] = {"not started",  };  int32_t +gf_cli_snapshot (call_frame_t *frame, xlator_t *this, void *data); + +int32_t  gf_cli_get_volume (call_frame_t *frame, xlator_t *this,                        void *data); @@ -7636,14 +7639,13 @@ out:  }  int32_t -cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict, call_frame_t *frame) +cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict)  {          int32_t       ret        = -1;          char         *snap_name  = NULL;          GF_ASSERT (rsp);          GF_ASSERT (dict); -        GF_ASSERT (frame);          if (rsp->op_ret) {                  cli_err("snapshot delete: failed: %s", @@ -8361,99 +8363,128 @@ out:  }  int -cli_snap_status_all (dict_t *dict) { +cli_populate_req_dict_for_status (dict_t *snap_dict, dict_t *dict, int index) {          int             ret             =       -1;          char            key[PATH_MAX]   =       ""; +        char            *buffer         =       NULL; +        int             type            =       0;          int             snapcount       =       0; -        int             i               =       0; +        GF_ASSERT (snap_dict);          GF_ASSERT (dict); -        ret = dict_get_int32 (dict, "status.snapcount", &snapcount); +        ret = dict_set_uint32 (snap_dict, "status-cmd", +                               GF_SNAP_STATUS_TYPE_SNAP);          if (ret) { -                gf_log ("cli", GF_LOG_ERROR, "Could not get snapcount"); +                gf_log ("cli", GF_LOG_ERROR, "Could not save command " +                        "type in snap dict");                  goto out;          } -        if (snapcount == 0) { -                cli_out ("No snapshots present"); +        ret = snprintf (key, sizeof (key), "status.snap%d.snapname", index); +         if (ret < 0) { +                 goto out; +         } + +        ret = dict_get_str (dict, key, &buffer); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Could not get snapname"); +                goto out;          } -        for (i = 0 ; i < snapcount; i++) { -                ret = snprintf (key, sizeof (key), "status.snap%d",i); -                if (ret < 0) { -                        goto out; -                } -                ret = cli_get_single_snap_status (dict, key); +        ret = dict_set_str (snap_dict, "snapname", buffer); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Could not save snapname " +                        "in snap dict"); +                goto out; +          } + +        ret = dict_set_int32 (snap_dict, "type", GF_SNAP_OPTION_TYPE_STATUS); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, +                        "Could not save command type"); +                goto out; +        } + +        ret = dict_set_dynstr_with_alloc (snap_dict, "cmd-str", +                                       "snapshot status"); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, +                        "Could not save command string as status"); +                goto out; +        } + +        ret = dict_set_int32 (snap_dict, "hold_vol_locks", _gf_false); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, +                        "Setting volume lock flag failed"); +                goto out; +        } +  out:          return ret;  } -  int -cli_snapshot_status_display (dict_t *dict, gf_cli_rsp *rsp) +cli_snapshot_status (dict_t *dict, gf_cli_rsp *rsp, +                             call_frame_t *frame)  {          char            key[PATH_MAX]   =       "";          int             ret             =       -1;          int             status_cmd      =       -1; +        cli_local_t     *local          =       NULL;          GF_ASSERT (dict);          GF_ASSERT (rsp); +        GF_ASSERT (frame); + +        local = ((call_frame_t *) frame) -> local; +        if (!local) { +                gf_log ("cli", GF_LOG_ERROR, "frame->local is NULL"); +                goto out; +        }          if (rsp->op_ret) { -                cli_err ("Snapshot Status : failed: %s", -                        rsp->op_errstr ? rsp->op_errstr : -                        "Please check log file for details"); +                if (rsp->op_errstr) { +                        ret = dict_set_dynstr_with_alloc (local->dict, +                                                          "op_err_str", +                                                          rsp->op_errstr); +                        if (ret) { +                                gf_log ("cli", GF_LOG_ERROR, "Failed to set " +                                        "op_errstr in local dictionary"); +                                goto out; +                        } +                }                  ret = rsp->op_ret;                  goto out;          } -        ret = dict_get_int32 (dict, "cmd", &status_cmd); +        ret = dict_get_int32 (dict, "status-cmd", &status_cmd);          if (ret) {                  gf_log ("cli", GF_LOG_ERROR, "Could not fetch status type");                  goto out;          } -        switch (status_cmd) { -                case GF_SNAP_STATUS_TYPE_ALL: -                { -                        ret = cli_snap_status_all (dict); -                        if (ret) { -                                gf_log ("cli", GF_LOG_ERROR, "Could not fetch " -                                        "status of all snap"); -                                goto out; -                        } -                break; -                } -                case GF_SNAP_STATUS_TYPE_SNAP: -                { -                        ret = snprintf (key, sizeof (key), "status.snap0"); -                        if (ret < 0) { -                                goto out; -                        } -                        ret = cli_get_single_snap_status (dict, key); -                        if (ret) { -                                gf_log ("cli", GF_LOG_ERROR, "Could not fetch " -                                        "status of snap"); -                                goto out; -                        } -                break; -                } +        if (status_cmd != GF_SNAP_STATUS_TYPE_SNAP) { +                dict_copy (dict, local->dict); +                goto out; +        } -                case GF_SNAP_STATUS_TYPE_VOL: -                { -                        ret = cli_snap_status_all (dict); -                        if (ret) { -                                gf_log ("cli", GF_LOG_ERROR, "Could not fetch " -                                        "status of snap in a volume"); -                                goto out; -                        } -                        break; -                } -                default: -                        break; + +        ret = snprintf (key, sizeof (key), "status.snap0"); +        if (ret < 0) { +                goto out;          } + +        ret = cli_get_single_snap_status (dict, key); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Could not fetch " +                        "status of snap"); +                goto out; +        } + +        ret = 0;  out:          return ret;  } @@ -8650,7 +8681,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                  break;          case GF_SNAP_OPTION_TYPE_DELETE: -                ret = cli_snapshot_remove_reply (&rsp, dict, frame); +                ret = cli_snapshot_remove_reply (&rsp, dict);                  if (ret) {                          gf_log ("cli", GF_LOG_ERROR,                                  "Failed to delete snap"); @@ -8659,7 +8690,7 @@ gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,                  break;          case GF_SNAP_OPTION_TYPE_STATUS: -                ret = cli_snapshot_status_display (dict, &rsp); +                ret = cli_snapshot_status (dict, &rsp, frame);                  if (ret) {                          gf_log ("cli", GF_LOG_ERROR, "Failed to display "                                  "snapshot status output."); @@ -8684,23 +8715,146 @@ out:  }  int32_t +gf_cli_snapshot_for_status (call_frame_t *frame, xlator_t *this, +                            void *data) +{ + +        gf_cli_req        req           = {{0,}}; +        dict_t           *options       = NULL; +        int               ret           = -1; +        int32_t           cmd           = -1; +        cli_local_t      *local         = NULL; +        dict_t           *snap_dict     = NULL; +        int              snapcount      =  0; +        int              i              =  0; + +        if (!frame || !this || !data) +                goto out; + +        if (frame->local) { +                local = frame->local; +        } else { +                goto out; +        } + +        options = data; + +        ret = dict_get_int32 (local->dict, "status-cmd", &cmd); + +        if (cmd == GF_SNAP_STATUS_TYPE_ALL || +            cmd == GF_SNAP_STATUS_TYPE_VOL) { + +                ret = dict_get_int32 (local->dict, "status.snapcount", +                                      &snapcount); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, "Could not get snapcount"); +                        goto out; +                } + +                if (snapcount == 0) { +                        cli_out ("No snapshots present"); +                } + +                for (i = 0 ; i < snapcount; i++) { +                        ret = -1; + +                        snap_dict = dict_new(); +                        if (!snap_dict) +                                goto out; + +                        ret = cli_populate_req_dict_for_status (snap_dict, +                                                               local->dict, i); +                        if (ret) { +                                gf_log ("cli", GF_LOG_ERROR, "Could not " +                                        "populate snap request dictionary"); +                                goto out; +                        } + +                        ret = cli_to_glusterd (&req, frame, +                                        gf_cli_snapshot_cbk, +                                       (xdrproc_t) xdr_gf_cli_req, snap_dict, +                                       GLUSTER_CLI_SNAP, this, cli_rpc_prog, +                                       NULL); + +                        /* Ignore the return value and error for snapshot +                         * status of type "ALL" or "VOL" +                         * +                         * Scenario : There might be case where status command +                         * and delete command might be issued at the same time. +                         * In that case when status tried to fetch detail of +                         * snap which has been deleted by concurrent command, +                         * then it will show snapshot not present. Which will +                         * not be appropriate. +                         */ +                        dict_unref (snap_dict); +                } +        } +out: +        return ret; + +        if (ret && snap_dict) +                dict_unref (snap_dict); +} + +int32_t  gf_cli_snapshot (call_frame_t *frame, xlator_t *this,                   void *data)  { -        gf_cli_req        req     = {{0,}}; -        dict_t           *options = NULL; -        int               ret     = -1; +        gf_cli_req        req           = {{0,}}; +        dict_t           *options       = NULL; +        int               ret           = -1; +        int               tmp_ret       = -1; +        cli_local_t      *local         = NULL; +        char             *err_str       = NULL; +        int              type           =  -1;          if (!frame || !this || !data)                  goto out; +        if (frame->local) { +                local = frame->local; +        } else { +                goto out; +        } +          options = data; +        ret = dict_get_int32 (local->dict, "type", &type); + +          ret = cli_to_glusterd (&req, frame, gf_cli_snapshot_cbk,                                 (xdrproc_t) xdr_gf_cli_req, options,                                 GLUSTER_CLI_SNAP, this, cli_rpc_prog,                                 NULL); +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "cli_to_glusterd for " +                        "snapshot failed"); +                goto out; +        } + +        if (GF_SNAP_OPTION_TYPE_STATUS == type) { +                ret = gf_cli_snapshot_for_status (frame, this, data); +                if (ret) { +                        gf_log ("cli", GF_LOG_ERROR, "cli to glusterd " +                                "for snapshot status command failed"); +                        goto out; +                } +        } + +        ret = 0; +  out: +        if (ret && GF_SNAP_OPTION_TYPE_STATUS == type) { +                tmp_ret = dict_get_str (local->dict, "op_err_str", &err_str); +                if (err_str) { +                        cli_err ("Snapshot Status : failed: %s", err_str); +                        dict_del (local->dict, "op_err_str"); +                } else { +                        cli_err ("Snapshot Status : failed: %s", "Please " +                                "check log file for details"); +                } +        } +          gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);          GF_FREE (req.dict.dict_val); diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index 58e423aab1c..a4c60a87d9e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -3099,155 +3099,15 @@ glusterd_handle_snapshot_status (rpcsvc_request_t *req, glusterd_op_t op,                                   dict_t *dict, char *err_str, size_t len)  {          int                     ret             =       -1; -        char                    *volname        =       NULL; -        char                    *snapname       =       NULL; -        char                    *buf            =       NULL; -        glusterd_conf_t         *conf           =       NULL;          xlator_t                *this           =       NULL; -        int32_t                 cmd             =       -1; -        int                     i               =       0; -        dict_t                  *voldict        =       NULL; -        char                    key[PATH_MAX]   =       ""; -        glusterd_volinfo_t     *volinfo         =       NULL; -        glusterd_snap_t         *snap           =       NULL; -        glusterd_volinfo_t      *snap_volinfo   =       NULL;          this = THIS;          GF_ASSERT (this); -        conf = this->private; -        GF_ASSERT (conf);          GF_ASSERT (req);          GF_ASSERT (dict);          GF_ASSERT (err_str); -        ret = dict_get_int32 (dict, "cmd", &cmd); -        if (ret) { -                gf_log (this->name, GF_LOG_ERROR, "Could not get status type"); -                goto out; -        } -        switch (cmd) { -                case GF_SNAP_STATUS_TYPE_ALL: -                { -                        /* IF we give "gluster snapshot status" -                         * then lock is held on all snaps. -                         * This is the place where necessary information -                         * (snapname and snapcount)is populated in dictionary -                         * for locking. -                         */ -                        ++i; -                        list_for_each_entry (snap, &conf->snapshots, snap_list) -                        { -                                snprintf (key, sizeof (key), "snapname%d", i); -                                buf = gf_strdup (snap->snapname); -                                if (!buf) { -                                        ret = -1; -                                        goto out; -                                } -                                ret = dict_set_dynstr (dict, key, buf); -                                if (ret) { -                                        gf_log (this->name, GF_LOG_ERROR, -                                                "Could not save snapname (%s) " -                                                "in the dictionary", -                                                snap->snapname); -                                        GF_FREE (buf); -                                        goto out; -                                } - -                                buf = NULL; -                                i++; -                        } - -                        ret = dict_set_int32 (dict, "snapcount", i - 1); -                        if (ret) { -                                gf_log (this->name, GF_LOG_ERROR, "Could not " -                                        "save snapcount in the dictionary"); -                                goto out; -                        } -                        break; -                } - -                case GF_SNAP_STATUS_TYPE_SNAP: -                { -                        /* IF we give "gluster snapshot status <snapname>" -                         * then lock is held on single snap. -                         * This is the place where necessary information -                         * (snapname)is populated in dictionary -                         * for locking. -                         */ -                        ret = dict_get_str (dict, "snapname", &snapname); -                        if (ret) { -                                gf_log (this->name, GF_LOG_ERROR, -                                        "Failed to fetch snap name"); -                                goto out; -                        } - -                        snap = glusterd_find_snap_by_name (snapname); -                        if (!snap) { -                                snprintf (err_str, len, "Snap (%s)" -                                          "does not exist", snapname); -                                gf_log(this->name, GF_LOG_ERROR, -                                        "%s", err_str); -                                ret = -1; -                                goto out; -                        } -                        break; -                } -                case GF_SNAP_STATUS_TYPE_VOL: -                        ret = dict_get_str (dict, "volname", &volname); -                        if (ret) { -                                gf_log (this->name, GF_LOG_ERROR, -                                        "Failed to fetch volname"); -                                goto out; -                        } - -                        ret = glusterd_volinfo_find (volname, &volinfo); -                        if (ret) { -                                snprintf (err_str, len, "Volume (%s) " -                                          "does not exist", volname); -                                gf_log (this->name, GF_LOG_ERROR, -                                        "%s", err_str); -                                goto out; -                        } - -                        i = 1; -                        list_for_each_entry (snap_volinfo, -                                        &volinfo->snap_volumes, snapvol_list) { -                                snprintf (key, sizeof (key), "snapname%d", i); - -                                buf = gf_strdup -                                             (snap_volinfo->snapshot->snapname); -                                if (!buf) { -                                        ret = -1; -                                        goto out; -                                } - -                                ret = dict_set_dynstr (dict, key, buf); -                                if (ret) { -                                        gf_log (this->name, GF_LOG_ERROR, -                                                "Could not save snapname"); -                                        GF_FREE (buf); -                                        goto out; -                                } - -                                buf = NULL; -                                i++; -                        } - -                        ret = dict_set_int32 (dict, "snapcount", i-1); -                        if (ret) { -                                gf_log (this->name, GF_LOG_ERROR, -                                        "Could not save snapcount"); -                                goto out; -                        } -                        break; -                default: -                { -                        gf_log (this->name, GF_LOG_ERROR, "Unknown type"); -                        ret = -1; -                        goto out; -                } -        }          ret = glusterd_mgmt_v3_initiate_snap_phases (req, op, dict);          if (ret) { @@ -3257,11 +3117,7 @@ glusterd_handle_snapshot_status (rpcsvc_request_t *req, glusterd_op_t op,          }          ret = 0; -  out: -        if (voldict) { -                dict_unref (voldict); -        }          return ret;  } @@ -4286,7 +4142,7 @@ glusterd_snapshot_status_prevalidate (dict_t *dict, char **op_errstr,                  goto out;          } -        ret = dict_get_int32 (dict, "cmd", &cmd); +        ret = dict_get_int32 (dict, "status-cmd", &cmd);          if (ret) {                  gf_log (this->name, GF_LOG_ERROR,                          "Could not fetch status cmd"); @@ -4331,7 +4187,7 @@ glusterd_snapshot_status_prevalidate (dict_t *dict, char **op_errstr,                          ret = glusterd_volinfo_find (volname, &volinfo);                          if (ret) { -                                ret = gf_asprintf (op_errstr, "Volume (%s)" +                                ret = gf_asprintf (op_errstr, "Volume (%s) "                                                    "not found", volname);                                  if (ret < 0) {                                          goto out; @@ -5616,19 +5472,20 @@ glusterd_get_snap_status_of_volume (char **op_errstr, dict_t *rsp_dict,          list_for_each_entry_safe (snap_volinfo, temp_volinfo,                               &volinfo->snap_volumes, snapvol_list) { -                ret = snprintf (key, sizeof (key), "status.snap%d", i); +                ret = snprintf (key, sizeof (key), +                                "status.snap%d.snapname", i);                  if (ret < 0) {                          goto out;                  } -                ret = glusterd_get_each_snap_object_status (op_errstr, -                                       rsp_dict, snap_volinfo->snapshot, key); - +                ret = dict_set_dynstr_with_alloc (rsp_dict, key, +                                    snap_volinfo->snapshot->snapname);                  if (ret) { -                        gf_log (this->name, GF_LOG_ERROR, "Function : " -                                "glusterd_get_single_snap_status failed"); +                        gf_log (this->name, GF_LOG_ERROR, "Could not save " +                                "snap name");                          goto out;                  } +                  i++;          } @@ -5664,20 +5521,20 @@ glusterd_get_all_snapshot_status (dict_t *dict, char **op_errstr,          list_for_each_entry_safe (snap, tmp_snap,                                    &priv->snapshots, snap_list) { -                ret = snprintf (key, sizeof (key), "status.snap%d", i); +                ret = snprintf (key, sizeof (key), +                                "status.snap%d.snapname", i);                  if (ret < 0) {                          goto out;                  } -                ret = glusterd_get_each_snap_object_status (op_errstr, -                                                         rsp_dict, snap, key); - +                ret = dict_set_dynstr_with_alloc (rsp_dict, key, +                                                  snap->snapname);                  if (ret) { -                        gf_log (this->name, GF_LOG_ERROR, "Could not get " -                                "the details of a snap object: %s", -                                snap->snapname); +                        gf_log (this->name, GF_LOG_ERROR, "Could not save " +                                "snap name");                          goto out;                  } +                  i++;          } @@ -5688,7 +5545,7 @@ glusterd_get_all_snapshot_status (dict_t *dict, char **op_errstr,          }          ret = 0; -out: +out :          return ret;  } @@ -5715,14 +5572,14 @@ glusterd_snapshot_status_commit (dict_t *dict, char **op_errstr,          conf = this->private;          GF_ASSERT (conf); -        ret = dict_get_int32 (dict, "cmd", &cmd); +        ret = dict_get_int32 (dict, "status-cmd", &cmd);          if (ret) {                  gf_log (this->name, GF_LOG_ERROR,                          "Failed to get status cmd type");                  goto out;          } -        ret = dict_set_int32 (rsp_dict, "cmd", cmd); +        ret = dict_set_int32 (rsp_dict, "status-cmd", cmd);          if (ret) {                  gf_log (this->name, GF_LOG_ERROR,                          "Could not save status cmd in rsp dictionary"); @@ -5769,6 +5626,13 @@ glusterd_snapshot_status_commit (dict_t *dict, char **op_errstr,                                          "get status of snap %s", get_buffer);                                  goto out;                          } + +                        ret = dict_set_int32 (rsp_dict, "status.snapcount", 1); +                        if (ret) { +                                gf_log (this->name, GF_LOG_ERROR, "Unable to " +                                        "set snapcount to 1"); +                                goto out; +                        }                          break;                  }                  case GF_SNAP_STATUS_TYPE_VOL:  | 
