From 9f77bc92810b070d0e692a827d94ccd571f39eee Mon Sep 17 00:00:00 2001 From: Amar Tumballi Date: Thu, 14 Jul 2011 12:14:37 +0530 Subject: 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 Reviewed-on: http://review.gluster.com/9 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- xlators/mgmt/glusterd/src/glusterd-rebalance.c | 110 +++++++++++++++++++++++++ 1 file changed, 110 insertions(+) (limited to 'xlators') diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c index d69f59eab11..f535f6a3a44 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, -- cgit