diff options
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-errno.h | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-ganesha.c | 32 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-messages.h | 19 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 112 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 3 | 
6 files changed, 163 insertions, 5 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-errno.h b/xlators/mgmt/glusterd/src/glusterd-errno.h index 55d44a5c6a1..3301e44a414 100644 --- a/xlators/mgmt/glusterd/src/glusterd-errno.h +++ b/xlators/mgmt/glusterd/src/glusterd-errno.h @@ -27,6 +27,7 @@ enum glusterd_op_errno {          EG_ISSNAP      = 30813,          /* Volume is a snap volume           */          EG_GEOREPRUN   = 30814,          /* Geo-Replication is running        */          EG_NOTTHINP    = 30815,          /* Bricks are not thinly provisioned */ +        EG_NOGANESHA   = 30816,          /* Global nfs-ganesha is not enabled */  };  #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c index 746a3d1e364..8dde82e89ed 100644 --- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c +++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c @@ -159,6 +159,38 @@ manage_service (char *action)                  " not recognized.", action);          return ret;  } + +/* + * Check if the cluster is a ganesha cluster or not * + */ +gf_boolean_t +glusterd_is_ganesha_cluster () { +        int                ret      = -1; +        glusterd_conf_t   *priv     = NULL; +        xlator_t          *this     = NULL; +        gf_boolean_t       ret_bool = _gf_false; + +        this = THIS; +        GF_VALIDATE_OR_GOTO ("ganesha", this, out); +        priv = this->private; +        GF_VALIDATE_OR_GOTO (this->name, priv, out); + +        ret = dict_get_str_boolean (priv->opts, +                                    GLUSTERD_STORE_KEY_GANESHA_GLOBAL, +                                    _gf_false); +        if (ret == _gf_true) { +                ret_bool = _gf_true; +                gf_msg_debug (this->name, 0, +                              "nfs-ganesha is enabled for the cluster"); +        } else +                gf_msg_debug (this->name, 0, +                              "nfs-ganesha is disabled for the cluster"); + +out: +        return ret_bool; + +} +  /* Check if ganesha.enable is set to 'on', that checks if   * a  particular volume is exported via NFS-Ganesha */  gf_boolean_t diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h index e520c69add2..0e15bd77621 100644 --- a/xlators/mgmt/glusterd/src/glusterd-messages.h +++ b/xlators/mgmt/glusterd/src/glusterd-messages.h @@ -41,7 +41,7 @@  #define GLUSTERD_COMP_BASE      GLFS_MSGID_GLUSTERD -#define GLFS_NUM_MESSAGES       587 +#define GLFS_NUM_MESSAGES       589  #define GLFS_MSGID_END          (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1)  /* Messaged with message IDs */ @@ -4727,7 +4727,7 @@   * @recommendation   *   */ -#define GD_MSG_BRICK_CLEANUP_SUCCESS               (GLUSTERD_COMP_BASE + 584) +#define GD_MSG_BRICK_CLEANUP_SUCCESS               (GLUSTERD_COMP_BASE + 585)  /*!   * @messageid @@ -4735,7 +4735,7 @@   * @recommendation   *   */ -#define GD_MSG_STATE_STR_GET_FAILED               (GLUSTERD_COMP_BASE + 585) +#define GD_MSG_STATE_STR_GET_FAILED               (GLUSTERD_COMP_BASE + 586)  /*!   * @messageid @@ -4743,7 +4743,7 @@   * @recommendedaction   *   */ -#define GD_MSG_RESET_BRICK_COMMIT_FORCE_REQ_RCVD   (GLUSTERD_COMP_BASE + 586) +#define GD_MSG_RESET_BRICK_COMMIT_FORCE_REQ_RCVD   (GLUSTERD_COMP_BASE + 587)  /*!   * @messageid @@ -4751,7 +4751,16 @@   * @recommendedaction   *   */ -#define GD_MSG_RESET_BRICK_CMD_FAIL                (GLUSTERD_COMP_BASE + 587) +#define GD_MSG_RESET_BRICK_CMD_FAIL                (GLUSTERD_COMP_BASE + 588) + +/*! + * @messageid + * @diagnosis + * @recommendedaction + * + */ +#define GD_MSG_NFS_GANESHA_DISABLED                (GLUSTERD_COMP_BASE + 589) +  /*------------*/  #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"  #endif /* !_GLUSTERD_MESSAGES_H_ */ diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c index d1fb849f0f0..c8af1ec21c4 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c @@ -3788,6 +3788,7 @@ glusterd_copy_nfs_ganesha_file (glusterd_volinfo_t *src_vol,                                  GD_MSG_FILE_OP_FAILED,                                  "Failed to open %s",                                  dest ? src_path : dest_path); +                        ret = -1;                          goto out;                  } diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index 0c92acb1803..6c97d45962d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -919,6 +919,76 @@ out:          return ret;  } +/* + * This function validates the particulat snapshot with respect to the current + * cluster. If the snapshot has ganesha enabled, and the cluster is not a nfs + * ganesha cluster, we fail the validation. Other scenarios where either the + * snapshot does not have ganesha enabled or it has and the cluster is a nfs + * ganesha cluster, we pass the validation + * + * @param snap          snap object of the snapshot to be validated + * @return              Negative value on Failure and 0 in success + */ +int32_t +glusterd_snapshot_validate_ganesha_conf (glusterd_snap_t *snap, +                                         char **op_errstr, +                                         uint32_t *op_errno) +{ +        int                     ret                    = -1; +        glusterd_volinfo_t      *snap_vol              = NULL; +        xlator_t                *this                  = NULL; + +        this = THIS; +        GF_VALIDATE_OR_GOTO ("snapshot", this, out); +        GF_VALIDATE_OR_GOTO (this->name, snap, out); +        GF_VALIDATE_OR_GOTO (this->name, op_errstr, out); +        GF_VALIDATE_OR_GOTO (this->name, op_errno, out); + +        snap_vol = list_entry (snap->volumes.next, +                               glusterd_volinfo_t, vol_list); + +        GF_VALIDATE_OR_GOTO (this->name, snap_vol, out); + +        /* +         * Check if the snapshot has ganesha enabled * +         */ +        if (glusterd_check_ganesha_export(snap_vol) == _gf_false) { +                /* +                 * If the snapshot has not been exported via ganesha * +                 * then we can proceed.                              * +                 */ +                ret = 0; +                goto out; +        } + +        /* +         * At this point we are certain that the snapshot has been exported * +         * via ganesha. So we check if the cluster is a nfs-ganesha cluster * +         * If it a nfs-ganesha cluster, then we proceed. Else we fail.      * +         */ +        if (glusterd_is_ganesha_cluster() != _gf_true) { +                ret = gf_asprintf (op_errstr, "Snapshot(%s) has a " +                                   "nfs-ganesha export conf file. " +                                   "cluster.enable-shared-storage and " +                                   "nfs-ganesha should be enabled " +                                   "before restoring this snapshot.", +                                   snap->snapname); +                *op_errno = EG_NOGANESHA; +                if (ret < 0) { +                        goto out; +                } + +                gf_msg (this->name, GF_LOG_ERROR, EINVAL, +                        GD_MSG_NFS_GANESHA_DISABLED, "%s", *op_errstr); +                ret = -1; +                goto out; +        } + +        ret = 0; +out: +        return ret; +} +  /* This function is called before actual restore is taken place. This function   * will validate whether the snapshot volumes are ready to be restored or not.   * @@ -989,6 +1059,15 @@ glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr,                  goto out;          } +        ret = glusterd_snapshot_validate_ganesha_conf (snap, op_errstr, +                                                       op_errno); +        if (ret) { +                gf_msg (this->name, GF_LOG_ERROR, 0, +                        GD_MSG_SNAPSHOT_OP_FAILED, +                        "ganesha conf validation failed."); +                goto out; +        } +          ret = dict_set_str (rsp_dict, "snapname", snapname);          if (ret) {                  gf_msg (this->name, GF_LOG_ERROR, 0, @@ -8847,6 +8926,7 @@ glusterd_snapshot_revert_partial_restored_vol (glusterd_volinfo_t *volinfo)          int                     ret                     = 0;          char                    pathname [PATH_MAX]     = {0,};          char                    trash_path[PATH_MAX]    = {0,}; +        glusterd_brickinfo_t   *brickinfo               = NULL;          glusterd_volinfo_t     *reverted_vol            = NULL;          glusterd_volinfo_t     *snap_vol                = NULL;          glusterd_volinfo_t     *tmp_vol                 = NULL; @@ -8901,6 +8981,38 @@ glusterd_snapshot_revert_partial_restored_vol (glusterd_volinfo_t *volinfo)                                        snapvol_list) {                  cds_list_add_tail (&snap_vol->snapvol_list,                                     &reverted_vol->snap_volumes); + +                cds_list_for_each_entry (brickinfo, &snap_vol->bricks, +                                         brick_list) { +                        /* +                         * If the brick is not of this peer, or snapshot is    * +                         * missed for the brick don't restore the xattr for it * +                         */ +                        if ((!gf_uuid_compare (brickinfo->uuid, MY_UUID)) && +                            (brickinfo->snap_status != -1)) { +                                /* +                                 * We need to restore volume id of all snap * +                                 * bricks to volume id of the snap volume.  * +                                 */ +                                ret = sys_lsetxattr (brickinfo->path, +                                                     GF_XATTR_VOL_ID_KEY, +                                                     snap_vol->volume_id, +                                                   sizeof (snap_vol->volume_id), +                                                     XATTR_REPLACE); +                                if (ret == -1) { +                                        gf_msg (this->name, GF_LOG_ERROR, 0, +                                                GD_MSG_SETXATTR_FAIL, +                                                "Failed to set extended " +                                                "attribute %s on %s. " +                                                "Reason: %s, snap: %s", +                                                GF_XATTR_VOL_ID_KEY, +                                                brickinfo->path, +                                                strerror (errno), +                                                snap_vol->volname); +                                        goto out; +                                } +                        } +                }          }          /* Since we retrieved the volinfo from store now we don't diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index a9601fdc632..adb0210c67e 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -1077,6 +1077,9 @@ int glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr);  int glusterd_op_set_ganesha (dict_t *dict, char **errstr);  int ganesha_manage_export (dict_t *dict, char *value, char **op_errstr);  int manage_export_config (char *volname, char *value, char **op_errstr); + +gf_boolean_t +glusterd_is_ganesha_cluster ();  gf_boolean_t glusterd_check_ganesha_export (glusterd_volinfo_t *volinfo);  int stop_ganesha (char **op_errstr);  int tear_down_cluster (gf_boolean_t run_teardown);  | 
