From 33e9f9da8546dc57ecf6b3705f6b6474150ec78c Mon Sep 17 00:00:00 2001 From: shishirng Date: Tue, 6 Mar 2012 18:55:37 +0530 Subject: glusterd/rebalance: Bring in support for parallel rebalance This patch, enables rebalance processes to be started on all nodes where the volume is spread across (1 process per node) node-uuid xattr identifies which node takes ownership of the task to migrate the file. The model employed is push (src pushes to dst) Change-Id: Ieacd46a6216cf6ded841bbaebd10cfaea51c16d6 BUG: 763844 Signed-off-by: shishirng Reviewed-on: http://review.gluster.com/2873 Tested-by: Gluster Build System Reviewed-by: Amar Tumballi Reviewed-by: Vijay Bellur --- xlators/cluster/dht/src/dht-common.h | 1 + xlators/cluster/dht/src/dht-rebalance.c | 69 +++++++++++++++++++++++++++++---- xlators/cluster/dht/src/dht.c | 17 ++++++++ 3 files changed, 80 insertions(+), 7 deletions(-) (limited to 'xlators/cluster') diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 3d215ab2546..d7689cc7f35 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -210,6 +210,7 @@ struct gf_defrag_info_ { uint32_t is_exiting; pid_t pid; inode_t *root_inode; + uuid_t node_uuid; }; diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c index 64249d0e06a..4c5dd6e99c5 100644 --- a/xlators/cluster/dht/src/dht-rebalance.c +++ b/xlators/cluster/dht/src/dht-rebalance.c @@ -320,7 +320,7 @@ out: static inline int __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc, - struct iatt *stbuf) + struct iatt *stbuf, int flag) { struct statvfs src_statfs = {0,}; struct statvfs dst_statfs = {0,}; @@ -344,6 +344,12 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc, loc->path, to->name, strerror (errno)); goto out; } + + /* if force option is given, do not check for space @ dst. + * Check only if space is avail for the file */ + if (flag != GF_DHT_MIGRATE_DATA) + goto check_avail_space; + if (((dst_statfs.f_bavail * dst_statfs.f_bsize) / GF_DISK_SECTOR_SIZE) < (((src_statfs.f_bavail * src_statfs.f_bsize) / @@ -360,6 +366,17 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc, goto out; } +check_avail_space: + if (((dst_statfs.f_bavail * dst_statfs.f_bsize) / + GF_DISK_SECTOR_SIZE) < stbuf->ia_blocks) { + gf_log (this->name, GF_LOG_ERROR, + "data movement attempted from node (%s) with " + "to node (%s) which does not have required free space" + " for %s", from->name, to->name, loc->path); + ret = 1; + goto out; + } + ret = 0; out: return ret; @@ -672,12 +689,9 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to, if (ret) goto out; - /* Should happen on all files when 'force' option is not given */ - if (flag == GF_DHT_MIGRATE_DATA) { - ret = __dht_check_free_space (to, from, loc, &stbuf); - if (ret) { - goto out; - } + ret = __dht_check_free_space (to, from, loc, &stbuf, flag); + if (ret) { + goto out; } /* Open the source, and also update mode/xattr */ @@ -1040,6 +1054,8 @@ gf_defrag_migrate_data (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, dict_t *dict = NULL; struct iatt iatt = {0,}; int32_t op_errno = 0; + char *uuid_str = NULL; + uuid_t node_uuid = {0,}; gf_log (this->name, GF_LOG_INFO, "migate data called on %s", loc->path); @@ -1122,6 +1138,43 @@ gf_defrag_migrate_data (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, continue; } + ret = syncop_getxattr (this, &entry_loc, &dict, + GF_XATTR_NODE_UUID_KEY); + if(ret < 0) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "get node-uuid for %s", entry_loc.path); + continue; + } + + ret = dict_get_str (dict, GF_XATTR_NODE_UUID_KEY, + &uuid_str); + if(ret < 0) { + gf_log (this->name, GF_LOG_ERROR, "Failed to " + "get node-uuid from dict for %s", + entry_loc.path); + continue; + } + + if (uuid_parse (uuid_str, node_uuid)) { + gf_log (this->name, GF_LOG_ERROR, "uuid_parse " + "failed for %s", entry_loc.path); + continue; + } + + /* if file belongs to different node, skip migration + * the other node will take responsibility of migration + */ + if (uuid_compare (node_uuid, defrag->node_uuid)) { + gf_log (this->name, GF_LOG_TRACE, "%s does not" + "belong to this node", entry_loc.path); + continue; + } + + uuid_str = NULL; + + dict_del (dict, GF_XATTR_NODE_UUID_KEY); + + /* if distribute is present, it will honor this key. * -1 is returned if distribute is not present or file * doesn't have a link-file. If file has link-file, the @@ -1131,6 +1184,8 @@ gf_defrag_migrate_data (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, ret = syncop_getxattr (this, &entry_loc, &dict, GF_XATTR_LINKINFO_KEY); if (ret < 0) { + gf_log (this->name, GF_LOG_TRACE, "getxattr " + "failed for %s", entry_loc.path); continue; } diff --git a/xlators/cluster/dht/src/dht.c b/xlators/cluster/dht/src/dht.c index 4502a751b49..96382bf16e0 100644 --- a/xlators/cluster/dht/src/dht.c +++ b/xlators/cluster/dht/src/dht.c @@ -359,6 +359,7 @@ init (xlator_t *this) int i = 0; gf_defrag_info_t *defrag = NULL; int cmd = 0; + char *node_uuid = NULL; GF_VALIDATE_OR_GOTO ("dht", this, err); @@ -391,6 +392,19 @@ init (xlator_t *this) defrag->is_exiting = 0; + ret = dict_get_str (this->options, "node-uuid", &node_uuid); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, "node-uuid not " + "specified"); + goto err; + } + + if (uuid_parse (node_uuid, defrag->node_uuid)) { + gf_log (this->name, GF_LOG_ERROR, "Cannot parse " + "glusterd node uuid"); + goto err; + } + defrag->cmd = cmd; conf->defrag = defrag; @@ -591,6 +605,9 @@ struct volume_options options[] = { { .key = {"rebalance-cmd"}, .type = GF_OPTION_TYPE_INT, }, + { .key = {"node-uuid"}, + .type = GF_OPTION_TYPE_STR, + }, { .key = {NULL} }, }; -- cgit