diff options
-rw-r--r-- | rpc/xdr/src/cli1-xdr.x | 4 | ||||
-rwxr-xr-x | tests/basic/tier/fops-during-migration-pause.t | 87 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 6 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 11 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-messages.h | 19 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-rebalance.c | 125 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-shared.c | 5 | ||||
-rw-r--r-- | xlators/cluster/dht/src/tier.c | 68 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-messages.h | 22 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 167 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 16 |
11 files changed, 518 insertions, 12 deletions
diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x index 73863ae3d9d..56f34bc2dae 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -7,7 +7,9 @@ GF_DEFRAG_CMD_START_TIER, GF_DEFRAG_CMD_STATUS_TIER, GF_DEFRAG_CMD_START_DETACH_TIER, - GF_DEFRAG_CMD_STOP_DETACH_TIER + GF_DEFRAG_CMD_STOP_DETACH_TIER, + GF_DEFRAG_CMD_PAUSE_TIER, + GF_DEFRAG_CMD_RESUME_TIER }; enum gf_defrag_status_t { diff --git a/tests/basic/tier/fops-during-migration-pause.t b/tests/basic/tier/fops-during-migration-pause.t new file mode 100755 index 00000000000..702465f4191 --- /dev/null +++ b/tests/basic/tier/fops-during-migration-pause.t @@ -0,0 +1,87 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + + +NUM_BRICKS=3 +DEMOTE_FREQ=5 +PROMOTE_FREQ=5 + +TEST_STR="Testing write and truncate fops on tier migration" + +function is_sticky_set () { + echo $1 + if [ -k $1 ]; + then + echo "yes" + else + echo "no" + fi +} + + +# Creates a tiered volume with pure distribute hot and cold tiers +# Both hot and cold tiers will have an equal number of bricks. + +function create_dist_tier_vol () { + mkdir $B0/cold + mkdir $B0/hot + TEST $CLI volume create $V0 $H0:$B0/cold/${V0}{0..$1} + TEST $CLI volume set $V0 performance.quick-read off + TEST $CLI volume set $V0 performance.io-cache off + TEST $CLI volume set $V0 features.ctr-enabled on + TEST $CLI volume start $V0 + TEST $CLI volume attach-tier $V0 $H0:$B0/hot/${V0}{0..$1} + TEST $CLI volume set $V0 cluster.tier-demote-frequency $DEMOTE_FREQ + TEST $CLI volume set $V0 cluster.tier-promote-frequency $PROMOTE_FREQ + TEST $CLI volume set $V0 cluster.read-freq-threshold 0 + TEST $CLI volume set $V0 cluster.write-freq-threshold 0 +} + + +cleanup; + +#Basic checks +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info + + +#Create and start a tiered volume +create_dist_tier_vol $NUM_BRICKS + +# Mount FUSE +TEST glusterfs -s $H0 --volfile-id $V0 $M0 + +TEST mkdir $M0/dir1 + +# Create a large file (200MB), so that rebalance takes time +# The file will be created on the hot tier + +dd if=/dev/zero of=$M0/dir1/FILE1 bs=64k count=5120 + +# Get the path of the file on the hot tier +HPATH=`find $B0/hot/ -name FILE1` +echo "File path on hot tier: "$HPATH + + +# Wait for the tier process to demote the file +EXPECT_WITHIN $REBALANCE_TIMEOUT "yes" is_sticky_set $HPATH + +TEST $CLI volume set $V0 cluster.tier-pause on + +# Wait for the tier process to finish migrating the file +EXPECT_WITHIN $REBALANCE_TIMEOUT "no" is_sticky_set $HPATH + +# Get the path of the file on the cold tier +CPATH=`find $B0/cold/ -name FILE1` + +# make sure destination is empty +TEST ! test -s $CPATH + +# make sure source exists and not empty +TEST test -s $HPATH + +cleanup; + diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index e2c9f5547ac..acbe3f40eea 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -7661,10 +7661,14 @@ dht_notify (xlator_t *this, int event, void *data, ...) cmd == GF_DEFRAG_CMD_STOP_DETACH_TIER) gf_defrag_stop (defrag, GF_DEFRAG_STATUS_STOPPED, output); + else if (cmd == GF_DEFRAG_CMD_PAUSE_TIER) + ret = gf_defrag_pause_tier (this, defrag); + else if (cmd == GF_DEFRAG_CMD_RESUME_TIER) + ret = gf_defrag_resume_tier (this, defrag); } unlock: UNLOCK (&defrag->lock); - return 0; + return ret; break; } diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 95ca7067806..6483b2e86d7 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -293,7 +293,8 @@ enum gf_defrag_type { GF_DEFRAG_CMD_STATUS_TIER = 1 + 6, GF_DEFRAG_CMD_START_DETACH_TIER = 1 + 7, GF_DEFRAG_CMD_STOP_DETACH_TIER = 1 + 8, - + GF_DEFRAG_CMD_PAUSE_TIER = 1 + 9, + GF_DEFRAG_CMD_RESUME_TIER = 1 + 10, }; typedef enum gf_defrag_type gf_defrag_type; @@ -353,6 +354,8 @@ typedef struct gf_tier_conf { int tier_demote_frequency; uint64_t st_last_promoted_size; uint64_t st_last_demoted_size; + int request_pause; + gf_boolean_t paused; } gf_tier_conf_t; struct gf_defrag_info_ { @@ -982,6 +985,12 @@ int gf_defrag_status_get (gf_defrag_info_t *defrag, dict_t *dict); int +gf_defrag_pause_tier (xlator_t *this, gf_defrag_info_t *defrag); + +int +gf_defrag_resume_tier (xlator_t *this, gf_defrag_info_t *defrag); + +int gf_defrag_start_detach_tier (gf_defrag_info_t *defrag); int diff --git a/xlators/cluster/dht/src/dht-messages.h b/xlators/cluster/dht/src/dht-messages.h index 61631e682f8..8960ac738ec 100644 --- a/xlators/cluster/dht/src/dht-messages.h +++ b/xlators/cluster/dht/src/dht-messages.h @@ -40,7 +40,7 @@ */ #define GLFS_DHT_BASE GLFS_MSGID_COMP_DHT -#define GLFS_DHT_NUM_MESSAGES 107 +#define GLFS_DHT_NUM_MESSAGES 109 #define GLFS_MSGID_END (GLFS_DHT_BASE + GLFS_DHT_NUM_MESSAGES + 1) /* Messages with message IDs */ @@ -1002,5 +1002,22 @@ #define DHT_MSG_LOG_IPC_TIER_ERROR (GLFS_DHT_BASE + 107) +/* + * @messageid 109108 + * @diagnosis + * @recommendedaction None + */ + +#define DHT_MSG_TIER_PAUSED (GLFS_DHT_BASE + 108) + +/* + * @messageid 109108 + * @diagnosis + * @recommendedaction None + */ + +#define DHT_MSG_TIER_RESUME (GLFS_DHT_BASE + 109) + + #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" #endif /* _DHT_MESSAGES_H_ */ diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c index b3c25ba9ee2..fe648f07e8e 100644 --- a/xlators/cluster/dht/src/dht-rebalance.c +++ b/xlators/cluster/dht/src/dht-rebalance.c @@ -727,7 +727,7 @@ out: static int __dht_rebalance_migrate_data (xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst, - uint64_t ia_size, int hole_exists) + uint64_t ia_size, int hole_exists) { int ret = 0; int count = 0; @@ -779,6 +779,68 @@ __dht_rebalance_migrate_data (xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst return ret; } +static int +__tier_migrate_data (gf_defrag_info_t *defrag, xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst, + uint64_t ia_size, int hole_exists) +{ + int ret = 0; + int count = 0; + off_t offset = 0; + struct iovec *vector = NULL; + struct iobref *iobref = NULL; + uint64_t total = 0; + size_t read_size = 0; + + /* if file size is '0', no need to enter this loop */ + while (total < ia_size) { + + read_size = (((ia_size - total) > DHT_REBALANCE_BLKSIZE) ? + DHT_REBALANCE_BLKSIZE : (ia_size - total)); + + ret = syncop_readv (from, src, read_size, + offset, 0, &vector, &count, &iobref, NULL, + NULL); + if (!ret || (ret < 0)) { + break; + } + + if (hole_exists) + ret = dht_write_with_holes (to, dst, vector, count, + ret, offset, iobref); + else + ret = syncop_writev (to, dst, vector, count, + offset, iobref, 0, NULL, NULL); + if (defrag->tier_conf.request_pause) { + gf_msg ("tier", GF_LOG_INFO, 0, + DHT_MSG_TIER_PAUSED, + "Migrate file paused"); + ret = -1; + } + + if (ret < 0) { + break; + } + offset += ret; + total += ret; + + GF_FREE (vector); + if (iobref) + iobref_unref (iobref); + iobref = NULL; + vector = NULL; + } + if (iobref) + iobref_unref (iobref); + GF_FREE (vector); + + if (ret >= 0) + ret = 0; + else + ret = -1; + + return ret; +} + static int __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc, @@ -1251,8 +1313,14 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to, /* All I/O happens in this function */ - ret = __dht_rebalance_migrate_data (from, to, src_fd, dst_fd, - stbuf.ia_size, file_has_holes); + if (defrag->cmd == GF_DEFRAG_CMD_START_TIER) { + ret = __tier_migrate_data (defrag, from, to, src_fd, dst_fd, + stbuf.ia_size, file_has_holes); + } else { + ret = __dht_rebalance_migrate_data (from, to, src_fd, dst_fd, + stbuf.ia_size, file_has_holes); + } + if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_MIGRATE_FILE_FAILED, @@ -3415,6 +3483,57 @@ out: } int +gf_defrag_pause_tier (xlator_t *this, gf_defrag_info_t *defrag) +{ + int poll = 0; + int ret = 0; + int usec_sleep = 100000; /* 1/10th of a sec */ + int poll_max = 15; /* 15 times = wait at most 3/2 sec */ + + if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) + goto out; + + /* + * Set flag requesting to pause tiering. Wait a finite time for + * tiering to actually stop as indicated by the "paused" boolean, + * before returning success or failure. + */ + defrag->tier_conf.request_pause = 1; + + for (poll = 0; poll < poll_max; poll++) { + if ((defrag->tier_conf.paused == _gf_true) || + (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED)) { + goto out; + } + + usleep (usec_sleep); + } + + ret = -1; + +out: + + gf_msg (this->name, GF_LOG_DEBUG, 0, + DHT_MSG_TIER_PAUSED, + "Pause tiering ret=%d", ret); + + return ret; +} + +int +gf_defrag_resume_tier (xlator_t *this, gf_defrag_info_t *defrag) +{ + gf_msg (this->name, GF_LOG_DEBUG, 0, + DHT_MSG_TIER_RESUME, + "Resume tiering"); + + defrag->tier_conf.request_pause = 0; + defrag->tier_conf.paused = _gf_false; + + return 0; +} + +int gf_defrag_start_detach_tier (gf_defrag_info_t *defrag) { defrag->cmd = GF_DEFRAG_CMD_START_DETACH_TIER; diff --git a/xlators/cluster/dht/src/dht-shared.c b/xlators/cluster/dht/src/dht-shared.c index 4d700482919..718f497bb03 100644 --- a/xlators/cluster/dht/src/dht-shared.c +++ b/xlators/cluster/dht/src/dht-shared.c @@ -963,6 +963,11 @@ struct volume_options options[] = { }, /* tier options */ + { .key = {"tier-pause"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + }, + { .key = {"tier-promote-frequency"}, .type = GF_OPTION_TYPE_INT, .default_value = "120", diff --git a/xlators/cluster/dht/src/tier.c b/xlators/cluster/dht/src/tier.c index d85fe41dcb0..9dcbc760330 100644 --- a/xlators/cluster/dht/src/tier.c +++ b/xlators/cluster/dht/src/tier.c @@ -307,6 +307,13 @@ tier_migrate_using_query_file (void *_args) per_file_status = 0; per_link_status = 0; + if (defrag->tier_conf.request_pause) { + gf_msg (this->name, GF_LOG_INFO, 0, + DHT_MSG_LOG_TIER_STATUS, + "Tiering paused. Exiting tier_migrate_using_query_file"); + break; + } + memset (gfid_str, 0, UUID_CANONICAL_FORM_LEN+1); memset (query_record->_link_info_str, 0, DB_QUERY_RECORD_SIZE); @@ -368,6 +375,14 @@ tier_migrate_using_query_file (void *_args) /* Per link of file */ while (token_str != NULL) { + if (defrag->tier_conf.request_pause) { + gf_msg (this->name, GF_LOG_INFO, 0, + DHT_MSG_LOG_TIER_STATUS, + "Tiering paused. " + "Exiting tier_migrate_using_query_file"); + goto abort; + } + link_str = gf_strdup (token_str); if (!link_info) { @@ -485,6 +500,14 @@ tier_migrate_using_query_file (void *_args) gf_uuid_copy (loc.gfid, loc.inode->gfid); + if (defrag->tier_conf.request_pause) { + gf_msg (this->name, GF_LOG_INFO, 0, + DHT_MSG_LOG_TIER_STATUS, + "Tiering paused. " + "Exiting tier_migrate_using_query_file"); + goto abort; + } + ret = syncop_setxattr (this, &loc, migrate_data, 0, NULL, NULL); if (ret) { @@ -1347,6 +1370,11 @@ tier_start (xlator_t *this, gf_defrag_info_t *defrag) goto out; } + if (defrag->tier_conf.request_pause) + defrag->tier_conf.paused = _gf_true; + else + defrag->tier_conf.paused = _gf_false; + sleep(1); if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) { @@ -1368,6 +1396,11 @@ tier_start (xlator_t *this, gf_defrag_info_t *defrag) goto out; } + if ((defrag->tier_conf.paused) || + (defrag->tier_conf.request_pause)) + continue; + + /* To have proper synchronization amongst all * brick holding nodes, so that promotion and demotions * start atomicly w.r.t promotion/demotion frequency @@ -1658,6 +1691,7 @@ tier_init (xlator_t *this) gf_defrag_info_t *defrag = NULL; char *voldir = NULL; char *mode = NULL; + char *paused = NULL; ret = dht_init (this); if (ret) { @@ -1776,7 +1810,15 @@ tier_init (xlator_t *this) defrag->tier_conf.mode = ret; } - ret = gf_asprintf (&voldir, "%s/%s", + defrag->tier_conf.request_pause = 0; + + ret = dict_get_str (this->options, + "tier-pause", &paused); + + if (paused && strcmp (paused, "on") == 0) + defrag->tier_conf.request_pause = 1; + + ret = gf_asprintf(&voldir, "%s/%s", DEFAULT_VAR_RUN_DIRECTORY, this->name); if (ret < 0) @@ -1844,6 +1886,9 @@ tier_reconfigure (xlator_t *this, dict_t *options) gf_defrag_info_t *defrag = NULL; char *mode = NULL; int migrate_mb = 0; + gf_boolean_t req_pause = _gf_false; + int ret = 0; + conf = this->private; if (conf->defrag) { @@ -1885,6 +1930,27 @@ tier_reconfigure (xlator_t *this, dict_t *options) GF_OPTION_RECONF ("tier-max-files", defrag->tier_conf.max_migrate_files, options, int32, out); + + GF_OPTION_RECONF ("tier-pause", + req_pause, options, + bool, out); + + if (req_pause == _gf_true) { + ret = gf_defrag_pause_tier (this, defrag); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + DHT_MSG_LOG_TIER_ERROR, + "pause tier failed on reconfigure"); + } + } else { + ret = gf_defrag_resume_tier (this, defrag); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + DHT_MSG_LOG_TIER_ERROR, + "resume tier failed on reconfigure"); + } + } + } out: diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h index 03826b7d748..ffcfa7773e9 100644 --- a/xlators/mgmt/glusterd/src/glusterd-messages.h +++ b/xlators/mgmt/glusterd/src/glusterd-messages.h @@ -40,7 +40,9 @@ */ #define GLUSTERD_COMP_BASE GLFS_MSGID_GLUSTERD -#define GLFS_NUM_MESSAGES 571 + +#define GLFS_NUM_MESSAGES 573 + #define GLFS_MSGID_END (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1) /* Messaged with message IDs */ #define glfs_msg_start_x GLFS_COMP_BASE, "Invalid: Start of messages" @@ -4611,8 +4613,26 @@ * @recommendedaction * */ + #define GD_MSG_SHARED_STORAGE_DOES_NOT_EXIST (GLUSTERD_COMP_BASE + 571) +/*! + * @messageid + * @diagnosis + * @recommendedaction + * + */ + +#define GD_MSG_SNAP_PAUSE_TIER_FAIL (GLUSTERD_COMP_BASE + 572) + +/*! + * @messageid + * @diagnosis + * @recommendedaction + * + */ +#define GD_MSG_SNAP_RESUME_TIER_FAIL (GLUSTERD_COMP_BASE + 573) + /*------------*/ #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.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c index d185ba82979..90dac9e45de 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c @@ -1948,6 +1948,142 @@ out: } int +glusterd_snapshot_pause_tier (xlator_t *this, glusterd_volinfo_t *volinfo) +{ + int ret = -1; + dict_t *dict = NULL; + char *op_errstr = NULL; + + GF_VALIDATE_OR_GOTO ("glusterd", this, out); + GF_VALIDATE_OR_GOTO (this->name, volinfo, out); + + if (volinfo->type != GF_CLUSTER_TYPE_TIER) { + ret = 0; + goto out; + } + + dict = dict_new (); + if (!dict) { + goto out; + } + + ret = dict_set_int32 (dict, "rebalance-command", + GF_DEFRAG_CMD_PAUSE_TIER); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_DICT_SET_FAILED, + "Failed to set rebalance-command"); + goto out; + } + + ret = dict_set_str (dict, "volname", volinfo->volname); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_DICT_SET_FAILED, + "Failed to set volname"); + goto out; + } + + ret = gd_brick_op_phase (GD_OP_DEFRAG_BRICK_VOLUME, NULL, + dict, &op_errstr); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_SNAP_PAUSE_TIER_FAIL, + "Failed to pause tier. Errstr=%s", + op_errstr); + goto out; + } + +out: + if (dict) + dict_unref (dict); + + return ret; +} + + +int +glusterd_snapshot_resume_tier (xlator_t *this, dict_t *snap_dict) +{ + int ret = -1; + dict_t *dict = NULL; + int64_t volcount = 0; + char key[PATH_MAX] = ""; + char *volname = NULL; + int i = 0; + char *op_errstr = NULL; + glusterd_volinfo_t *volinfo = NULL; + + GF_VALIDATE_OR_GOTO ("glusterd", this, out); + GF_VALIDATE_OR_GOTO (this->name, snap_dict, out); + + ret = dict_get_int64 (snap_dict, "volcount", &volcount); + if (ret) { + goto out; + } + if (volcount <= 0) { + ret = -1; + goto out; + } + + dict = dict_new (); + if (!dict) + goto out; + + for (i = 1; i <= volcount; i++) { + snprintf (key, sizeof (key), "volname%d", i); + ret = dict_get_str (snap_dict, key, &volname); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_DICT_SET_FAILED, + "Failed to get key %s", volname); + goto out; + } + + ret = glusterd_volinfo_find (volname, &volinfo); + if (ret) + goto out; + + if (volinfo->type != GF_CLUSTER_TYPE_TIER) + continue; + + ret = dict_set_int32 (dict, "rebalance-command", + GF_DEFRAG_CMD_RESUME_TIER); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_DICT_SET_FAILED, + "Failed to set rebalance-command"); + + goto out; + } + + ret = dict_set_str (dict, "volname", volname); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_DICT_SET_FAILED, + "Failed to set volname"); + goto out; + } + + ret = gd_brick_op_phase (GD_OP_DEFRAG_BRICK_VOLUME, NULL, + dict, &op_errstr); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_SNAP_RESUME_TIER_FAIL, + "Failed to resume tier"); + goto out; + } + } + +out: + if (dict) + dict_unref (dict); + + return ret; +} + + +int glusterd_snap_create_clone_common_prevalidate (dict_t *rsp_dict, int flags, char *snapname, char *err_str, char *snap_volname, @@ -2249,7 +2385,12 @@ glusterd_snapshot_clone_prevalidate (dict_t *dict, char **op_errstr, goto out; } - ret = 0; + ret = glusterd_snapshot_pause_tier (this, snap_vol); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_SNAP_PAUSE_TIER_FAIL, + "Failed to pause tier in clone prevalidate."); + } out: if (ret && err_str[0] != '\0') { @@ -2439,6 +2580,14 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, goto out; } + ret = glusterd_snapshot_pause_tier (this, volinfo); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_SNAP_PAUSE_TIER_FAIL, + "Failed to pause tier in snap prevalidate."); + goto out; + } + } ret = dict_set_int64 (rsp_dict, "volcount", volcount); @@ -2449,6 +2598,7 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr, } ret = 0; + out: if (ret && err_str[0] != '\0') { gf_msg (this->name, loglevel, 0, @@ -7819,7 +7969,12 @@ glusterd_snapshot_clone_postvalidate (dict_t *dict, int32_t op_ret, } snap_vol->snapshot = NULL; - ret = 0; + ret = glusterd_snapshot_resume_tier (this, dict); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_SNAP_RESUME_TIER_FAIL, + "Failed to resume tier in clone postvalidate."); + } out: return ret; @@ -7914,7 +8069,13 @@ glusterd_snapshot_create_postvalidate (dict_t *dict, int32_t op_ret, //ignore the errors of autodelete ret = glusterd_handle_snap_limit (dict, rsp_dict); } - ret = 0; + + ret = glusterd_snapshot_resume_tier (this, dict); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_SNAP_RESUME_TIER_FAIL, + "Failed to resume tier in snapshot postvalidate."); + } out: return ret; diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index 58405b67363..d2ef4b184fb 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -47,6 +47,15 @@ validate_tier (glusterd_volinfo_t *volinfo, dict_t *dict, char *key, goto out; } + else if (strstr (key, "tier-pause")) { + if (strcmp(value, "off") && + strcmp(value, "on")) { + ret = -1; + goto out; + } + goto out; + } + /* * Rest of the volume set options for tier are expecting a positive * Integer. Change the function accordingly if this constraint is @@ -1994,6 +2003,13 @@ struct volopt_map_entry glusterd_volopt_map[] = { "file that has read hits less than this value will be " "considered as COLD and will be demoted." }, + { .key = "cluster.tier-pause", + .voltype = "cluster/tier", + .option = "tier-pause", + .op_version = GD_OP_VERSION_3_7_6, + .flags = OPT_FLAG_CLIENT_OPT, + .validate_fn = validate_tier, + }, { .key = "cluster.tier-promote-frequency", .voltype = "cluster/tier", .value = "120", |