diff options
author | Amar Tumballi <amar@gluster.com> | 2011-07-14 12:14:37 +0530 |
---|---|---|
committer | Anand Avati <avati@gluster.com> | 2011-07-19 08:04:19 -0700 |
commit | 9f77bc92810b070d0e692a827d94ccd571f39eee (patch) | |
tree | 842bf7bcdfd69b29be95b201dd8d9f22d1f0a8af | |
parent | 4c31a8662570a60260b36938d7f67d114befef4e (diff) |
glusterd rebalance: feature to migrate extended attributes added
currently when a file gets migrated, the extended attributes of the
files are getting lost (which should be treated as data-loss).
Change-Id: Ic417afbdbe0390491055bb0126eb4f48e6588f88
BUG: 3069
Signed-off-by: Amar Tumballi <amar@gluster.com>
Reviewed-on: http://review.gluster.com/9
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@gluster.com>
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rebalance.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c index d69f59eab..f535f6a3a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c +++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c @@ -40,6 +40,109 @@ #include "syscall.h" #include "cli1.h" +static int +migrate_xattrs_of_file (int src, int dst) +{ + int ret = -1; + ssize_t len = 0; + ssize_t size = 0; + ssize_t size_processed = 0; + char *key = NULL; + char *value = NULL; + char *list = NULL; + int value_size = 0; + + /* Get the size of xattr list */ + size = sys_flistxattr (src, NULL, 0); + if (size < 0) { + gf_log (THIS->name, GF_LOG_ERROR, + "failed to fetch the xattr list size (%s)", + strerror (errno)); + goto out; + } + if (size == 0) { + gf_log (THIS->name, GF_LOG_DEBUG, + "there are no extended attributes for the file"); + ret = 0; + goto out; + } + + list = GF_CALLOC (size + 1, sizeof (char), gf_common_mt_char); + if (!list) + goto out; + + size = sys_flistxattr (src, list, size); + if (size < 0) { + gf_log (THIS->name, GF_LOG_ERROR, + "failed to fetch the xattr list (%s)", + strerror (errno)); + goto out; + } + if (size == 0) { + gf_log (THIS->name, GF_LOG_DEBUG, + "there are no extended attributes for the file"); + ret = 0; + goto out; + } + + value_size = 4096; + value = GF_CALLOC (value_size, sizeof (char), gf_common_mt_char); + if (!value) + goto out; + + while (size > size_processed) { + key = &list[size_processed]; + + len = sys_fgetxattr (src, key, value, value_size); + if (len < 0) { + if (errno != ERANGE) { + gf_log (THIS->name, GF_LOG_ERROR, + "failed to get xattr for key %s (%s)", + key, strerror (errno)); + goto out; + } + /* need bigger buffer */ + value_size *= 4; + value = GF_REALLOC (value, value_size); + if (!value) + goto out; + + /* go back and check the same key */ + continue; + } + + len = sys_fgetxattr (src, key, value, len); + if (len < 0) { + gf_log (THIS->name, GF_LOG_ERROR, + "failed to get the xattr for key %s (%s)", + key, strerror (errno)); + goto out; + } + + ret = sys_fsetxattr (dst, key, value, len, 0); + if (ret < 0) { + gf_log (THIS->name, GF_LOG_ERROR, + "failed to set the xattr for key %s (%s)", + key, strerror (errno)); + goto out; + } + + /* Exclude the NULL character */ + size_processed += strlen (key) + 1; + } + + ret = 0; +out: + if (list) + GF_FREE (list); + + if (value) + GF_FREE (value); + + return ret; +} + + int gf_glusterd_rebalance_move_data (glusterd_volinfo_t *volinfo, const char *dir) { @@ -137,6 +240,13 @@ gf_glusterd_rebalance_move_data (glusterd_volinfo_t *volinfo, const char *dir) tmp_filename, strerror (errno)); } + ret = migrate_xattrs_of_file (src_fd, dst_fd); + if (ret) { + gf_log (THIS->name, GF_LOG_WARNING, + "failed to copy the extended attributes " + "from source file %s", full_path); + } + ret = fchown (dst_fd, stbuf.st_uid, stbuf.st_gid); if (ret) { gf_log ("", GF_LOG_WARNING, |