diff options
| -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 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,  | 
