summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSusant Palai <spalai@redhat.com>2017-01-10 16:11:50 +0530
committerShyamsundar Ranganathan <srangana@redhat.com>2017-08-11 17:40:29 +0000
commit082868b81a0f4c9ed27f71b48708b2ddfd379150 (patch)
treeabf01c476289da944a81c932e74b5312cceb2238
parent967171f76dc91bf23bc7853147975ac882881039 (diff)
cluster/dht: rebalance perf enhancement
Problem: Throttle settings "normal" and "aggressive" for rebalance did not have performance difference. normal mode spawns $(no. of cores - 4)/2 threads and aggressive spawns $(no. of cores - 4) threads. Though aggressive mode has twice the number of threads compared to that of normal mode, there was no performance gain when switched to aggressive mode from normal mode. RCA: During the course of debugging the above problem, we tried assigning migration job to migration threads spawned by rebalance, rather than synctasks(as there is more overhead associated to manage the task queue and threads). This gave us a significant improvement over rebalance under synctasks. This patch does not really gurantee that there will be a clear performance difference between normal and aggressive mode, but this patch certainly maximized the disk utilization for 1GBfiles run. Results: Test enviroment: Gluster Config: Number of Bricks: 2 (one brick per disk(RAID-6 12 disk)) Bricks: Brick1: server1:/brick/test1/1 Brick2: server2:/brick/test1/1 Options Reconfigured: performance.readdir-ahead: on server.event-threads: 4 client.event-threads: 4 1000 files with 1GB each were created/renamed such that all files will have server1 as cached and server2 as hashed, so that all files will be migrated. Test machines had 24 cores each. Results with/without synctask based migration: ----------------------------------------------- mode normal(10threads) aggressive(20threads) timetaken 0:55:30 (h:m:s) 0:56:3 (h:m:s) withsynctask timetaken with migrator 0:38:3 (h:m:s) 0:23:41 (h:m:s) threads From above table it can be seen that, there is a clear 2x perf gain between rebalance with synctask vs rebalance with migrator threads. Additionally this patch modifies the code so that caller will have the exact error number returned by dht_migrate_file(earlier the errno meaning was overloaded). This will help avoiding scenarios where migration failure due to ENOENT, can result in rebalance abort/failure. > Change-Id: I8904e2fb147419d4a51c1267be11a08ffd52168e > BUG: 1420166 > Signed-off-by: Susant Palai <spalai@redhat.com> > Reviewed-on: https://review.gluster.org/16427 > Smoke: Gluster Build System <jenkins@build.gluster.org> > Reviewed-by: N Balachandran <nbalacha@redhat.com> > Reviewed-by: Raghavendra G <rgowdapp@redhat.com> > NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> > CentOS-regression: Gluster Build System <jenkins@build.gluster.org> > Signed-off-by: Susant Palai <spalai@redhat.com> Change-Id: I8904e2fb147419d4a51c1267be11a08ffd52168e BUG: 1473134 Signed-off-by: Susant Palai <spalai@redhat.com> Reviewed-on: https://review.gluster.org/17834 CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Smoke: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Shyamsundar Ranganathan <srangana@redhat.com>
-rw-r--r--libglusterfs/src/syncop.c2
-rw-r--r--xlators/cluster/dht/src/dht-common.h4
-rw-r--r--xlators/cluster/dht/src/dht-rebalance.c350
3 files changed, 247 insertions, 109 deletions
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index 4e76587acda..2b8c322d77e 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -1567,7 +1567,7 @@ syncop_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags,
- dict_t *xdata_in, dict_t **xdata_out)
+ dict_t *xdata_in, dict_t **xdata_out)
{
struct syncargs args = {0, };
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index 66a70a555a9..9aae11f2d0f 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -1136,10 +1136,10 @@ gf_defrag_start (void *this);
int32_t
gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
- struct iatt *stbuf);
+ struct iatt *stbuf, int *fop_errno);
int
dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
- int flag);
+ int flag, int *fop_errno);
int
dht_inode_ctx_layout_get (inode_t *inode, xlator_t *this,
dht_layout_t **layout_int);
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c
index 65b4d329532..27410897d34 100644
--- a/xlators/cluster/dht/src/dht-rebalance.c
+++ b/xlators/cluster/dht/src/dht-rebalance.c
@@ -18,12 +18,12 @@
#include <signal.h>
#include "events.h"
-
#define GF_DISK_SECTOR_SIZE 512
#define DHT_REBALANCE_PID 4242 /* Change it if required */
#define DHT_REBALANCE_BLKSIZE (128 * 1024)
#define MAX_MIGRATE_QUEUE_COUNT 500
#define MIN_MIGRATE_QUEUE_COUNT 200
+#define MAX_REBAL_TYPE_SIZE 16
#ifndef MAX
#define MAX(a, b) (((a) > (b))?(a):(b))
@@ -165,7 +165,8 @@ dht_send_rebalance_event (xlator_t *this, int cmd, gf_defrag_status_t status)
static int
dht_write_with_holes (xlator_t *to, fd_t *fd, struct iovec *vec, int count,
- int32_t size, off_t offset, struct iobref *iobref)
+ int32_t size, off_t offset, struct iobref *iobref,
+ int *fop_errno)
{
int i = 0;
int ret = -1;
@@ -199,6 +200,7 @@ dht_write_with_holes (xlator_t *to, fd_t *fd, struct iovec *vec, int count,
gf_log (THIS->name, GF_LOG_WARNING,
"failed to write (%s)",
strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -219,6 +221,7 @@ dht_write_with_holes (xlator_t *to, fd_t *fd, struct iovec *vec, int count,
gf_log (THIS->name, GF_LOG_WARNING,
"failed to write (%s)",
strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -272,7 +275,7 @@ be converted to "0" in dht_migrate_file.
int32_t
gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
- struct iatt *stbuf)
+ struct iatt *stbuf, int *fop_errno)
{
int32_t ret = -1;
xlator_t *cached_subvol = NULL;
@@ -285,6 +288,9 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
gf_loglevel_t loglevel = 0;
dict_t *link_xattr = NULL;
+
+ *fop_errno = EINVAL;
+
GF_VALIDATE_OR_GOTO ("defrag", loc, out);
GF_VALIDATE_OR_GOTO ("defrag", loc->name, out);
GF_VALIDATE_OR_GOTO ("defrag", stbuf, out);
@@ -299,6 +305,8 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed :"
"loc->pargfid is NULL for %s", loc->path);
+ *fop_errno = EINVAL;
+ ret = -1;
goto out;
}
@@ -307,13 +315,15 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed :"
"loc->gfid is NULL for %s", loc->path);
+ *fop_errno = EINVAL;
+ ret = -1;
goto out;
}
link_xattr = dict_new ();
if (!link_xattr) {
ret = -1;
- errno = ENOMEM;
+ *fop_errno = ENOMEM;
goto out;
}
@@ -354,6 +364,7 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed:%s lookup failed with ret = %d",
loc->path, ret);
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -365,6 +376,8 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
"Migrate file failed :"
"Failed to get cached subvol"
" for %s on %s", loc->name, this->name);
+ *fop_errno = EINVAL;
+ ret = -1;
goto out;
}
@@ -375,6 +388,8 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
"Migrate file failed :"
"Failed to get hashed subvol"
" for %s on %s", loc->name, this->name);
+ *fop_errno = EINVAL;
+ ret = -1;
goto out;
}
@@ -398,6 +413,8 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
"Failed to set dictionary value:"
" key = %s for %s",
conf->link_xattr_name, loc->name);
+ *fop_errno = ENOMEM;
+ ret = -1;
goto out;
}
@@ -410,6 +427,7 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
"Linkto setxattr failed %s -> %s (%s)",
cached_subvol->name,
loc->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -439,8 +457,10 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
" failed on subvol %s", loc->name,
uuid_utoa(loc->gfid),
hashed_subvol->name);
- if (op_errno != EEXIST)
+ if (op_errno != EEXIST) {
+ *fop_errno = op_errno;
goto out;
+ }
}
}
ret = syncop_lookup (hashed_subvol, loc, &iatt, NULL, NULL, NULL);
@@ -450,15 +470,18 @@ gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
"Migrate file failed :Failed lookup %s on %s ",
loc->name, hashed_subvol->name);
+ *fop_errno = -ret;
ret = -1;
goto out;
}
if (iatt.ia_nlink == stbuf->ia_nlink) {
ret = dht_migrate_file (this, loc, cached_subvol, hashed_subvol,
- GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS);
- if (ret)
+ GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS,
+ fop_errno);
+ if (ret) {
goto out;
+ }
}
ret = -2;
out:
@@ -471,8 +494,8 @@ out:
static int
__check_file_has_hardlink (xlator_t *this, loc_t *loc,
- struct iatt *stbuf, dict_t *xattrs, int flags,
- gf_defrag_info_t *defrag)
+ struct iatt *stbuf, dict_t *xattrs, int flags,
+ gf_defrag_info_t *defrag, int *fop_errno)
{
int ret = 0;
@@ -485,7 +508,7 @@ __check_file_has_hardlink (xlator_t *this, loc_t *loc,
if (flags == GF_DHT_MIGRATE_HARDLINK) {
synclock_lock (&defrag->link_lock);
ret = gf_defrag_handle_hardlink
- (this, loc, xattrs, stbuf);
+ (this, loc, xattrs, stbuf, fop_errno);
synclock_unlock (&defrag->link_lock);
/*
Returning zero will force the file to be remigrated.
@@ -501,9 +524,10 @@ __check_file_has_hardlink (xlator_t *this, loc_t *loc,
} else {
gf_msg (this->name, GF_LOG_WARNING, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
- "Migrate file failed:"
+ "Migration skipped for:"
"%s: file has hardlinks", loc->path);
- ret = -ENOTSUP;
+ *fop_errno = ENOTSUP;
+ ret = -1;
}
}
@@ -522,7 +546,7 @@ __check_file_has_hardlink (xlator_t *this, loc_t *loc,
static int
__is_file_migratable (xlator_t *this, loc_t *loc,
struct iatt *stbuf, dict_t *xattrs, int flags,
- gf_defrag_info_t *defrag)
+ gf_defrag_info_t *defrag, int *fop_errno)
{
int ret = -1;
int lock_count = 0;
@@ -532,6 +556,7 @@ __is_file_migratable (xlator_t *this, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed:"
"%s: migrate-file called on directory", loc->path);
+ *fop_errno = EISDIR;
ret = -1;
goto out;
}
@@ -545,6 +570,7 @@ __is_file_migratable (xlator_t *this, loc_t *loc,
"Migrate file failed:"
"%s: Unable to get lock count for file",
loc->path);
+ *fop_errno = EINVAL;
ret = -1;
goto out;
}
@@ -554,6 +580,7 @@ __is_file_migratable (xlator_t *this, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed: %s: File has locks."
" Skipping file migration", loc->path);
+ *fop_errno = ENOTSUP;
ret = -1;
goto out;
}
@@ -561,17 +588,17 @@ __is_file_migratable (xlator_t *this, loc_t *loc,
/* Check if file has hardlink*/
ret = __check_file_has_hardlink (this, loc, stbuf, xattrs,
- flags, defrag);
+ flags, defrag, fop_errno);
out:
return ret;
}
static int
-__dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struct iatt *stbuf,
- fd_t **dst_fd, dict_t *xattr)
+__dht_rebalance_create_dst_file (xlator_t *this, xlator_t *to, xlator_t *from,
+ loc_t *loc, struct iatt *stbuf, fd_t **dst_fd,
+ dict_t *xattr, int *fop_errno)
{
- xlator_t *this = NULL;
int ret = -1;
fd_t *fd = NULL;
struct iatt new_stbuf = {0,};
@@ -579,15 +606,21 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
dht_conf_t *conf = NULL;
dict_t *dict = NULL;
- this = THIS;
conf = this->private;
dict = dict_new ();
- if (!dict)
+ if (!dict) {
+ *fop_errno = ENOMEM;
+ ret = -1;
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
+ DHT_MSG_NO_MEMORY, "dictionary allocation failed for"
+ "path:%s", loc->path);
goto out;
-
+ }
ret = dict_set_static_bin (dict, "gfid-req", stbuf->ia_gfid, 16);
if (ret) {
+ *fop_errno = ENOMEM;
+ ret = -1;
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_DICT_SET_FAILED,
"%s: failed to set dictionary value: key = gfid-req",
@@ -597,6 +630,8 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
ret = dict_set_str (dict, conf->link_xattr_name, from->name);
if (ret) {
+ *fop_errno = ENOMEM;
+ ret = -1;
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_DICT_SET_FAILED,
"%s: failed to set dictionary value: key = %s ",
@@ -606,11 +641,12 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
fd = fd_create (loc->inode, DHT_REBALANCE_PID);
if (!fd) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "%s: fd create failed (destination) (%s)",
- loc->path, strerror (errno));
+ *fop_errno = ENOMEM;
ret = -1;
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
+ DHT_MSG_MIGRATE_FILE_FAILED,
+ "%s: fd create failed (destination)",
+ loc->path);
goto out;
}
@@ -622,6 +658,7 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
DHT_MSG_GFID_MISMATCH,
"file %s exists in %s with different gfid",
loc->path, to->name);
+ *fop_errno = EINVAL;
ret = -1;
goto out;
}
@@ -632,6 +669,7 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: failed to lookup file (%s)",
loc->path, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -648,6 +686,7 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
DHT_MSG_MIGRATE_FILE_FAILED,
"failed to open %s on %s",
loc->path, to->name);
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -659,6 +698,7 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
DHT_MSG_MIGRATE_FILE_FAILED,
"failed to create %s on %s",
loc->path, to->name);
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -686,6 +726,7 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
"file %s exists in %s with different gfid,"
"found in lookup after create",
loc->path, to->name);
+ *fop_errno = EINVAL;
ret = -1;
goto out;
}
@@ -696,23 +737,27 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED, "%s: file does not exists"
"on %s (%s)", loc->path, to->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
ret = syncop_fsetxattr (to, fd, xattr, 0, NULL, NULL);
- if (ret < 0)
+ if (ret < 0) {
+ *fop_errno = -ret;
gf_msg (this->name, GF_LOG_WARNING, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: failed to set xattr on %s (%s)",
loc->path, to->name, strerror (-ret));
+ }
/* TODO: Need to add a detailed comment about why we moved away from
ftruncate.
ret = syncop_ftruncate (to, fd, stbuf->ia_size, NULL, NULL);
- if (ret < 0)
+ if (ret < 0) {
+ *fop_errno = -ret;
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"ftruncate failed for %s on %s (%s)",
@@ -722,11 +767,13 @@ __dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struc
ret = syncop_fsetattr (to, fd, stbuf,
(GF_SET_ATTR_UID | GF_SET_ATTR_GID),
NULL, NULL, NULL, NULL);
- if (ret < 0)
+ if (ret < 0) {
+ *fop_errno = -ret;
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"chown failed for %s on %s (%s)",
loc->path, to->name, strerror (-ret));
+ }
/* Fallocate does not work for size 0, hence the check. Anyway we don't
* need to care about min-free-disk for 0 byte size file */
@@ -762,15 +809,14 @@ out:
}
static int
-__dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
+__dht_check_free_space (xlator_t *this, xlator_t *to, xlator_t *from, loc_t *loc,
struct iatt *stbuf, int flag, dht_conf_t *conf,
gf_boolean_t *target_changed, xlator_t **new_subvol,
- gf_boolean_t *ignore_failure)
+ gf_boolean_t *ignore_failure, int *fop_errno)
{
struct statvfs src_statfs = {0,};
struct statvfs dst_statfs = {0,};
int ret = -1;
- xlator_t *this = NULL;
dict_t *xdata = NULL;
dht_layout_t *layout = NULL;
uint64_t src_statfs_blocks = 1;
@@ -779,11 +825,10 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
double post_percent = 0;
int i = 0;
- this = THIS;
-
xdata = dict_new ();
if (!xdata) {
- errno = ENOMEM;
+ *fop_errno = ENOMEM;
+ ret = -1;
gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
DHT_MSG_NO_MEMORY,
"failed to allocate dictionary");
@@ -796,6 +841,7 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
"Failed to set "
GF_INTERNAL_IGNORE_DEEM_STATFS" in dict");
ret = -1;
+ *fop_errno = ENOMEM;
goto out;
}
@@ -805,6 +851,7 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"failed to get statfs of %s on %s (%s)",
loc->path, from->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -815,6 +862,7 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"failed to get statfs of %s on %s (%s)",
loc->path, to->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -857,6 +905,7 @@ __dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
/* this is not a 'failure', but we don't want to
consider this as 'success' too :-/ */
+ *fop_errno = ENOSPC;
ret = -1;
goto out;
}
@@ -898,6 +947,7 @@ find_new_subvol:
layout = dht_layout_get (this, loc->parent);
if (!layout) {
gf_log (this->name, GF_LOG_ERROR, "Layout is NULL");
+ *fop_errno = EINVAL;
ret = -1;
goto out;
}
@@ -925,6 +975,7 @@ find_new_subvol:
}
*target_changed = _gf_false;
+ *fop_errno = ENOSPC;
ret = -1;
goto out;
} else {
@@ -944,7 +995,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 *fop_errno)
{
int ret = 0;
int count = 0;
@@ -963,18 +1014,26 @@ __dht_rebalance_migrate_data (xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst
offset, 0, &vector, &count, &iobref, NULL,
NULL);
if (!ret || (ret < 0)) {
+ *fop_errno = -ret;
break;
}
- if (hole_exists)
+ if (hole_exists) {
ret = dht_write_with_holes (to, dst, vector, count,
- ret, offset, iobref);
- else
+ ret, offset, iobref,
+ fop_errno);
+ } else {
ret = syncop_writev (to, dst, vector, count,
offset, iobref, 0, NULL, NULL);
+ if (ret < 0) {
+ *fop_errno = -ret;
+ }
+ }
+
if (ret < 0) {
break;
}
+
offset += ret;
total += ret;
@@ -998,7 +1057,7 @@ __dht_rebalance_migrate_data (xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst
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)
+ uint64_t ia_size, int hole_exists, int *fop_errno)
{
int ret = 0;
int count = 0;
@@ -1018,15 +1077,20 @@ __tier_migrate_data (gf_defrag_info_t *defrag, xlator_t *from, xlator_t *to, fd_
offset, 0, &vector, &count, &iobref, NULL,
NULL);
if (!ret || (ret < 0)) {
+ *fop_errno = -ret;
break;
}
- if (hole_exists)
+ if (hole_exists) {
ret = dht_write_with_holes (to, dst, vector, count,
- ret, offset, iobref);
- else
+ ret, offset, iobref,
+ fop_errno);
+ } else {
ret = syncop_writev (to, dst, vector, count,
offset, iobref, 0, NULL, NULL);
+ *fop_errno = -ret;
+ }
+
if (gf_defrag_get_pause_state (&defrag->tier_conf) != TIER_RUNNING) {
gf_msg ("tier", GF_LOG_INFO, 0,
DHT_MSG_TIER_PAUSED,
@@ -1060,18 +1124,17 @@ __tier_migrate_data (gf_defrag_info_t *defrag, xlator_t *from, xlator_t *to, fd_
static int
-__dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
+__dht_rebalance_open_src_file (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
struct iatt *stbuf, fd_t **src_fd,
- gf_boolean_t *clean_src)
+ gf_boolean_t *clean_src, int *fop_errno)
{
+
int ret = 0;
fd_t *fd = NULL;
dict_t *dict = NULL;
- xlator_t *this = NULL;
struct iatt iatt = {0,};
dht_conf_t *conf = NULL;
- this = THIS;
conf = this->private;
*clean_src = _gf_false;
@@ -1081,6 +1144,7 @@ __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: fd create failed (source)", loc->path);
+ *fop_errno = ENOMEM;
ret = -1;
goto out;
}
@@ -1091,6 +1155,7 @@ __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"failed to open file %s on %s (%s)",
loc->path, from->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -1102,14 +1167,22 @@ __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
ret = -1;
dict = dict_new ();
- if (!dict)
+ if (!dict) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ DHT_MSG_MIGRATE_FILE_FAILED,
+ "%s: Could not allocate memory for dict", loc->path);
+ *fop_errno = ENOMEM;
+ ret = -1;
goto out;
+ }
ret = dict_set_str (dict, conf->link_xattr_name, to->name);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"failed to set xattr in dict for %s (linkto:%s)",
loc->path, to->name);
+ *fop_errno = ENOMEM;
+ ret = -1;
goto out;
}
@@ -1121,6 +1194,7 @@ __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"failed to set xattr on %s in %s (%s)",
loc->path, from->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -1141,6 +1215,7 @@ __dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"failed to set mode on %s in %s (%s)",
loc->path, from->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -1156,7 +1231,7 @@ out:
int
migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
- struct iatt *buf)
+ struct iatt *buf, int *fop_errno)
{
int ret = -1;
dict_t *rsp_dict = NULL;
@@ -1166,11 +1241,15 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
dht_conf_t *conf = this->private;
dict = dict_new ();
- if (!dict)
+ if (!dict) {
+ *fop_errno = ENOMEM;
+ ret = -1;
goto out;
-
+ }
ret = dict_set_int32 (dict, conf->link_xattr_name, 256);
if (ret) {
+ *fop_errno = ENOMEM;
+ ret = -1;
gf_log (this->name, GF_LOG_ERROR,
"%s: failed to set 'linkto' key in dict", loc->path);
goto out;
@@ -1183,6 +1262,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: lookup failed (%s)",
loc->path, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -1198,6 +1278,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
gf_msg (this->name, GF_LOG_WARNING, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: file exists in destination", loc->path);
+ *fop_errno = EINVAL;
ret = -1;
goto out;
}
@@ -1209,6 +1290,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: failed to delete the linkfile (%s)",
loc->path, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -1217,6 +1299,8 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
/* Set the gfid of the source file in dict */
ret = dict_set_static_bin (dict, "gfid-req", buf->ia_gfid, 16);
if (ret) {
+ *fop_errno = ENOMEM;
+ ret = -1;
gf_log (this->name, GF_LOG_ERROR,
"%s: failed to set gfid in dict for create", loc->path);
goto out;
@@ -1232,6 +1316,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: readlink on symlink failed (%s)",
loc->path, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -1242,6 +1327,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: creating symlink failed (%s)",
loc->path, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -1258,6 +1344,7 @@ migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: mknod failed (%s)",
loc->path, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -1272,6 +1359,7 @@ done:
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: failed to perform setattr on %s (%s)",
loc->path, to->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
}
@@ -1281,6 +1369,7 @@ done:
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: unlink failed (%s)",
loc->path, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
}
@@ -1369,7 +1458,7 @@ out:
*/
int
dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
- int flag)
+ int flag, int *fop_errno)
{
int ret = -1;
struct iatt new_stbuf = {0,};
@@ -1416,11 +1505,17 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
loc->path, from->name, to->name);
dict = dict_new ();
- if (!dict)
+ if (!dict) {
+ ret = -1;
+ *fop_errno = ENOMEM;
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_NO_MEMORY,
+ "Could not allocate memory for dict");
goto out;
-
+ }
ret = dict_set_int32 (dict, conf->link_xattr_name, 256);
if (ret) {
+ *fop_errno = ENOMEM;
+ ret = -1;
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed:"
@@ -1435,6 +1530,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
ret = dict_set_int32 (dict,
GLUSTERFS_POSIXLK_COUNT, sizeof(int32_t));
if (ret) {
+ *fop_errno = ENOMEM;
+ ret = -1;
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed: %s: failed to "
@@ -1456,12 +1553,13 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
ret = syncop_inodelk (from, DHT_FILE_MIGRATE_DOMAIN, &tmp_loc, F_SETLKW,
&flock, NULL, NULL);
if (ret < 0) {
+ *fop_errno = -ret;
+ ret = -1;
gf_msg (this->name, GF_LOG_WARNING, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"migrate file failed: "
"%s: failed to lock file on %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
+ loc->path, from->name, strerror (*fop_errno));
goto out;
}
@@ -1470,20 +1568,22 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
/* Phase 1 - Data migration is in progress from now on */
ret = syncop_lookup (from, loc, &stbuf, NULL, dict, &xattr_rsp);
if (ret) {
+ *fop_errno = -ret;
+ ret = -1;
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed:"
"%s: lookup failed on %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
- goto out;
+ loc->path, from->name, strerror (*fop_errno));
+ goto out;
}
/* preserve source mode, so set the same to the destination */
src_ia_prot = stbuf.ia_prot;
/* Check if file can be migrated */
- ret = __is_file_migratable (this, loc, &stbuf, xattr_rsp, flag, defrag);
+ ret = __is_file_migratable (this, loc, &stbuf, xattr_rsp, flag, defrag,
+ fop_errno);
if (ret) {
if (ret == -2)
ret = 0;
@@ -1493,7 +1593,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
/* Take care of the special files */
if (!IA_ISREG (stbuf.ia_type)) {
/* Special files */
- ret = migrate_special_files (this, from, to, loc, &stbuf);
+ ret = migrate_special_files (this, from, to, loc, &stbuf,
+ fop_errno);
goto out;
}
@@ -1501,17 +1602,18 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
/* TODO: move all xattr related operations to fd based operations */
ret = syncop_listxattr (from, loc, &xattr, NULL, NULL);
if (ret < 0) {
+ *fop_errno = -ret;
+ ret = -1;
gf_msg (this->name, GF_LOG_WARNING, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed:"
"%s: failed to get xattr from %s (%s)",
- loc->path, from->name, strerror (-ret));
- ret = -1;
+ loc->path, from->name, strerror (*fop_errno));
}
/* create the destination, with required modes/xattr */
- ret = __dht_rebalance_create_dst_file (to, from, loc, &stbuf,
- &dst_fd, xattr);
+ ret = __dht_rebalance_create_dst_file (this, to, from, loc, &stbuf,
+ &dst_fd, xattr, fop_errno);
if (ret) {
gf_msg (this->name, GF_LOG_ERROR, 0, 0, "Create dst failed"
" on - %s for file - %s", to->name, loc->path);
@@ -1520,8 +1622,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
clean_dst = _gf_true;
- ret = __dht_check_free_space (to, from, loc, &stbuf, flag, conf,
- &target_changed, &new_target, &ignore_failure);
+ ret = __dht_check_free_space (this, to, from, loc, &stbuf, flag, conf,
+ &target_changed, &new_target, &ignore_failure, fop_errno);
if (target_changed) {
/* Can't handle for hardlinks. Marking this as failure */
if (flag == GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS || stbuf.ia_nlink > 1) {
@@ -1552,8 +1654,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
* destination. We need to do update this only post migration
* as in case of failure the linkto needs to point to the source
* subvol */
- ret = __dht_rebalance_create_dst_file (to, from, loc, &stbuf,
- &dst_fd, xattr);
+ ret = __dht_rebalance_create_dst_file (this, to, from, loc, &stbuf,
+ &dst_fd, xattr, fop_errno);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Create dst failed"
" on - %s for file - %s", to->name, loc->path);
@@ -1572,8 +1674,8 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
}
/* Open the source, and also update mode/xattr */
- ret = __dht_rebalance_open_src_file (from, to, loc, &stbuf, &src_fd,
- &clean_src);
+ ret = __dht_rebalance_open_src_file (this, from, to, loc, &stbuf, &src_fd,
+ &clean_src, fop_errno);
if (ret) {
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
@@ -1593,13 +1695,14 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed:failed to lookup %s on %s ",
loc->path, from->name);
+ *fop_errno = -ret;
ret = -1;
goto out;
}
/* Check again if file has hardlink */
ret = __check_file_has_hardlink (this, loc, &stbuf, xattr_rsp,
- flag, defrag);
+ flag, defrag, fop_errno);
if (ret) {
if (ret == -2)
ret = 0;
@@ -1613,10 +1716,12 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
/* All I/O happens in this function */
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);
+ stbuf.ia_size,
+ file_has_holes, fop_errno);
} else {
ret = __dht_rebalance_migrate_data (from, to, src_fd, dst_fd,
- stbuf.ia_size, file_has_holes);
+ stbuf.ia_size,
+ file_has_holes, fop_errno);
}
if (ret) {
@@ -1636,6 +1741,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
gf_log (this->name, GF_LOG_WARNING,
"%s: failed to fsync on %s (%s)",
loc->path, to->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
}
@@ -1649,6 +1755,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed: failed to fstat file %s on %s ",
loc->path, from->name);
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -1671,8 +1778,9 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
if (!meta_dict) {
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
- "Trace dict_new failed");
+ "dict_new failed");
+ *fop_errno = ENOMEM;
ret = -1;
goto out;
}
@@ -1684,6 +1792,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
"Failed to set dictionary value: key = %s,"
" path = %s", GLUSTERFS_INTERNAL_FOP_KEY,
loc->path);
+ *fop_errno = ENOMEM;
ret = -1;
goto out;
}
@@ -1693,7 +1802,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"Trace dict_set failed");
-
+ *fop_errno = ENOMEM;
ret = -1;
goto out;
}
@@ -1704,6 +1813,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
DHT_MSG_MIGRATE_FILE_FAILED,
"Trace syncop_setxattr metalock failed");
+ *fop_errno = -ret;
ret = -1;
goto out;
} else {
@@ -1724,6 +1834,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
"Migrate file failed:"
"%s: Failed to lock on %s",
loc->path, from->name);
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -1748,6 +1859,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
DHT_MSG_LOCK_MIGRATION_FAILED,
"write lock failed on:%s", loc->path);
+ *fop_errno = -ret;
ret = -1;
goto metaunlock;
}
@@ -1755,6 +1867,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_LOCK_MIGRATION_FAILED,
"getactivelk failed for file: %s", loc->path);
+ *fop_errno = -ret;
}
}
@@ -1780,6 +1893,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
"Migrate file failed:"
"%s: failed to perform setattr on %s ",
loc->path, to->name);
+ *fop_errno = -ret;
ret = -1;
goto metaunlock;
}
@@ -1792,6 +1906,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
gf_log (this->name, GF_LOG_WARNING,
"%s: failed to perform setattr on %s ",
loc->path, to->name);
+ *fop_errno = -ret;
ret = -1;
}
@@ -1799,6 +1914,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
if (!dict) {
dict = dict_new ();
if (!dict) {
+ *fop_errno = ENOMEM;
ret = -1;
goto out;
}
@@ -1810,6 +1926,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
gf_log (this->name, GF_LOG_ERROR,
"failed to set xattr in dict for %s (linkto:%s)",
loc->path, to->name);
+ *fop_errno = ENOMEM;
ret = -1;
goto out;
}
@@ -1820,6 +1937,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
DHT_MSG_MIGRATE_FILE_FAILED,
"failed to set xattr on %s in %s (%s)",
loc->path, old_target->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto out;
} else if (-ret == ESTALE || -ret == ENOENT) {
@@ -1833,6 +1951,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: fd create failed (%s)",
loc->path, strerror (errno));
+ *fop_errno = ENOMEM;
ret = -1;
goto out;
}
@@ -1840,6 +1959,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
DHT_LINKFILE_MODE, linkto_fd,
NULL, dict, NULL);
if (ret != 0 && -ret != EEXIST && -ret != ESTALE) {
+ *fop_errno = -ret;
ret = -1;
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
@@ -1851,6 +1971,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
(GF_SET_ATTR_UID | GF_SET_ATTR_GID),
NULL, NULL, NULL, NULL);
if (ret < 0)
+ *fop_errno = -ret;
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"chown failed for %s on %s (%s)",
@@ -1879,6 +2000,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
"Migrate file failed:"
"%s: failed to get xattr from %s (%s)",
loc->path, from->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
} else {
ret = syncop_setxattr (to, loc, xattr, 0, NULL, NULL);
@@ -1891,6 +2013,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
"Migrate file failed:"
"%s: failed to set xattr on %s (%s)",
loc->path, to->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
}
}
@@ -1920,6 +2043,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
"Migrate file failed:"
"%s: failed to perform setattr on %s ",
loc->path, from->name);
+ *fop_errno = -ret;
ret = -1;
goto metaunlock;
}
@@ -1931,6 +2055,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
gf_log (this->name, GF_LOG_WARNING,
"%s: failed to perform truncate on %s (%s)",
loc->path, from->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
}
@@ -1940,6 +2065,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
gf_log (this->name, GF_LOG_WARNING,
"%s: failed to perform removexattr on %s (%s)",
loc->path, to->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
}
@@ -1961,6 +2087,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
loc->path, from->name, strerror (-ret));
if (-ret != ENOENT) {
+ *fop_errno = -ret;
ret = -1;
goto metaunlock;
}
@@ -1978,6 +2105,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
DHT_MSG_MIGRATE_FILE_FAILED,
"%s: failed to perform unlink on %s (%s)",
loc->path, from->name, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
goto metaunlock;
}
@@ -1988,6 +2116,7 @@ dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
gf_msg_debug (this->name, 0,
"%s: failed to lookup the file on subvolumes (%s)",
loc->path, strerror (-ret));
+ *fop_errno = -ret;
ret = -1;
}
@@ -2010,6 +2139,7 @@ metaunlock:
DHT_MSG_MIGRATE_FILE_FAILED,
"Trace dict_set failed");
+ *fop_errno = ENOMEM;
ret = -1;
goto out;
}
@@ -2024,6 +2154,7 @@ metaunlock:
DHT_MSG_MIGRATE_FILE_FAILED,
"Trace dict_set failed");
+ *fop_errno = ENOMEM;
ret = -1;
goto out;
}
@@ -2034,6 +2165,7 @@ metaunlock:
DHT_MSG_MIGRATE_FILE_FAILED,
"Trace syncop_setxattr meta unlock failed");
+ *fop_errno = -ret;
ret = -1;
goto out;
}
@@ -2115,6 +2247,7 @@ rebalance_task (void *data)
int ret = -1;
dht_local_t *local = NULL;
call_frame_t *frame = NULL;
+ int fop_errno = 0;
frame = data;
@@ -2123,7 +2256,8 @@ rebalance_task (void *data)
/* This function is 'synchrounous', hence if it returns,
we are done with the task */
ret = dht_migrate_file (THIS, &local->loc, local->rebalance.from_subvol,
- local->rebalance.target_node, local->flags);
+ local->rebalance.target_node, local->flags,
+ &fop_errno);
return ret;
}
@@ -2157,7 +2291,7 @@ rebalance_task_completion (int op_ret, call_frame_t *sync_frame, void *data)
int
dht_start_rebalance_task (xlator_t *this, call_frame_t *frame)
{
- int ret = -1;
+ int ret = -1;
ret = synctask_new (this->ctx->env, rebalance_task,
rebalance_task_completion,
@@ -2165,6 +2299,7 @@ dht_start_rebalance_task (xlator_t *this, call_frame_t *frame)
return ret;
}
+
int
gf_listener_stop (xlator_t *this)
{
@@ -2344,17 +2479,16 @@ gf_defrag_should_i_migrate (xlator_t *this, int local_subvol_index, uuid_t gfid)
int
gf_defrag_migrate_single_file (void *opaque)
{
- xlator_t *this = NULL;
- dht_conf_t *conf = NULL;
- gf_defrag_info_t *defrag = NULL;
- int ret = 0;
+ xlator_t *this = NULL;
+ dht_conf_t *conf = NULL;
+ gf_defrag_info_t *defrag = NULL;
+ int ret = 0;
gf_dirent_t *entry = NULL;
struct timeval start = {0,};
loc_t entry_loc = {0,};
loc_t *loc = NULL;
struct iatt iatt = {0,};
dict_t *migrate_data = NULL;
- int32_t op_errno = 0;
struct timeval end = {0,};
double elapsed = {0,};
struct dht_container *rebal_entry = NULL;
@@ -2363,6 +2497,10 @@ gf_defrag_migrate_single_file (void *opaque)
xlator_t *cached_subvol = NULL;
call_frame_t *statfs_frame = NULL;
xlator_t *old_THIS = NULL;
+ data_t *tmp = NULL;
+ int fop_errno = 0;
+ gf_dht_migrate_data_type_t rebal_type = GF_DHT_MIGRATE_DATA;
+ char value[MAX_REBAL_TYPE_SIZE] = {0,};
rebal_entry = (struct dht_container *)opaque;
if (!rebal_entry) {
@@ -2432,7 +2570,7 @@ gf_defrag_migrate_single_file (void *opaque)
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"Migrate file failed: %s lookup failed",
- entry_loc.name);
+ entry_loc.path);
ret = 0;
goto out;
}
@@ -2442,7 +2580,7 @@ gf_defrag_migrate_single_file (void *opaque)
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_HASHED_SUBVOL_GET_FAILED,
"Failed to get hashed subvol for %s",
- loc->path);
+ entry_loc.path);
ret = 0;
goto out;
}
@@ -2452,7 +2590,7 @@ gf_defrag_migrate_single_file (void *opaque)
gf_msg (this->name, GF_LOG_ERROR, 0,
DHT_MSG_CACHED_SUBVOL_GET_FAILED,
"Failed to get cached subvol for %s",
- loc->path);
+ entry_loc.path);
ret = 0;
goto out;
@@ -2482,12 +2620,20 @@ gf_defrag_migrate_single_file (void *opaque)
dht_get_du_info (statfs_frame, this, loc);
THIS = old_THIS;
- ret = syncop_setxattr (this, &entry_loc, migrate_data, 0, NULL, NULL);
+ tmp = dict_get (migrate_data, GF_XATTR_FILE_MIGRATE_KEY);
+ if (tmp) {
+ memcpy (value, tmp->data, tmp->len);
+ if (strcmp (value, "force") == 0)
+ rebal_type = GF_DHT_MIGRATE_DATA_EVEN_IF_LINK_EXISTS;
+
+ if (conf->decommission_in_progress)
+ rebal_type = GF_DHT_MIGRATE_HARDLINK;
+ }
+
+ ret = dht_migrate_file (this, &entry_loc, cached_subvol,
+ hashed_subvol, rebal_type, &fop_errno);
if (ret < 0) {
- op_errno = -ret;
- /* errno is overloaded. See
- * rebalance_task_completion () */
- if (op_errno == ENOSPC) {
+ if (fop_errno == ENOSPC) {
gf_msg_debug (this->name, 0, "migrate-data skipped for"
" %s due to space constraints",
entry_loc.path);
@@ -2496,7 +2642,7 @@ gf_defrag_migrate_single_file (void *opaque)
defrag->skipped += 1;
}
UNLOCK (&defrag->lock);
- } else if (op_errno == ENOTSUP) {
+ } else if (fop_errno == ENOTSUP) {
gf_msg_debug (this->name, 0, "migrate-data skipped for"
" hardlink %s ", entry_loc.path);
LOCK (&defrag->lock);
@@ -2504,9 +2650,9 @@ gf_defrag_migrate_single_file (void *opaque)
defrag->skipped += 1;
}
UNLOCK (&defrag->lock);
- } else if (op_errno != EEXIST) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
+ } else if (fop_errno != EEXIST) {
+ gf_msg (this->name, GF_LOG_ERROR,
+ DHT_MSG_MIGRATE_FILE_FAILED, fop_errno,
"migrate-data failed for %s", entry_loc.path);
LOCK (&defrag->lock);
@@ -2517,29 +2663,19 @@ gf_defrag_migrate_single_file (void *opaque)
}
- ret = gf_defrag_handle_migrate_error (op_errno, defrag);
+ ret = gf_defrag_handle_migrate_error (fop_errno, defrag);
if (!ret) {
gf_msg(this->name, GF_LOG_ERROR, 0,
DHT_MSG_MIGRATE_FILE_FAILED,
"migrate-data on %s failed: %s", entry_loc.path,
- strerror (op_errno));
+ strerror (fop_errno));
} else if (ret == 1) {
ret = 0;
goto out;
} else if (ret == -1) {
goto out;
}
- } else if (ret > 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- DHT_MSG_MIGRATE_FILE_FAILED,
- "migrate-data failed for %s", entry_loc.path);
- ret = 0;
- LOCK (&defrag->lock);
- {
- defrag->total_failures += 1;
- }
- UNLOCK (&defrag->lock);
}
LOCK (&defrag->lock);
@@ -2577,7 +2713,7 @@ gf_defrag_task (void *opaque)
struct dht_container *iterator = NULL;
gf_defrag_info_t *defrag = NULL;
int ret = 0;
-
+ pid_t pid = GF_CLIENT_PID_DEFRAG;
defrag = (gf_defrag_info_t *)opaque;
if (!defrag) {
@@ -2585,6 +2721,8 @@ gf_defrag_task (void *opaque)
goto out;
}
+ syncopctx_setfspid (&pid);
+
q_head = &(defrag->queue[0].list);
/* The following while loop will dequeue one entry from the defrag->queue