diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-snapshot.c')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 333 | 
1 files changed, 293 insertions, 40 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index 9c64fe2d61a..73723422bc7 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -2854,16 +2854,6 @@ glusterd_handle_snapshot_status (rpcsvc_request_t *req, glusterd_op_t op,                  }          } -        /* Volume lock is not necessary for snapshot status, hence -         * turning it off -         */ -        ret = dict_set_int8 (dict, "hold_vol_locks", 0); -        if (ret) { -                gf_log (this->name, GF_LOG_ERROR, "Setting volume lock " -                        "flag failed"); -                goto out; -        } -          ret = glusterd_mgmt_v3_initiate_snap_phases (req, op, dict);          if (ret) {                  gf_log (this->name, GF_LOG_ERROR, "Failed to initiate " @@ -3751,35 +3741,13 @@ glusterd_do_snap_vol (glusterd_volinfo_t *origin_vol, glusterd_snap_t *snap,                  goto out;          } -        list_for_each_entry (brickinfo, &snap_vol->bricks, brick_list) { -                if (uuid_compare (brickinfo->uuid, MY_UUID)) -                        continue; +        /*Starting the snap volume without GF_CLI_FLAG_OP_FORCE option*/ +        ret = glusterd_start_volume (snap_vol, 0); -                if (brickinfo->snap_status == -1) { -                        gf_log (this->name, GF_LOG_INFO, -                                "not starting snap brick %s:%s for " -                                "for the snap %s (volume: %s)", -                                brickinfo->hostname, brickinfo->path, -                                snap->snapname, origin_vol->volname); -                        continue; -                } - -                ret = glusterd_brick_start (snap_vol, brickinfo, _gf_true); -                if (ret) { -                        gf_log (this->name, GF_LOG_WARNING, "starting the " -                                "brick %s:%s for the snap %s (volume: %s) " -                                "failed", brickinfo->hostname, brickinfo->path, -                                snap->snapname, origin_vol->volname); -                        goto out; -                } -        } - -        snap_vol->status = GLUSTERD_STATUS_STARTED; -        ret = glusterd_store_volinfo (snap_vol, -                                      GLUSTERD_VOLINFO_VER_AC_INCREMENT);          if (ret) {                  gf_log (this->name, GF_LOG_ERROR, -                        "Failed to store snap volinfo"); +                        "Failed to activate snap volume %s of the snap %s", +                        snap_vol->volname, snap->snapname);                  goto out;          } @@ -3794,6 +3762,105 @@ out:          return snap_vol;  } +/*This is the prevalidate function for both activate and deactive of snap + * For Activate operation pass is_op_activate as _gf_true + * For Deactivate operation pass is_op_activate as _gf_false + * */ +int +glusterd_snapshot_activate_deactivate_prevalidate (dict_t *dict, +                char **op_errstr, dict_t *rsp_dict, gf_boolean_t is_op_activate) +{ +        int32_t                 ret                   = -1; +        char                    *snapname             = NULL; +        xlator_t                *this                 = NULL; +        glusterd_snap_t         *snap                 = NULL; +        glusterd_volinfo_t      *snap_volinfo         = NULL; +        char                    err_str[PATH_MAX]     = ""; +        gf_loglevel_t           loglevel              = GF_LOG_ERROR; +        glusterd_volume_status  volume_status         = GLUSTERD_STATUS_STOPPED; +        int                     flags                 = 0; + +        this = THIS; + +        if (!dict || !op_errstr) { +                gf_log (this->name, GF_LOG_ERROR, "input parameters NULL"); +                goto out; +        } + +        ret = dict_get_str (dict, "snapname", &snapname); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Getting the snap name " +                        "failed"); +                goto out; +        } + +        snap = glusterd_find_snap_by_name (snapname); +        if (!snap) { +                snprintf (err_str, sizeof (err_str), "Snap %s does not exist.", +                        snapname); +                ret = -1; +                goto out; +        } + +        /*If its activation of snap then fetch the flags*/ +        if (is_op_activate) { +                ret = dict_get_int32 (dict, "flags", &flags); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Unable to get flags"); +                        goto out; +                } +        } + +        /* TODO : As of now there is only volume in snapshot. +        * Change this when multiple volume snapshot is introduced +        */ +        snap_volinfo = list_entry (snap->volumes.next, glusterd_volinfo_t, +                        vol_list); +        if (!snap_volinfo) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Unable to fetch snap_volinfo"); +                ret = -1; +                goto out; +        } + +        /*TODO: When multiple snapvolume are involved a cummulative +         * logic is required to tell whether is snapshot is +         * started/partially started/stopped*/ +        if (is_op_activate) { +                volume_status = GLUSTERD_STATUS_STARTED; +        } + +        if (snap_volinfo->status == volume_status) { +                if (is_op_activate) { +                        /* if flag is to GF_CLI_FLAG_OP_FORCE +                         * try to start the snap volume, even +                         * if the volume_status is GLUSTERD_STATUS_STARTED. +                         * By doing so we try to bring +                         * back the brick processes that are down*/ +                        if (!(flags & GF_CLI_FLAG_OP_FORCE)) { +                                snprintf (err_str, sizeof (err_str), +                                     "Snap %s is already activated.", snapname); +                                ret = -1; +                        } +                } else { +                        snprintf (err_str, sizeof (err_str), +                                "Snap %s is already deactivated.", snapname); +                        ret = -1; +                } +                goto out; +        } +        ret = 0; +out: + +        if (ret && err_str[0] != '\0') { +                gf_log (this->name, loglevel, "%s", err_str); +                *op_errstr = gf_strdup (err_str); +        } + +        return ret; +} +  /* This is a snapshot remove handler function. This function will be   * executed in the originator node. This function is responsible for   * calling mgmt v3 framework to do the actual remove on all the bricks @@ -4009,6 +4076,134 @@ out:  }  int32_t +glusterd_snapshot_activate_commit (dict_t *dict, char **op_errstr, +                                 dict_t *rsp_dict) +{ +        int32_t                   ret                  = -1; +        char                     *snapname             = NULL; +        glusterd_snap_t          *snap                 = NULL; +        glusterd_volinfo_t       *snap_volinfo         = NULL; +        xlator_t                 *this                 = NULL; +        int                      flags                 = 0; + +        this = THIS; +        GF_ASSERT (this); +        GF_ASSERT (dict); +        GF_ASSERT (rsp_dict); +        GF_ASSERT (op_errstr); + +        if (!dict || !op_errstr) { +                gf_log (this->name, GF_LOG_ERROR, "input parameters NULL"); +                goto out; +        } + +        ret = dict_get_str (dict, "snapname", &snapname); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Getting the snap name " +                        "failed"); +                goto out; +        } + +        ret = dict_get_int32 (dict, "flags", &flags); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Unable to get flags"); +                goto out; +        } + +        snap = glusterd_find_snap_by_name (snapname); +        if (!snap) { +                gf_log (this->name, GF_LOG_ERROR, "Snap %s does not exist", +                        snapname); +                ret = -1; +                goto out; +        } + +        /* TODO : As of now there is only volume in snapshot. +        * Change this when multiple volume snapshot is introduced +        */ +        snap_volinfo = list_entry (snap->volumes.next, glusterd_volinfo_t, +                        vol_list); +        if (!snap_volinfo) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Unable to fetch snap_volinfo"); +                        ret = -1; +                        goto out; +        } + +        ret = glusterd_start_volume (snap_volinfo, flags); + +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Failed to activate snap volume %s of the snap %s", +                        snap_volinfo->volname, snap->snapname); +                goto out; +        } +        ret = 0; +out: +        return ret; +} + +int32_t +glusterd_snapshot_deactivate_commit (dict_t *dict, char **op_errstr, +                                 dict_t *rsp_dict) +{ +        int32_t                   ret                  = -1; +        char                     *snapname             = NULL; +        glusterd_snap_t          *snap                 = NULL; +        glusterd_volinfo_t       *snap_volinfo         = NULL; +        xlator_t                 *this                 = NULL; + +        this = THIS; +        GF_ASSERT (this); +        GF_ASSERT (dict); +        GF_ASSERT (rsp_dict); +        GF_ASSERT (op_errstr); + +        if (!dict || !op_errstr) { +                gf_log (this->name, GF_LOG_ERROR, "input parameters NULL"); +                goto out; +        } + +        ret = dict_get_str (dict, "snapname", &snapname); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Getting the snap name " +                        "failed"); +                goto out; +        } + +        snap = glusterd_find_snap_by_name (snapname); +        if (!snap) { +                gf_log (this->name, GF_LOG_ERROR, "Snap %s does not exist", +                        snapname); +                ret = -1; +                goto out; +        } + +        /* TODO : As of now there is only volume in snapshot. +        * Change this when multiple volume snapshot is introduced +        */ +        snap_volinfo = list_entry (snap->volumes.next, glusterd_volinfo_t, +                        vol_list); +        if (!snap_volinfo) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Unable to fetch snap_volinfo"); +                        ret = -1; +                        goto out; +        } + +        ret = glusterd_stop_volume (snap_volinfo); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Failed to deactivate" +                        "snap %s", snapname); +                goto out; +        } + +        ret = 0; +out: +        return ret; +} + +int32_t  glusterd_snapshot_remove_commit (dict_t *dict, char **op_errstr,                                   dict_t *rsp_dict)  { @@ -5220,6 +5415,27 @@ glusterd_snapshot (dict_t *dict, char **op_errstr, dict_t *rsp_dict)                  }                  break; +        case  GF_SNAP_OPTION_TYPE_ACTIVATE: +                ret = glusterd_snapshot_activate_commit (dict, op_errstr, +                                                 rsp_dict); +                if (ret) { +                        gf_log (this->name, GF_LOG_WARNING, "Failed to " +                                "activate snapshot"); +                        goto out; +                } + +                break; + +        case GF_SNAP_OPTION_TYPE_DEACTIVATE: +                ret = glusterd_snapshot_deactivate_commit (dict, op_errstr, +                                                 rsp_dict); +                if (ret) { +                        gf_log (this->name, GF_LOG_WARNING, "Failed to " +                                "deactivate snapshot"); +                        goto out; +                } + +                break;          case GF_SNAP_OPTION_TYPE_STATUS:                  ret = glusterd_snapshot_status_commit (dict, op_errstr, @@ -5395,6 +5611,25 @@ glusterd_snapshot_prevalidate (dict_t *dict, char **op_errstr,                          goto out;                  }                  break; + +        case  GF_SNAP_OPTION_TYPE_ACTIVATE: +                ret = glusterd_snapshot_activate_deactivate_prevalidate (dict, +                                                op_errstr, rsp_dict, _gf_true); +                if (ret) { +                        gf_log (this->name, GF_LOG_WARNING, "Snapshot activate " +                                        "validation failed"); +                        goto out; +                } +                break; +        case GF_SNAP_OPTION_TYPE_DEACTIVATE: +                ret = glusterd_snapshot_activate_deactivate_prevalidate (dict, +                                                op_errstr, rsp_dict, _gf_false); +                if (ret) { +                        gf_log (this->name, GF_LOG_WARNING, +                        "Snapshot deactivate validation failed"); +                        goto out; +                } +                break;          case GF_SNAP_OPTION_TYPE_DELETE:                  ret = glusterd_snapshot_remove_prevalidate (dict, op_errstr,                                                              rsp_dict); @@ -5457,7 +5692,6 @@ glusterd_snapshot_postvalidate (dict_t *dict, int32_t op_ret, char **op_errstr,                          goto out;                  }                  break; -          case GF_SNAP_OPTION_TYPE_DELETE:          case GF_SNAP_OPTION_TYPE_RESTORE:                  ret = glusterd_snapshot_update_snaps_post_validate (dict, @@ -5469,7 +5703,12 @@ glusterd_snapshot_postvalidate (dict_t *dict, int32_t op_ret, char **op_errstr,                          goto out;                  }                  break; - +        case GF_SNAP_OPTION_TYPE_ACTIVATE: +        case GF_SNAP_OPTION_TYPE_DEACTIVATE: +                 /*Nothing to be done. But want to +                 * avoid the default case warning*/ +                ret = 0; +                break;          default:                  gf_log (this->name, GF_LOG_WARNING, "invalid snap command");                  goto out; @@ -5603,8 +5842,22 @@ glusterd_handle_snapshot_fn (rpcsvc_request_t *req)                                  "failed: %s", err_str);                  }                  break; -        case GF_SNAP_OPTION_TYPE_START: -        case GF_SNAP_OPTION_TYPE_STOP: +        case  GF_SNAP_OPTION_TYPE_ACTIVATE: +                ret = glusterd_mgmt_v3_initiate_snap_phases (req, cli_op, +                                                             dict); +                if (ret) { +                        gf_log (this->name, GF_LOG_WARNING, +                                "Snapshot activate failed: %s", err_str); +                } +                break; +        case GF_SNAP_OPTION_TYPE_DEACTIVATE: +                ret = glusterd_mgmt_v3_initiate_snap_phases (req, cli_op, +                                                             dict); +                if (ret) { +                        gf_log (this->name, GF_LOG_WARNING, +                                "Snapshot deactivate failed: %s", err_str); +                } +                break;          case GF_SNAP_OPTION_TYPE_STATUS:                  ret = glusterd_handle_snapshot_status (req, cli_op, dict,                                                         err_str,  | 
