summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvra Sengupta <asengupt@redhat.com>2016-12-19 13:52:59 +0530
committerAravinda VK <avishwan@redhat.com>2017-02-03 01:25:56 -0500
commita583e14056ba0358ed4e3689d19dbf59089086fe (patch)
tree0593756bde543877442de2db1783c3f71635a283
parent4017f2415f128d91256004fbfbbd7bfe376cf241 (diff)
snapshot: Fix restore rollback to reassign snap volume ids to bricks
Added further checks to ensure we do not go beyond prevalidate when trying to restore a snapshot which has a nfs-gansha conf file, in a cluster when nfs-ganesha is not enabled The error message for the particular scenario is: "Snapshot(<snapname>) has a nfs-ganesha export conf file. cluster.enable-shared-storage and nfs-ganesha should be enabled before restoring this snapshot." > Reviewed-on: http://review.gluster.org/16116 > Reviewed-by: Rajesh Joseph <rjoseph@redhat.com> > Smoke: Gluster Build System <jenkins@build.gluster.org> > NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> > CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Change-Id: I1b87e9907e0a5e162f26ef1ca89fe76e8da8610f BUG: 1405909 Signed-off-by: Avra Sengupta <asengupt@redhat.com> Reviewed-on: https://review.gluster.org/16195 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: jiffin tony Thottan <jthottan@redhat.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Aravinda VK <avishwan@redhat.com>
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-errno.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-ganesha.c32
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-messages.h19
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c112
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h3
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);