From d772a79d6fac46426b5eaa6a307bac74f4e8033f Mon Sep 17 00:00:00 2001 From: "Kaleb S. KEITHLEY" Date: Thu, 9 Mar 2017 12:34:41 -0500 Subject: build/packaging: Debian and Ubuntu don't have /usr/libexec GLUSTERFS_LIBEXECDIR is effectively hard-coded to /usr/libexec/glusterfs in configure(.ac) Debian-based distributions don't have a /usr/libexec/ directory This issues is partially mitigated by the use of $libexecdir in some of the Makefile.am files, but even so the incorrectly defined GLUSTERFS_LIBEXECDIR results in various things such as gsyncd, glusterfind, eventsd, etc., trying to invoke other scripts and programs from a location that doesn't exist. And once we correctly define GLUSTERFS_LIBEXECDIR, then we might as well use it appropriatedly. master change https://review.gluster.org/16880 master BZ: 1430841 release-3.10 change https://review.gluster.org/16881 release-3.10 BZ: 1430845 Change-Id: If5219cadc51ae316f7ba2e2831d739235c77902d BUG: 1430845 Signed-off-by: Kaleb S. KEITHLEY Reviewed-on: https://review.gluster.org/16882 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Milind Changire --- cli/src/Makefile.am | 2 +- configure.ac | 12 ++++++------ extras/Makefile.am | 2 +- geo-replication/src/Makefile.am | 4 ++-- geo-replication/syncdaemon/Makefile.am | 2 +- tools/gfind_missing_files/Makefile.am | 4 ++-- tools/glusterfind/Makefile.am | 4 ++-- tools/glusterfind/src/Makefile.am | 2 +- xlators/features/ganesha/src/Makefile.am | 2 +- xlators/mgmt/glusterd/src/Makefile.am | 2 +- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am index 91819d111e3..8e47e209056 100644 --- a/cli/src/Makefile.am +++ b/cli/src/Makefile.am @@ -17,7 +17,7 @@ AM_CPPFLAGS = $(GF_CPPFLAGS) \ -I$(top_srcdir)/rpc/xdr/src\ -DDATADIR=\"$(localstatedir)\" \ -DCONFDIR=\"$(sysconfdir)/glusterfs\" \ - -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\ + -DGSYNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\"\ -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) -DSBIN_DIR=\"$(sbindir)\"\ $(XML_CPPFLAGS) diff --git a/configure.ac b/configure.ac index 5a7231262d9..1ab3c996d3c 100644 --- a/configure.ac +++ b/configure.ac @@ -974,24 +974,24 @@ old_prefix=$prefix if test "x$prefix" = xNONE; then prefix=$ac_default_prefix fi -GLUSTERFS_LIBEXECDIR="$(eval echo $prefix)/libexec/glusterfs" -GLUSTERFSD_MISCDIR="$(eval echo $prefix)/var/lib/misc/glusterfsd" +GLUSTERFS_LIBEXECDIR="$libexecdir/glusterfs" +GLUSTERFSD_MISCDIR="$prefix/var/lib/misc/glusterfsd" prefix=$old_prefix ### Dirty hacky stuff to make LOCALSTATEDIR work if test "x$prefix" = xNONE; then - test $localstatedir = '${prefix}/var' && localstatedir=$ac_default_prefix/var + test $localstatedir = '$prefix/var' && localstatedir=$ac_default_prefix/var localstatedir=/var - LOCALSTATEDIR=$(eval echo ${localstatedir}) + LOCALSTATEDIR=$localstatedir else - LOCALSTATEDIR=$(eval echo ${localstatedir}) + LOCALSTATEDIR=$localstatedir fi old_prefix=$prefix if test "x$prefix" = xNONE; then prefix=$ac_default_prefix fi -GLUSTERD_VOLFILE="$(eval echo ${sysconfdir})/glusterfs/glusterd.vol" +GLUSTERD_VOLFILE="$sysconfdir/glusterfs/glusterd.vol" prefix=$old_prefix diff --git a/extras/Makefile.am b/extras/Makefile.am index 609d497f5b8..5ebb45a9a79 100644 --- a/extras/Makefile.am +++ b/extras/Makefile.am @@ -1,4 +1,4 @@ -addonexecdir = $(libexecdir)/glusterfs +addonexecdir = $(GLUSTERFS_LIBEXECDIR) addonexec_SCRIPTS = peer_add_secret_pub EditorModedir = $(docdir) diff --git a/geo-replication/src/Makefile.am b/geo-replication/src/Makefile.am index 1572698f8ae..04355bf8d52 100644 --- a/geo-replication/src/Makefile.am +++ b/geo-replication/src/Makefile.am @@ -1,4 +1,4 @@ -gsyncddir = $(libexecdir)/glusterfs +gsyncddir = $(GLUSTERFS_LIBEXECDIR) gsyncd_SCRIPTS = gverify.sh peer_gsec_create \ set_geo_rep_pem_keys.sh peer_mountbroker @@ -19,7 +19,7 @@ noinst_HEADERS = procdiggy.h AM_CPPFLAGS = $(GF_CPPFLAGS) \ -I$(top_srcdir)/libglusterfs/src\ - -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\ + -DGSYNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\"\ -DUSE_LIBGLUSTERFS\ -DSBIN_DIR=\"$(sbindir)\" -DPYTHON=\"$(PYTHON)\" diff --git a/geo-replication/syncdaemon/Makefile.am b/geo-replication/syncdaemon/Makefile.am index ed0f5e40924..6449d9ecc18 100644 --- a/geo-replication/syncdaemon/Makefile.am +++ b/geo-replication/syncdaemon/Makefile.am @@ -1,4 +1,4 @@ -syncdaemondir = $(libexecdir)/glusterfs/python/syncdaemon +syncdaemondir = $(GLUSTERFS_LIBEXECDIR)/python/syncdaemon syncdaemon_PYTHON = gconf.py gsyncd.py __init__.py master.py README.md repce.py \ resource.py configinterface.py syncdutils.py monitor.py libcxattr.py \ diff --git a/tools/gfind_missing_files/Makefile.am b/tools/gfind_missing_files/Makefile.am index 043c34c4182..f77f7899efb 100644 --- a/tools/gfind_missing_files/Makefile.am +++ b/tools/gfind_missing_files/Makefile.am @@ -1,4 +1,4 @@ -gfindmissingfilesdir = $(libexecdir)/glusterfs/gfind_missing_files +gfindmissingfilesdir = $(GLUSTERFS_LIBEXECDIR)/gfind_missing_files gfindmissingfiles_SCRIPTS = gfind_missing_files.sh gfid_to_path.sh \ gfid_to_path.py @@ -21,6 +21,6 @@ uninstall-local: install-data-local: rm -f $(DESTDIR)$(sbindir)/gfind_missing_files - ln -s $(libexecdir)/glusterfs/gfind_missing_files/gfind_missing_files.sh $(DESTDIR)$(sbindir)/gfind_missing_files + ln -s $(GLUSTERFS_LIBEXECDIR)/gfind_missing_files/gfind_missing_files.sh $(DESTDIR)$(sbindir)/gfind_missing_files CLEANFILES = diff --git a/tools/glusterfind/Makefile.am b/tools/glusterfind/Makefile.am index 37f23bed1bb..92fa61461ad 100644 --- a/tools/glusterfind/Makefile.am +++ b/tools/glusterfind/Makefile.am @@ -6,7 +6,7 @@ bin_SCRIPTS = glusterfind CLEANFILES = $(bin_SCRIPTS) -deletehookscriptsdir = $(libexecdir)/glusterfs/glusterfind/ +deletehookscriptsdir = $(GLUSTERFS_LIBEXECDIR)/glusterfind/ deletehookscripts_SCRIPTS = S57glusterfind-delete-post.py uninstall-local: @@ -16,5 +16,5 @@ install-data-local: $(mkdir_p) $(DESTDIR)$(GLUSTERD_WORKDIR)/glusterfind/.keys $(mkdir_p) $(DESTDIR)$(GLUSTERD_WORKDIR)/hooks/1/delete/post/ rm -f $(DESTDIR)$(GLUSTERD_WORKDIR)/hooks/1/delete/post/S57glusterfind-delete-post - ln -s $(libexecdir)/glusterfs/glusterfind/S57glusterfind-delete-post.py \ + ln -s $(GLUSTERFS_LIBEXECDIR)/glusterfind/S57glusterfind-delete-post.py \ $(DESTDIR)$(GLUSTERD_WORKDIR)/hooks/1/delete/post/S57glusterfind-delete-post diff --git a/tools/glusterfind/src/Makefile.am b/tools/glusterfind/src/Makefile.am index 541ff946c04..e4469c1c0cf 100644 --- a/tools/glusterfind/src/Makefile.am +++ b/tools/glusterfind/src/Makefile.am @@ -1,4 +1,4 @@ -glusterfinddir = $(libexecdir)/glusterfs/glusterfind +glusterfinddir = $(GLUSTERFS_LIBEXECDIR)/glusterfind glusterfind_PYTHON = conf.py utils.py __init__.py \ main.py libgfchangelog.py changelogdata.py diff --git a/xlators/features/ganesha/src/Makefile.am b/xlators/features/ganesha/src/Makefile.am index 3bf291b92c6..be2f45c6d43 100644 --- a/xlators/features/ganesha/src/Makefile.am +++ b/xlators/features/ganesha/src/Makefile.am @@ -11,7 +11,7 @@ ganesha_la_SOURCES = ganesha.c AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS)\ -DGANESHA_DIR=\"$(sysconfdir)/ganesha\" \ - -DGYSNCD_PREFIX=\"$(libexecdir)/glusterfs\" + -DGYSNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\" AM_CFLAGS = -Wall $(GF_CFLAGS) diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am index f938aaf9436..d20fcefd97d 100644 --- a/xlators/mgmt/glusterd/src/Makefile.am +++ b/xlators/mgmt/glusterd/src/Makefile.am @@ -46,7 +46,7 @@ AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ -I$(CONTRIBDIR)/mount \ -I$(CONTRIBDIR)/userspace-rcu \ -DSBIN_DIR=\"$(sbindir)\" -DDATADIR=\"$(localstatedir)\" \ - -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\" \ + -DGSYNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\" \ -DCONFDIR=\"$(sysconfdir)/ganesha\" \ -DGANESHA_PREFIX=\"$(libexecdir)/ganesha\" \ -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) $(XML_CPPFLAGS) -- cgit From 7920d7f3879ca5971d4e7ba569534934bfa676e8 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Tue, 28 Mar 2017 19:26:41 +0530 Subject: features/shard: Pass the correct iatt for cache invalidation Backport of: https://review.gluster.org/16961 This fixes a performance issue with shard which was causing the translator to trigger unusually high number of lookups for cache invalidation even when there was no modification to the file. In shard_common_stat_cbk(), it is local->prebuf that contains the aggregated size and block count as opposed to buf which only holds the attributes for the physical copy of base shard. Passing buf for inode_ctx invalidation would always set refresh to true since the file size in inode ctx contains the aggregated size and would never be same as @buf->ia_size. This was leading to every write/read being preceded by a lookup on the base shard even when the file underwent no modification. Change-Id: I85940b4b33e77b98e97e277d880ab35b1496c89a BUG: 1437330 Signed-off-by: Krutika Dhananjay Reviewed-on: https://review.gluster.org/16968 Smoke: Gluster Build System Reviewed-by: Pranith Kumar Karampuri NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: jiffin tony Thottan --- xlators/features/shard/src/shard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index 39d648bb34d..9504f12da85 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -1269,7 +1269,7 @@ shard_common_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, else inode = local->fd->inode; - shard_inode_ctx_invalidate (inode, this, buf); + shard_inode_ctx_invalidate (inode, this, &local->prebuf); unwind: local->handler (frame, this); -- cgit From 5e1324fffebbf6a650d6aff33849a8362300c1cc Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Tue, 28 Feb 2017 14:27:51 +0530 Subject: storage/posix: Use more granular mutex locks for atomic writes Backport of: https://review.gluster.org/16785 Change-Id: I64aa561cb76ff9d4597d91fb5aeb64531698936a BUG: 1427390 Signed-off-by: Krutika Dhananjay Reviewed-on: https://review.gluster.org/16892 NetBSD-regression: NetBSD Build System Reviewed-by: Pranith Kumar Karampuri Smoke: Gluster Build System CentOS-regression: Gluster Build System --- xlators/storage/posix/src/posix-helpers.c | 2 ++ xlators/storage/posix/src/posix.c | 38 ++++++++++++++++++++++++------- xlators/storage/posix/src/posix.h | 1 + 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 190298db235..0ed8015294b 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -2195,10 +2195,12 @@ __posix_inode_ctx_get (inode_t *inode, xlator_t *this) return NULL; pthread_mutex_init (&ctx_p->xattrop_lock, NULL); + pthread_mutex_init (&ctx_p->write_atomic_lock, NULL); ret = __inode_ctx_set (inode, this, (uint64_t *)&ctx_p); if (ret < 0) { pthread_mutex_destroy (&ctx_p->xattrop_lock); + pthread_mutex_destroy (&ctx_p->write_atomic_lock); GF_FREE (ctx_p); return NULL; } diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 6582d609af4..de995b980d0 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -136,6 +136,7 @@ posix_forget (xlator_t *this, inode_t *inode) } out: pthread_mutex_destroy (&ctx->xattrop_lock); + pthread_mutex_destroy (&ctx->write_atomic_lock); GF_FREE (ctx); return ret; } @@ -685,6 +686,7 @@ posix_do_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t op_errno = 0; struct posix_fd *pfd = NULL; gf_boolean_t locked = _gf_false; + posix_inode_ctx_t *ctx = NULL; DECLARE_OLD_FS_ID_VAR; @@ -700,9 +702,15 @@ posix_do_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, goto out; } + ret = posix_inode_ctx_get_all (fd->inode, this, &ctx); + if (ret < 0) { + ret = -ENOMEM; + goto out; + } + if (dict_get (xdata, GLUSTERFS_WRITE_UPDATE_ATOMIC)) { locked = _gf_true; - LOCK(&fd->inode->lock); + pthread_mutex_lock (&ctx->write_atomic_lock); } ret = posix_fdstat (this, pfd->fd, statpre); @@ -729,7 +737,7 @@ posix_do_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, out: if (locked) { - UNLOCK (&fd->inode->lock); + pthread_mutex_unlock (&ctx->write_atomic_lock); locked = _gf_false; } SET_TO_OLD_FS_ID (); @@ -843,6 +851,7 @@ posix_do_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, int32_t flags = 0; struct posix_fd *pfd = NULL; gf_boolean_t locked = _gf_false; + posix_inode_ctx_t *ctx = NULL; DECLARE_OLD_FS_ID_VAR; @@ -858,9 +867,15 @@ posix_do_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, goto out; } + ret = posix_inode_ctx_get_all (fd->inode, this, &ctx); + if (ret < 0) { + ret = -ENOMEM; + goto out; + } + if (dict_get (xdata, GLUSTERFS_WRITE_UPDATE_ATOMIC)) { locked = _gf_true; - LOCK(&fd->inode->lock); + pthread_mutex_lock (&ctx->write_atomic_lock); } ret = posix_fdstat (this, pfd->fd, statpre); @@ -910,7 +925,7 @@ fsync: out: if (locked) { - UNLOCK (&fd->inode->lock); + pthread_mutex_unlock (&ctx->write_atomic_lock); locked = _gf_false; } SET_TO_OLD_FS_ID (); @@ -3314,6 +3329,7 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, gf_boolean_t locked = _gf_false; gf_boolean_t write_append = _gf_false; gf_boolean_t update_atomic = _gf_false; + posix_inode_ctx_t *ctx = NULL; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -3357,9 +3373,15 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, * as of today). */ + op_ret = posix_inode_ctx_get_all (fd->inode, this, &ctx); + if (op_ret < 0) { + op_errno = ENOMEM; + goto out; + } + if (write_append || update_atomic) { locked = _gf_true; - LOCK(&fd->inode->lock); + pthread_mutex_lock (&ctx->write_atomic_lock); } op_ret = posix_fdstat (this, _fd, &preop); @@ -3379,7 +3401,7 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, (pfd->flags & O_DIRECT)); if (locked && (!update_atomic)) { - UNLOCK (&fd->inode->lock); + pthread_mutex_unlock (&ctx->write_atomic_lock); locked = _gf_false; } @@ -3409,7 +3431,7 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, } if (locked) { - UNLOCK (&fd->inode->lock); + pthread_mutex_unlock (&ctx->write_atomic_lock); locked = _gf_false; } @@ -3435,7 +3457,7 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, out: if (locked) { - UNLOCK (&fd->inode->lock); + pthread_mutex_unlock (&ctx->write_atomic_lock); locked = _gf_false; } diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index e6304250d14..01a0bfa6860 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -193,6 +193,7 @@ typedef struct { typedef struct { uint64_t unlink_flag; pthread_mutex_t xattrop_lock; + pthread_mutex_t write_atomic_lock; } posix_inode_ctx_t; #define POSIX_BASE_PATH(this) (((struct posix_private *)this->private)->base_path) -- cgit From 8b8098ed5c6e0f5a82d89c9d5f22bd7b17d6a882 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Tue, 28 Feb 2017 15:52:49 +0530 Subject: storage/posix: Use granular mutex locks for pgfid update syscalls Backport of: https://review.gluster.org/16869 Change-Id: I5c48b3be3f39bb8f951d33e2729522605384d1ff BUG: 1427390 Signed-off-by: Krutika Dhananjay Reviewed-on: https://review.gluster.org/16893 NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Smoke: Gluster Build System Reviewed-by: Pranith Kumar Karampuri --- xlators/storage/posix/src/posix-helpers.c | 2 + xlators/storage/posix/src/posix.c | 62 +++++++++++++++++++++++++------ xlators/storage/posix/src/posix.h | 1 + 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 0ed8015294b..e7bd2cfd803 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -2196,11 +2196,13 @@ __posix_inode_ctx_get (inode_t *inode, xlator_t *this) pthread_mutex_init (&ctx_p->xattrop_lock, NULL); pthread_mutex_init (&ctx_p->write_atomic_lock, NULL); + pthread_mutex_init (&ctx_p->pgfid_lock, NULL); ret = __inode_ctx_set (inode, this, (uint64_t *)&ctx_p); if (ret < 0) { pthread_mutex_destroy (&ctx_p->xattrop_lock); pthread_mutex_destroy (&ctx_p->write_atomic_lock); + pthread_mutex_destroy (&ctx_p->pgfid_lock); GF_FREE (ctx_p); return NULL; } diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index de995b980d0..200a740a09c 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -137,6 +137,7 @@ posix_forget (xlator_t *this, inode_t *inode) out: pthread_mutex_destroy (&ctx->xattrop_lock); pthread_mutex_destroy (&ctx->write_atomic_lock); + pthread_mutex_destroy (&ctx->pgfid_lock); GF_FREE (ctx); return ret; } @@ -159,6 +160,7 @@ posix_lookup (call_frame_t *frame, xlator_t *this, char *pgfid_xattr_key = NULL; int32_t nlink_samepgfid = 0; struct posix_private *priv = NULL; + posix_inode_ctx_t *ctx = NULL; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -218,7 +220,14 @@ posix_lookup (call_frame_t *frame, xlator_t *this, PGFID_XATTR_KEY_PREFIX, loc->pargfid); - LOCK (&loc->inode->lock); + op_ret = posix_inode_ctx_get_all (loc->inode, this, + &ctx); + if (op_ret < 0) { + op_errno = ENOMEM; + goto out; + } + + pthread_mutex_lock (&ctx->pgfid_lock); { SET_PGFID_XATTR_IF_ABSENT (real_path, pgfid_xattr_key, @@ -227,7 +236,7 @@ posix_lookup (call_frame_t *frame, xlator_t *this, this, unlock); } unlock: - UNLOCK (&loc->inode->lock); + pthread_mutex_unlock (&ctx->pgfid_lock); } } @@ -1924,6 +1933,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this, char uuid_str[GF_UUID_BUF_SIZE] = {0}; char gfid_str[GF_UUID_BUF_SIZE] = {0}; gf_boolean_t get_link_count = _gf_false; + posix_inode_ctx_t *ctx = NULL; DECLARE_OLD_FS_ID_VAR; @@ -2027,14 +2037,19 @@ posix_unlink (call_frame_t *frame, xlator_t *this, if (priv->update_pgfid_nlinks && (stbuf.ia_nlink > 1)) { MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, loc->pargfid); - LOCK (&loc->inode->lock); + op_ret = posix_inode_ctx_get_all (loc->inode, this, &ctx); + if (op_ret < 0) { + op_errno = ENOMEM; + goto out; + } + pthread_mutex_lock (&ctx->pgfid_lock); { UNLINK_MODIFY_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid, 0, op_ret, this, unlock); } unlock: - UNLOCK (&loc->inode->lock); + pthread_mutex_unlock (&ctx->pgfid_lock); if (op_ret < 0) { gf_msg (this->name, GF_LOG_WARNING, 0, @@ -2389,6 +2404,8 @@ posix_rename (call_frame_t *frame, xlator_t *this, dict_t *unwind_dict = NULL; gf_boolean_t locked = _gf_false; gf_boolean_t get_link_count = _gf_false; + posix_inode_ctx_t *ctx_old = NULL; + posix_inode_ctx_t *ctx_new = NULL; DECLARE_OLD_FS_ID_VAR; @@ -2471,10 +2488,26 @@ posix_rename (call_frame_t *frame, xlator_t *this, goto out; } + op_ret = posix_inode_ctx_get_all (oldloc->inode, this, &ctx_old); + if (op_ret < 0) { + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + + if (newloc->inode) { + op_ret = posix_inode_ctx_get_all (newloc->inode, this, &ctx_new); + if (op_ret < 0) { + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + } + if (IA_ISDIR (oldloc->inode->ia_type)) posix_handle_unset (this, oldloc->inode->gfid, NULL); - LOCK (&oldloc->inode->lock); + pthread_mutex_lock (&ctx_old->pgfid_lock); { if (!IA_ISDIR (oldloc->inode->ia_type) && priv->update_pgfid_nlinks) { @@ -2490,7 +2523,7 @@ posix_rename (call_frame_t *frame, xlator_t *this, if ((xdata) && (dict_get (xdata, GET_LINK_COUNT)) && (real_newpath) && (was_present)) { - LOCK (&newloc->inode->lock); + pthread_mutex_lock (&ctx_new->pgfid_lock); locked = _gf_true; get_link_count = _gf_true; op_ret = posix_pstat (this, newloc->gfid, real_newpath, @@ -2532,7 +2565,7 @@ posix_rename (call_frame_t *frame, xlator_t *this, } if (locked) { - UNLOCK (&newloc->inode->lock); + pthread_mutex_unlock (&ctx_new->pgfid_lock); locked = _gf_false; } @@ -2557,10 +2590,10 @@ posix_rename (call_frame_t *frame, xlator_t *this, } unlock: if (locked) { - UNLOCK (&newloc->inode->lock); + pthread_mutex_unlock (&ctx_new->pgfid_lock); locked = _gf_false; } - UNLOCK (&oldloc->inode->lock); + pthread_mutex_unlock (&ctx_old->pgfid_lock); if (op_ret < 0) { gf_msg (this->name, GF_LOG_WARNING, 0, P_MSG_XATTR_FAILED, @@ -2641,6 +2674,7 @@ posix_link (call_frame_t *frame, xlator_t *this, int32_t nlink_samepgfid = 0; char *pgfid_xattr_key = NULL; gf_boolean_t entry_created = _gf_false; + posix_inode_ctx_t *ctx = NULL; DECLARE_OLD_FS_ID_VAR; @@ -2707,14 +2741,20 @@ posix_link (call_frame_t *frame, xlator_t *this, MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX, newloc->pargfid); - LOCK (&newloc->inode->lock); + op_ret = posix_inode_ctx_get_all (newloc->inode, this, &ctx); + if (op_ret < 0) { + op_errno = ENOMEM; + goto out; + } + + pthread_mutex_lock (&ctx->pgfid_lock); { LINK_MODIFY_PGFID_XATTR (real_newpath, pgfid_xattr_key, nlink_samepgfid, 0, op_ret, this, unlock); } unlock: - UNLOCK (&newloc->inode->lock); + pthread_mutex_unlock (&ctx->pgfid_lock); if (op_ret < 0) { gf_msg (this->name, GF_LOG_WARNING, 0, diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 01a0bfa6860..4e43b1f2d32 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -194,6 +194,7 @@ typedef struct { uint64_t unlink_flag; pthread_mutex_t xattrop_lock; pthread_mutex_t write_atomic_lock; + pthread_mutex_t pgfid_lock; } posix_inode_ctx_t; #define POSIX_BASE_PATH(this) (((struct posix_private *)this->private)->base_path) -- cgit From b787c17b4143ef81882529d9ffebcab5fb0748f0 Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Sun, 19 Mar 2017 22:42:33 +0530 Subject: afr: do not mention split-brain in log message in read_txn I am seeing a lot of messages in qe/customer logs where read_txn complains that file is possibly in split-brain because of no readable subvol being found, does inode refresh and then there is no split-brain message post the inode refresh. This means that a lookup was not issued on the indoe to populate 'readable' or it can mean one brick is source for data and the other for metadata, making readable to be zero (because readable=intersection of (data,metadata readable) since commit 7a1c1e290470149696. Since we anyway log actual split-brains post inode-refresh, move this message to DEBUG log level. > Signed-off-by: Ravishankar N > Reviewed-on: https://review.gluster.org/16879 > Reviewed-by: Pranith Kumar Karampuri > Tested-by: Pranith Kumar Karampuri > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System (cherry picked from commit 71e023fcaab0058f32fedc7b6b702040fdd85f46) Change-Id: Idb88b8ea362515279dc9b246f06b6b646c6d8013 BUG: 1434302 Reviewed-on: https://review.gluster.org/16933 Tested-by: Ravishankar N Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Pranith Kumar Karampuri --- xlators/cluster/afr/src/afr-read-txn.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/xlators/cluster/afr/src/afr-read-txn.c b/xlators/cluster/afr/src/afr-read-txn.c index 2390764bccd..a7a2d2999bf 100644 --- a/xlators/cluster/afr/src/afr-read-txn.c +++ b/xlators/cluster/afr/src/afr-read-txn.c @@ -222,9 +222,8 @@ afr_read_txn (call_frame_t *frame, xlator_t *this, inode_t *inode, local->readable, NULL); if (read_subvol < 0 || read_subvol > priv->child_count) { - gf_msg (this->name, GF_LOG_WARNING, 0, AFR_MSG_SPLIT_BRAIN, - "Unreadable subvolume %d found with event generation " - "%d for gfid %s. (Possible split-brain)", + gf_msg_debug (this->name, 0, "Unreadable subvolume %d found " + "with event generation %d for gfid %s.", read_subvol, event_generation, uuid_utoa(inode->gfid)); goto refresh; } -- cgit From ca58ac814e2d983f6ebdf532a40ae9d5a216226b Mon Sep 17 00:00:00 2001 From: Xavier Hernandez Date: Thu, 9 Mar 2017 09:29:49 +0100 Subject: features/locks: Fix leak of posix_lock_t's client_uid > Change-Id: I3bc14998ed6a8841f77a004c24a456331048a521 > BUG: 1428510 > Signed-off-by: Xavier Hernandez > Reviewed-on: https://review.gluster.org/16838 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Amar Tumballi > Reviewed-by: Jeff Darcy Change-Id: I3bc14998ed6a8841f77a004c24a456331048a521 BUG: 1431592 Signed-off-by: Xavier Hernandez Reviewed-on: https://review.gluster.org/16896 Smoke: Gluster Build System CentOS-regression: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Pranith Kumar Karampuri --- xlators/features/locks/src/common.c | 92 ++++++++++++++++------------------ xlators/features/locks/src/posix.c | 6 +-- xlators/features/locks/src/reservelk.c | 18 ++----- 3 files changed, 47 insertions(+), 69 deletions(-) diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c index d56a7aca2be..68904f63140 100644 --- a/xlators/features/locks/src/common.c +++ b/xlators/features/locks/src/common.c @@ -433,7 +433,7 @@ pl_inode_get (xlator_t *this, inode_t *inode) INIT_LIST_HEAD (&pl_inode->blocked_reservelks); INIT_LIST_HEAD (&pl_inode->blocked_calls); INIT_LIST_HEAD (&pl_inode->metalk_list); - INIT_LIST_HEAD (&pl_inode->queued_locks); + INIT_LIST_HEAD (&pl_inode->queued_locks); gf_uuid_copy (pl_inode->gfid, inode->gfid); __inode_ctx_put (inode, this, (uint64_t)(long)(pl_inode)); @@ -505,9 +505,27 @@ __delete_lock (posix_lock_t *lock) void __destroy_lock (posix_lock_t *lock) { + GF_FREE (lock->client_uid); GF_FREE (lock); } +static posix_lock_t * +__copy_lock(posix_lock_t *src) +{ + posix_lock_t *dst; + + dst = GF_CALLOC(1, sizeof(posix_lock_t), gf_locks_mt_posix_lock_t); + if (dst != NULL) { + memcpy (dst, src, sizeof(posix_lock_t)); + dst->client_uid = gf_strdup(src->client_uid); + if (dst->client_uid == NULL) { + GF_FREE(dst); + dst = NULL; + } + } + + return dst; +} /* Convert a posix_lock to a struct gf_flock */ void @@ -613,11 +631,11 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small) if ((big->fl_start == small->fl_start) && (big->fl_end == small->fl_end)) { /* both edges coincide with big */ - v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[0]) + v.locks[0] = __copy_lock(big); + if (!v.locks[0]) { goto out; - memcpy (v.locks[0], big, sizeof (posix_lock_t)); + } + v.locks[0]->fl_type = small->fl_type; goto done; } @@ -625,27 +643,15 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small) if ((small->fl_start > big->fl_start) && (small->fl_end < big->fl_end)) { /* both edges lie inside big */ - v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[0]) - goto out; - - v.locks[1] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[1]) - goto out; - - v.locks[2] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[1]) + v.locks[0] = __copy_lock(big); + v.locks[1] = __copy_lock(small); + v.locks[2] = __copy_lock(big); + if ((v.locks[0] == NULL) || (v.locks[1] == NULL) || + (v.locks[2] == NULL)) { goto out; + } - memcpy (v.locks[0], big, sizeof (posix_lock_t)); v.locks[0]->fl_end = small->fl_start - 1; - - memcpy (v.locks[1], small, sizeof (posix_lock_t)); - - memcpy (v.locks[2], big, sizeof (posix_lock_t)); v.locks[2]->fl_start = small->fl_end + 1; goto done; @@ -653,38 +659,24 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small) /* one edge coincides with big */ if (small->fl_start == big->fl_start) { - v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[0]) - goto out; - - v.locks[1] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[1]) + v.locks[0] = __copy_lock(big); + v.locks[1] = __copy_lock(small); + if ((v.locks[0] == NULL) || (v.locks[1] == NULL)) { goto out; + } - memcpy (v.locks[0], big, sizeof (posix_lock_t)); v.locks[0]->fl_start = small->fl_end + 1; - - memcpy (v.locks[1], small, sizeof (posix_lock_t)); goto done; } if (small->fl_end == big->fl_end) { - v.locks[0] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[0]) - goto out; - - v.locks[1] = GF_CALLOC (1, sizeof (posix_lock_t), - gf_locks_mt_posix_lock_t); - if (!v.locks[1]) + v.locks[0] = __copy_lock(big); + v.locks[1] = __copy_lock(small); + if ((v.locks[0] == NULL) || (v.locks[1] == NULL)) { goto out; + } - memcpy (v.locks[0], big, sizeof (posix_lock_t)); v.locks[0]->fl_end = small->fl_start - 1; - - memcpy (v.locks[1], small, sizeof (posix_lock_t)); goto done; } @@ -693,15 +685,15 @@ subtract_locks (posix_lock_t *big, posix_lock_t *small) out: if (v.locks[0]) { - GF_FREE (v.locks[0]); + __destroy_lock(v.locks[0]); v.locks[0] = NULL; } if (v.locks[1]) { - GF_FREE (v.locks[1]); + __destroy_lock(v.locks[1]); v.locks[1] = NULL; } if (v.locks[2]) { - GF_FREE (v.locks[2]); + __destroy_lock(v.locks[2]); v.locks[2] = NULL; } @@ -967,7 +959,7 @@ grant_blocked_locks (xlator_t *this, pl_inode_t *pl_inode) STACK_UNWIND_STRICT (lk, lock->frame, 0, 0, &lock->user_flock, NULL); - GF_FREE (lock); + __destroy_lock(lock); } return; @@ -1013,7 +1005,7 @@ pl_send_prelock_unlock (xlator_t *this, pl_inode_t *pl_inode, STACK_UNWIND_STRICT (lk, lock->frame, 0, 0, &lock->user_flock, NULL); - GF_FREE (lock); + __destroy_lock(lock); } out: diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index 3415d59324c..f217220a04b 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -3077,8 +3077,7 @@ out: STACK_UNWIND_STRICT (lk, posix_lock->frame, -1, EREMOTE, &posix_lock->user_flock, NULL); - GF_FREE (posix_lock->client_uid); - GF_FREE (posix_lock); + __destroy_lock(posix_lock); } return ret; @@ -3572,8 +3571,7 @@ unlock: STACK_UNWIND_STRICT (lk, posix_lock->frame, -1, EREMOTE, &posix_lock->user_flock, NULL); - GF_FREE (posix_lock->client_uid); - GF_FREE (posix_lock); + __destroy_lock(posix_lock); } return 0; } diff --git a/xlators/features/locks/src/reservelk.c b/xlators/features/locks/src/reservelk.c index 8eb08d0ef79..13b23f9f887 100644 --- a/xlators/features/locks/src/reservelk.c +++ b/xlators/features/locks/src/reservelk.c @@ -18,18 +18,6 @@ #include "locks.h" #include "common.h" -void -__delete_reserve_lock (posix_lock_t *lock) -{ - list_del (&lock->list); -} - -void -__destroy_reserve_lock (posix_lock_t *lock) -{ - GF_FREE (lock); -} - /* Return true if the two reservelks have exactly same lock boundaries */ int reservelks_equal (posix_lock_t *l1, posix_lock_t *l2) @@ -110,7 +98,7 @@ __reservelk_conflict (xlator_t *this, pl_inode_t *pl_inode, list_del_init (&conf->list); gf_log (this->name, GF_LOG_TRACE, "Removing the matching reservelk for setlk to progress"); - GF_FREE (conf); + __destroy_lock(conf); ret = 0; } else { gf_log (this->name, GF_LOG_TRACE, @@ -217,7 +205,7 @@ __reserve_unlock_lock (xlator_t *this, posix_lock_t *lock, pl_inode_t *pl_inode) " Matching lock not found for unlock"); goto out; } - __delete_reserve_lock (conf); + __delete_lock(conf); gf_log (this->name, GF_LOG_DEBUG, " Matching lock found for unlock"); @@ -392,7 +380,7 @@ pl_reserve_unlock (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock) gf_log (this->name, GF_LOG_TRACE, "Reservelk Unlock successful"); - __destroy_reserve_lock (retlock); + __destroy_lock(retlock); ret = 0; } out: -- cgit From cbded629e9ba2d293832e9ed9e81e0390ef29f72 Mon Sep 17 00:00:00 2001 From: Sunil Kumar Acharya Date: Mon, 27 Feb 2017 15:35:17 +0530 Subject: cluster/ec: Metadata healing fails to update the version During meatadata heal, we were not updating the version though all the inode attributes were in sync. Updated the code to adjust version when all the inode attributes are in sync. >BUG: 1425703 >Change-Id: I6723be3c5f748b286d4efdaf3c71e9d2087c7235 >Signed-off-by: Sunil Kumar Acharya >Reviewed-on: https://review.gluster.org/16772 >Smoke: Gluster Build System >Reviewed-by: Xavier Hernandez >NetBSD-regression: NetBSD Build System >Reviewed-by: Pranith Kumar Karampuri >CentOS-regression: Gluster Build System BUG: 1434298 Change-Id: I5b74423253138957644b1bfa543d4abb2532c377 Signed-off-by: Sunil Kumar Acharya Reviewed-on: https://review.gluster.org/16935 Smoke: Gluster Build System CentOS-regression: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Xavier Hernandez --- xlators/cluster/ec/src/ec-heal.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c index da08f6c9a75..2373e6f93d5 100644 --- a/xlators/cluster/ec/src/ec-heal.c +++ b/xlators/cluster/ec/src/ec-heal.c @@ -410,6 +410,8 @@ ec_adjust_versions (call_frame_t *frame, ec_t *ec, ec_txn_t type, if (EC_COUNT (sources, ec->nodes) + EC_COUNT (healed_sinks, ec->nodes) == ec->nodes) erase_dirty = _gf_true; + else + op_ret = -ENOTCONN; for (i = 0; i < ec->nodes; i++) { if (!sources[i] && !healed_sinks[i]) @@ -509,7 +511,7 @@ ec_heal_metadata_find_direction (ec_t *ec, default_args_cbk_t *replies, if (!are_dicts_equal(replies[i].xdata, replies[j].xdata, ec_sh_key_match, NULL)) continue; - groups[j] = i; /*If iatts match put them into a group*/ + groups[j] = i; same_count++; } @@ -541,7 +543,6 @@ out: return ret; } - int __ec_heal_metadata_prepare (call_frame_t *frame, ec_t *ec, inode_t *inode, unsigned char *locked_on, default_args_cbk_t *replies, @@ -679,15 +680,12 @@ __ec_heal_metadata (call_frame_t *frame, ec_t *ec, inode_t *inode, goto out; } - if (EC_COUNT (sources, ec->nodes) == ec->nodes) { + if ((EC_COUNT (sources, ec->nodes) == ec->nodes) || + (EC_COUNT (healed_sinks, ec->nodes) == 0)) { ret = 0; goto erase_dirty; } - if (EC_COUNT (healed_sinks, ec->nodes) == 0) { - ret = -ENOTCONN; - goto out; - } source_buf = replies[source].stat; ret = cluster_setattr (ec->xl_list, healed_sinks, ec->nodes, sreplies, output, frame, ec->xl, &loc, -- cgit From 50ac9c87020d0e9712491c04afbb208a01c6ecbd Mon Sep 17 00:00:00 2001 From: karthik-us Date: Sat, 18 Mar 2017 13:44:56 +0530 Subject: cluster/afr: Undo pending xattrs only on the up bricks Problem: While doing conservative merge, even if a brick is down, it will reset the pending xattr on that. When that brick comes up, as part of the heal, it will consider this brick as the source and removes the entries on the other bricks, which leads to data loss. Fix: Undo pending only for the bricks which are up. > Change-Id: I18436fa0bb1faa5f60531b357dea3f6b20446303 > BUG: 1433571 > Signed-off-by: karthik-us > Reviewed-on: https://review.gluster.org/16913 > Reviewed-by: Pranith Kumar Karampuri > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Ravishankar N (cherry picked from commit f91596e6566c605e70a31a60523d11f78a097c3c) Change-Id: Id20c9ce53ee59f005d977494903247e2a8024ed1 BUG: 1436231 Signed-off-by: karthik-us Reviewed-on: https://review.gluster.org/16956 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Ravishankar N Reviewed-by: Pranith Kumar Karampuri --- .../bug-1433571-undo-pending-only-on-up-bricks.t | 89 ++++++++++++++++++++++ xlators/cluster/afr/src/afr-self-heal-common.c | 2 +- 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t diff --git a/tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t b/tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t new file mode 100644 index 00000000000..271abb4fe9a --- /dev/null +++ b/tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t @@ -0,0 +1,89 @@ +#!/bin/bash +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2} +TEST $CLI volume start $V0 +TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0; + +# Disable self-heal-daemon, client-side-heal and set quorum-type to none +TEST $CLI volume set $V0 cluster.self-heal-daemon off +TEST $CLI volume set $V0 cluster.data-self-heal off +TEST $CLI volume set $V0 cluster.metadata-self-heal off +TEST $CLI volume set $V0 cluster.entry-self-heal off +TEST $CLI volume set $V0 cluster.quorum-type none + +#Kill bricks 0 & 1 and create a file to have pending entry for 0 & 1 on brick 2 +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST kill_brick $V0 $H0 $B0/${V0}1 +echo "file 1" >> $M0/f1 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2 + +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1 + +#Kill bricks 1 & 2 and create a file to have pending entry for 1 & 2 on brick 0 +TEST kill_brick $V0 $H0 $B0/${V0}1 +TEST kill_brick $V0 $H0 $B0/${V0}2 +echo "file 2" >> $M0/f2 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}0 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}0 + +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 2 + +#Kill bricks 2 & 0 and create a file to have pending entry for 2 & 0 on brick 1 +TEST kill_brick $V0 $H0 $B0/${V0}2 +TEST kill_brick $V0 $H0 $B0/${V0}0 +echo "file 3" >> $M0/f3 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1 + +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 2 + +#Kill brick 0 and turn on the client side heal and do ls to trigger the heal. +#The pending xattrs on bricks 1 & 2 should have pending entry on brick 0. +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST $CLI volume set $V0 cluster.data-self-heal on +TEST $CLI volume set $V0 cluster.metadata-self-heal on +TEST $CLI volume set $V0 cluster.entry-self-heal on + +TEST ls $M0 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1 +EXPECT "000000000000000000000001" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2 + +#Bring back all the bricks and trigger the heal again by doing ls. Now the +#pending xattrs on all the bricks should be 0. +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 +TEST ls $M0 + +TEST cat $M0/f1 +TEST cat $M0/f2 +TEST cat $M0/f3 + +EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V0 + +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}0 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}0 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2 +EXPECT "000000000000000000000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2 + +#Check whether all the bricks contains all the 3 files. +EXPECT "3" echo $(ls $B0/${V0}0 | wc -l) +EXPECT "3" echo $(ls $B0/${V0}1 | wc -l) +EXPECT "3" echo $(ls $B0/${V0}2 | wc -l) + +cleanup; diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index 6d1ae1312ea..adf5ab20a6c 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -247,7 +247,7 @@ afr_selfheal_undo_pending (call_frame_t *frame, xlator_t *this, inode_t *inode, output_matrix[i][j] = 1; if (type == AFR_ENTRY_TRANSACTION) full_heal_mtx_out[i][j] = 1; - } else { + } else if (locked_on[j]) { output_matrix[i][j] = -input_matrix[i][j]; if (type == AFR_ENTRY_TRANSACTION) full_heal_mtx_out[i][j] = -full_heal_mtx_in[i][j]; -- cgit From abe5b927878bb72e177942a79586300d98ac44f8 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Tue, 7 Mar 2017 18:01:25 +0100 Subject: glusterd: support filesystems with dynamic inode sizes btrfs and zfs are two filesystems that do not have fixed sizes for inodes. Instead of logging an error, skip checking and mark the size as "N/A" like other properties that can not be reported. The error message that was reported by users on the mailinglist shows up like: [glusterd-utils.c:5458:glusterd_add_inode_size_to_dict] 0-management: could not find (null) to getinode size for /dev/vdb (btrfs): (null) package missing? Cherry picked from commit 12921693b572f642156d3167d1c92d3449dfc8ec: > Change-Id: Ib10b7a3669f2f4221075715d9fd44ce1ffc35324 > Reported-by: Arman Khalatyan > URL: http://lists.gluster.org/pipermail/gluster-users/2017-March/030189.html > BUG: 1433425 > Signed-off-by: Niels de Vos > Reviewed-on: https://review.gluster.org/16867 > Smoke: Gluster Build System > Reviewed-by: Atin Mukherjee > Reviewed-by: Prashanth Pai > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System Change-Id: Ib10b7a3669f2f4221075715d9fd44ce1ffc35324 Reported-by: Arman Khalatyan BUG: 1436412 Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/16960 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Zhou Zhengping --- xlators/mgmt/glusterd/src/glusterd-utils.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 46d932bbc2e..931683486ab 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -5382,6 +5382,7 @@ static struct fs_info { { "ext3", "tune2fs", "-l", "Inode size:", "e2fsprogs" }, { "ext4", "tune2fs", "-l", "Inode size:", "e2fsprogs" }, { "btrfs", NULL, NULL, NULL, NULL }, + { "zfs", NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL} }; @@ -5426,6 +5427,16 @@ glusterd_add_inode_size_to_dict (dict_t *dict, int count) for (fs = glusterd_fs ; fs->fs_type_name; fs++) { if (strcmp (fs_name, fs->fs_type_name) == 0) { + if (!fs->fs_tool_name) { + /* dynamic inodes */ + gf_msg (THIS->name, GF_LOG_INFO, 0, + GD_MSG_INODE_SIZE_GET_FAIL, "the " + "brick on %s (%s) uses dynamic inode " + "sizes", device, fs_name); + cur_word = "N/A"; + goto cached; + } + snprintf (fs_tool_name, sizeof (fs_tool_name), "/usr/sbin/%s", fs->fs_tool_name); if (sys_access (fs_tool_name, R_OK|X_OK) == 0) -- cgit From e7b96efd37ed04fdfe8454f84e3e803f7edc754b Mon Sep 17 00:00:00 2001 From: Ashish Pandey Date: Thu, 14 Apr 2016 16:19:40 +0530 Subject: cluster/ec: Add/Modify description for eager-lock option This patch provides description for disperse.eager-lock option for disperse volume. It also modifies the description for cluster.eager-lock option to indicate that this option is only for replica volume. >Change-Id: Ie73298947fcaaa6aaf825978bc2d27ceaff386d2 >BUG: 1327171 >Signed-off-by: Ashish Pandey >Reviewed-on: http://review.gluster.org/13999 >NetBSD-regression: NetBSD Build System >Smoke: Gluster Build System >Reviewed-by: Ravishankar N >CentOS-regression: Gluster Build System >Reviewed-by: Pranith Kumar Karampuri BUG: 1435645 Change-Id: I48b091e002b5c3308d6fbf2feb024a7f2fe08969 Signed-off-by: Sunil Kumar Acharya Reviewed-on: https://review.gluster.org/16943 Smoke: Gluster Build System CentOS-regression: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Xavier Hernandez --- xlators/cluster/afr/src/afr.c | 9 +++++---- xlators/cluster/ec/src/ec.c | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index 6f4783c9213..af81b77ddb6 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -766,16 +766,17 @@ struct volume_options options[] = { { .key = {"eager-lock"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", - .description = "Lock phase of a transaction has two sub-phases. " + .description = "Enable/Disable eager lock for replica volume. " + "Lock phase of a transaction has two sub-phases. " "First is an attempt to acquire locks in parallel by " "broadcasting non-blocking lock requests. If lock " "acquisition fails on any server, then the held locks " - "are unlocked and revert to a blocking locked mode " + "are unlocked and we revert to a blocking locks mode " "sequentially on one server after another. If this " "option is enabled the initial broadcasting lock " - "request attempt to acquire lock on the entire file. " + "request attempts to acquire a full lock on the entire file. " "If this fails, we revert back to the sequential " - "\"regional\" blocking lock as before. In the case " + "\"regional\" blocking locks as before. In the case " "where such an \"eager\" lock is granted in the " "non-blocking phase, it gives rise to an opportunity " "for optimization. i.e, if the next write transaction " diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c index b5e6bc08216..0a3a3cce391 100644 --- a/xlators/cluster/ec/src/ec.c +++ b/xlators/cluster/ec/src/ec.c @@ -1328,8 +1328,18 @@ struct volume_options options[] = { .key = {"eager-lock"}, .type = GF_OPTION_TYPE_BOOL, .default_value = "on", - .description = "This option will enable/diable eager lock for" - "disperse volume " + .description = "Enable/Disable eager lock for disperse volume. " + "If a fop takes a lock and completes its operation, " + "it waits for next 1 second before releasing the lock, " + "to see if the lock can be reused for next fop from " + "the same client. If ec finds any lock contention within " + "1 second it releases the lock immediately before time " + "expires. This improves the performance of file operations." + "However, as it takes lock on first brick, for few operations " + "like read, discovery of lock contention might take long time " + "and can actually degrade the performance. " + "If eager lock is disabled, lock will be released as soon as fop " + "completes. " }, { .key = {"background-heals"}, .type = GF_OPTION_TYPE_INT, -- cgit From 982de32c7f559ab57f66a9ee92f884b772bae1e4 Mon Sep 17 00:00:00 2001 From: Poornima G Date: Tue, 14 Feb 2017 12:45:36 +0530 Subject: rpcsvc: Add rpchdr and proghdr to iobref before submitting to transport Backport of https://review.gluster.org/16613 Issue: When fio is run on multiple clients (each client writes to its own files), and meanwhile the clients does a readdirp, thus the client which did a readdirp will now recieve the upcalls. In this scenario the client disconnects with rpc decode failed error. RCA: Upcall calls rpcsvc_request_submit to submit the request to socket: rpcsvc_request_submit currently: rpcsvc_request_submit () { iobuf = iobuf_new iov = iobuf->ptr fill iobuf to contain xdrised upcall content - proghdr rpcsvc_callback_submit (..iov..) ... if (iobuf) iobuf_unref (iobuf) } rpcsvc_callback_submit (... iov...) { ... iobuf = iobuf_new iov1 = iobuf->ptr fill iobuf to contain xdrised rpc header - rpchdr msg.rpchdr = iov1 msg.proghdr = iov ... rpc_transport_submit_request (msg) ... if (iobuf) iobuf_unref (iobuf) } rpcsvc_callback_submit assumes that once rpc_transport_submit_request() returns the msg is written on to socket and thus the buffers(rpchdr, proghdr) can be freed, which is not the case. In especially high workload, rpc_transport_submit_request() may not be able to write to socket immediately and hence adds it to its own queue and returns as successful. Thus, we have use after free, for rpchdr and proghdr. Hence the clients gets garbage rpchdr and proghdr and thus fails to decode the rpc, resulting in disconnect. To prevent this, we need to add the rpchdr and proghdr to a iobref and send it in msg: iobref_add (iobref, iobufs) msg.iobref = iobref; The socket layer takes a ref on msg.iobref, if it cannot write to socket and is adding to the queue. Thus we do not have use after free. Thank You for discussing, debugging and fixing along: Prashanth Pai Raghavendra G Rajesh Joseph Kotresh HR Mohammed Rafi KC Soumya Koduri > Reviewed-on: https://review.gluster.org/16613 > Reviewed-by: Prashanth Pai > Smoke: Gluster Build System > Reviewed-by: soumya k > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Raghavendra G Change-Id: Ifa6bf6f4879141f42b46830a37c1574b21b37275 BUG: 1422788 Signed-off-by: Poornima G Reviewed-on: https://review.gluster.org/16638 CentOS-regression: Gluster Build System Smoke: Gluster Build System Reviewed-by: Prashanth Pai NetBSD-regression: NetBSD Build System Reviewed-by: Raghavendra G --- rpc/rpc-lib/src/rpcsvc.c | 33 +++++++++++++++++++++++++++++++-- rpc/rpc-lib/src/rpcsvc.h | 3 ++- xlators/mgmt/glusterd/src/glusterd.c | 6 ++++-- xlators/protocol/server/src/server.c | 20 +++++++++++++------- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c index f07e745a4b3..5a5c65114c4 100644 --- a/rpc/rpc-lib/src/rpcsvc.c +++ b/rpc/rpc-lib/src/rpcsvc.c @@ -1020,6 +1020,7 @@ int rpcsvc_request_submit (rpcsvc_t *rpc, rpc_transport_t *trans, struct iovec iov = {0, }; struct iobuf *iobuf = NULL; ssize_t xdr_size = 0; + struct iobref *iobref = NULL; if (!req) goto out; @@ -1042,20 +1043,33 @@ int rpcsvc_request_submit (rpcsvc_t *rpc, rpc_transport_t *trans, iov.iov_len = ret; count = 1; + iobref = iobref_new (); + if (!iobref) { + ret = -1; + gf_log ("rpcsvc", GF_LOG_WARNING, "Failed to create iobref"); + goto out; + } + + iobref_add (iobref, iobuf); + ret = rpcsvc_callback_submit (rpc, trans, prog, procnum, - &iov, count); + &iov, count, iobref); out: if (iobuf) iobuf_unref (iobuf); + if (iobref) + iobref_unref (iobref); + return ret; } int rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, rpcsvc_cbk_program_t *prog, int procnum, - struct iovec *proghdr, int proghdrcount) + struct iovec *proghdr, int proghdrcount, + struct iobref *iobref) { struct iobuf *request_iob = NULL; struct iovec rpchdr = {0,}; @@ -1063,6 +1077,7 @@ rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, int ret = -1; int proglen = 0; uint32_t xid = 0; + gf_boolean_t new_iobref = _gf_false; if (!rpc) { goto out; @@ -1084,11 +1099,22 @@ rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, "cannot build rpc-record"); goto out; } + if (!iobref) { + iobref = iobref_new (); + if (!iobref) { + gf_log ("rpcsvc", GF_LOG_WARNING, "Failed to create iobref"); + goto out; + } + new_iobref = 1; + } + + iobref_add (iobref, request_iob); req.msg.rpchdr = &rpchdr; req.msg.rpchdrcount = 1; req.msg.proghdr = proghdr; req.msg.proghdrcount = proghdrcount; + req.msg.iobref = iobref; ret = rpc_transport_submit_request (trans, &req); if (ret == -1) { @@ -1102,6 +1128,9 @@ rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, out: iobuf_unref (request_iob); + if (new_iobref) + iobref_unref (iobref); + return ret; } diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h index 02e467e68a7..08402373be6 100644 --- a/rpc/rpc-lib/src/rpcsvc.h +++ b/rpc/rpc-lib/src/rpcsvc.h @@ -584,7 +584,8 @@ int rpcsvc_request_submit (rpcsvc_t *rpc, rpc_transport_t *trans, int rpcsvc_callback_submit (rpcsvc_t *rpc, rpc_transport_t *trans, rpcsvc_cbk_program_t *prog, int procnum, - struct iovec *proghdr, int proghdrcount); + struct iovec *proghdr, int proghdrcount, + struct iobref *iobref); rpcsvc_actor_t * rpcsvc_program_actor (rpcsvc_request_t *req); diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index 26cd0fc4f25..c2272558939 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -244,7 +244,8 @@ glusterd_fetchspec_notify (xlator_t *this) list_for_each_entry (trans, &priv->xprt_list, list) { rpcsvc_callback_submit (priv->rpc, trans, &glusterd_cbk_prog, - GF_CBK_FETCHSPEC, NULL, 0); + GF_CBK_FETCHSPEC, NULL, 0, + NULL); } } pthread_mutex_unlock (&priv->xprt_lock); @@ -280,7 +281,8 @@ glusterd_fetchsnap_notify (xlator_t *this) list_for_each_entry (trans, &priv->xprt_list, list) { rpcsvc_callback_submit (priv->rpc, trans, &glusterd_cbk_prog, - GF_CBK_GET_SNAPS, NULL, 0); + GF_CBK_GET_SNAPS, NULL, 0, + NULL); } } pthread_mutex_unlock (&priv->xprt_lock); diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index 10009e2b4a7..7ab0862b0a2 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -1235,12 +1235,18 @@ server_process_event_upcall (xlator_t *this, void *data) if (!client || strcmp(client->client_uid, client_uid)) continue; - rpcsvc_request_submit(conf->rpc, xprt, - &server_cbk_prog, - cbk_procnum, - up_req, - this->ctx, - xdrproc); + ret = rpcsvc_request_submit (conf->rpc, xprt, + &server_cbk_prog, + cbk_procnum, + up_req, + this->ctx, + xdrproc); + if (ret < 0) { + gf_msg_debug (this->name, 0, "Failed to send " + "upcall to client:%s upcall " + "event:%d", client_uid, + upcall_data->event_type); + } break; } } @@ -1272,7 +1278,7 @@ server_process_child_event (xlator_t *this, int32_t event, void *data, rpcsvc_callback_submit (conf->rpc, xprt, &server_cbk_prog, cbk_procnum, - NULL, 0); + NULL, 0, NULL); } } pthread_mutex_unlock (&conf->mutex); -- cgit From a01d6f460c09c67f647aa529fc38a229e8461d4e Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Thu, 30 Mar 2017 14:58:38 +0530 Subject: cluster/dht: Modify local->loc.gfid in thread safe manner Backport of https://review.gluster.org/16986 Problem: local->loc.gfid in dht_lookup_directory() will be null-gfid for a fresh lookup. dht_lookup_dir_cbk() updates local->loc.gfid while in other thread dht_lookup_directory() is still winding lookup calls to subvolumes so there is a chance of partial gfid being seen by EC. We saw in 12x(4+2) volume, ec is receiving an loc where the gfid has last 10 bytes matching with the gfid of the directory and the first 4 bytes are all-zeros. This is leading to EC erroring out the lookup with EINVAL which leads to NFS failing lookup with EIO. snip from gdb: $37 = (dht_local_t *) 0x7fde5de5b3cc (gdb) p /x $37->loc.gfid $39 = {0x3b, 0x82, 0x10, 0x5e, 0x40, 0x65, 0x43, 0x14, 0xa0, 0xc6, 0x8, 0xf5, 0x6c, 0x2c, 0xb8, 0x56} (gdb) fr 7 state=) at ec-generic.c:837 837 ec_lookup_rebuild(fop->xl->private, fop, cbk); (gdb) p /x fop->loc[0].gfid $40 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x43, 0x14, 0xa0, 0xc6, 0x8, 0xf5, 0x6c, 0x2c, 0xb8, 0x56} snip from log: [2017-01-29 03:22:30.132328] W [MSGID: 122019] [ec-helpers.c:354:ec_loc_gfid_check] 0-butcher-disperse-4: Mismatching GFID's in loc [2017-01-29 03:22:30.132709] W [MSGID: 112199] [nfs3-helpers.c:3515:nfs3_log_newfh_res] 0-nfs-nfsv3: /linux-4.9.5/Documentation => (XID: b27b9474, MKDIR: NFS: 5(I/O error), POSIX: 5(Input/output error)), FH: exportid 00000000-0000-0000-0000-000000000000, gfid 00000000-0000-0000-0000-000000000000, mountid 00000000-0000-0000-0000-000000000000 [Invalid argument] Fix: update local->loc.gfid in last-call to make sure there are no races. >BUG: 1438411 >Change-Id: Ifcb7e911568c1f1f83123da6ff0cf742b91800a0 >Signed-off-by: Pranith Kumar K BUG: 1438424 Change-Id: If039956205cfac5e798c2c90e92a9a47b404e804 Signed-off-by: Pranith Kumar K Reviewed-on: https://review.gluster.org/16988 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Raghavendra G --- xlators/cluster/dht/src/dht-common.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 74a2aa78ca7..a50d6fe5628 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -809,8 +809,6 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!op_ret && gf_uuid_is_null (local->gfid)) memcpy (local->gfid, stbuf->ia_gfid, 16); - memcpy (local->loc.gfid, local->gfid, 16); - /* Check if the gfid is different for file from other node */ if (!op_ret && gf_uuid_compare (local->gfid, stbuf->ia_gfid)) { @@ -879,6 +877,8 @@ unlock: this_call_cnt = dht_frame_return (frame); if (is_last_call (this_call_cnt)) { + gf_uuid_copy (local->loc.gfid, local->gfid); + if (local->need_selfheal) { local->need_selfheal = 0; dht_lookup_everywhere (frame, this, &local->loc); @@ -919,7 +919,6 @@ unlock: selfheal: FRAME_SU_DO (frame, dht_local_t); - gf_uuid_copy (local->loc.gfid, local->gfid); ret = dht_selfheal_directory (frame, dht_lookup_selfheal_cbk, &local->loc, layout); out: -- cgit From a2c3f86db8c9eea19359ddef9d9595b2d372814c Mon Sep 17 00:00:00 2001 From: karthik-us Date: Tue, 4 Apr 2017 18:57:32 +0530 Subject: features/worm: Adding implementation for ftruncate Problem: Since the ftruncate fop was not handled in the worm feature, when truncate and write was happening on a worm-retained/worm file, it was giving the EROFS error but truncating the file, which is not correct. > Change-Id: I1a7e904655210d78bce9e01652ac56f3783b5aed > BUG: 1438810 > Signed-off-by: karthik-us > Reviewed-on: https://review.gluster.org/16995 > NetBSD-regression: NetBSD Build System > Reviewed-by: Niels de Vos > CentOS-regression: Gluster Build System > Reviewed-by: Ravishankar N > Smoke: Gluster Build System > Reviewed-by: Amar Tumballi > Reviewed-by: Raghavendra Talur (cherry picked from commit c5a4a77848024d2adf8cd4f35d550ba90c174fc7) Change-Id: Ic5e904b5bb3d76954a143f92fbfd8959fec884b8 BUG: 1439112 Signed-off-by: karthik-us Reviewed-on: https://review.gluster.org/17000 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Ravishankar N Reviewed-by: Niels de Vos --- xlators/features/read-only/src/worm.c | 40 +++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/xlators/features/read-only/src/worm.c b/xlators/features/read-only/src/worm.c index 3e32d65dbac..dd9d720e569 100644 --- a/xlators/features/read-only/src/worm.c +++ b/xlators/features/read-only/src/worm.c @@ -35,7 +35,7 @@ worm_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { if (is_readonly_or_worm_enabled (this) && - (flags & (O_WRONLY | O_RDWR | O_APPEND))) { + (flags & (O_WRONLY | O_RDWR | O_APPEND | O_TRUNC))) { STACK_UNWIND_STRICT (open, frame, -1, EROFS, NULL, NULL); return 0; } @@ -175,7 +175,7 @@ worm_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, goto out; } op_errno = gf_worm_state_transition (this, _gf_false, loc, - GF_FOP_TRUNCATE); + GF_FOP_TRUNCATE); out: if (op_errno) @@ -189,6 +189,41 @@ out: } +static int32_t +worm_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + dict_t *xdata) +{ + int op_errno = EROFS; + read_only_priv_t *priv = NULL; + + priv = this->private; + GF_ASSERT (priv); + if (is_readonly_or_worm_enabled (this)) + goto out; + if (!priv->worm_file) { + op_errno = 0; + goto out; + } + + if (is_wormfile (this, _gf_true, fd)) { + op_errno = 0; + goto out; + } + op_errno = gf_worm_state_transition (this, _gf_true, fd, + GF_FOP_FTRUNCATE); + +out: + if (op_errno) + STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL, + NULL); + else + STACK_WIND_TAIL (frame, FIRST_CHILD (this), + FIRST_CHILD (this)->fops->ftruncate, + fd, offset, xdata); + return 0; +} + + static int32_t worm_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) @@ -557,6 +592,7 @@ struct xlator_fops fops = { .link = worm_link, .unlink = worm_unlink, .truncate = worm_truncate, + .ftruncate = worm_ftruncate, .create = worm_create, .rmdir = ro_rmdir, -- cgit From d5d599abaa598062885abc7ad8226faf26d11e64 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Mon, 10 Apr 2017 11:04:31 +0530 Subject: features/shard: Initialize local->fop in readv Backport of: https://review.gluster.org/17014 Change-Id: I4d2f0a3f533009038d48579db5a8a2a048b77ca1 BUG: 1440635 Signed-off-by: Krutika Dhananjay Reviewed-on: https://review.gluster.org/17020 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Pranith Kumar Karampuri CentOS-regression: Gluster Build System --- xlators/features/shard/src/shard.c | 1 + 1 file changed, 1 insertion(+) diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index 9504f12da85..33c501f8498 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -3566,6 +3566,7 @@ shard_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, local->offset = offset; local->req_size = size; local->flags = flags; + local->fop = GF_FOP_READ; local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new (); if (!local->xattr_req) goto err; -- cgit From d71ec72b981d110199c3376f39f91b704241975c Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Thu, 6 Apr 2017 18:10:41 +0530 Subject: features/shard: Fix vm corruption upon fix-layout Backport of: https://review.gluster.org/17010 shard's writev implementation, as part of identifying presence of participant shards that aren't in memory, first sends an MKNOD on these shards, and upon EEXIST error, looks up the shards before proceeding with the writes. The VM corruption was caused when the following happened: 1. DHT had n subvolumes initially. 2. Upon add-brick + fix-layout, the layout of .shard changed although the existing shards under it were yet to be migrated to their new hashed subvolumes. 3. During this time, there were writes on the VM falling in regions of the file whose corresponding shards were already existing under .shard. 4. Sharding xl sent MKNOD on these shards, now creating them in their new hashed subvolumes although there already exist shard blocks for this region with valid data. 5. All subsequent writes were wound on these newly created copies. The net outcome is that both copies of the shard didn't have the correct data. This caused the affected VMs to be unbootable. FIX: For want of better alternatives in DHT, the fix changes shard fops to do a LOOKUP before the MKNOD and upon EEXIST error, perform another lookup. Change-Id: I1a5d3515b42e2e5583c407d1b4aff44d7ce472eb BUG: 1440635 RCA'd-by: Raghavendra Gowdappa Reported-by: Mahdi Adnan Signed-off-by: Krutika Dhananjay Reviewed-on: https://review.gluster.org/17019 CentOS-regression: Gluster Build System NetBSD-regression: NetBSD Build System Smoke: Gluster Build System Reviewed-by: jiffin tony Thottan --- xlators/features/shard/src/shard.c | 154 +++++++++++++++++++++++-------------- xlators/features/shard/src/shard.h | 1 + 2 files changed, 96 insertions(+), 59 deletions(-) diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c index 33c501f8498..4dd581dd19e 100644 --- a/xlators/features/shard/src/shard.c +++ b/xlators/features/shard/src/shard.c @@ -1693,11 +1693,30 @@ shard_common_lookup_shards_cbk (call_frame_t *frame, void *cookie, if (op_ret < 0) { /* Ignore absence of shards in the backend in truncate fop. */ - if (((local->fop == GF_FOP_TRUNCATE) || - (local->fop == GF_FOP_FTRUNCATE) || - (local->fop == GF_FOP_RENAME) || - (local->fop == GF_FOP_UNLINK)) && (op_errno == ENOENT)) - goto done; + switch (local->fop) { + case GF_FOP_TRUNCATE: + case GF_FOP_FTRUNCATE: + case GF_FOP_RENAME: + case GF_FOP_UNLINK: + if (op_errno == ENOENT) + goto done; + break; + case GF_FOP_WRITE: + case GF_FOP_READ: + case GF_FOP_ZEROFILL: + case GF_FOP_DISCARD: + case GF_FOP_FALLOCATE: + if ((!local->first_lookup_done) && + (op_errno == ENOENT)) { + local->create_count++; + goto done; + } + break; + default: + break; + } + + /* else */ gf_msg (this->name, GF_LOG_ERROR, op_errno, SHARD_MSG_LOOKUP_SHARD_FAILED, "Lookup on shard %d " "failed. Base file gfid = %s", shard_block_num, @@ -1714,6 +1733,8 @@ shard_common_lookup_shards_cbk (call_frame_t *frame, void *cookie, done: call_count = shard_call_count_return (frame); if (call_count == 0) { + if (!local->first_lookup_done) + local->first_lookup_done = _gf_true; if (local->op_ret < 0) goto unwind; else @@ -3196,47 +3217,6 @@ next: return 0; } -int -shard_post_lookup_shards_readv_handler (call_frame_t *frame, xlator_t *this) -{ - shard_local_t *local = NULL; - - local = frame->local; - - if (local->op_ret < 0) { - SHARD_STACK_UNWIND (readv, frame, local->op_ret, - local->op_errno, NULL, 0, NULL, NULL, NULL); - return 0; - } - - shard_readv_do (frame, this); - - return 0; -} - -int -shard_post_mknod_readv_handler (call_frame_t *frame, xlator_t *this) -{ - shard_local_t *local = NULL; - - local = frame->local; - - if (local->op_ret < 0) { - SHARD_STACK_UNWIND (readv, frame, local->op_ret, - local->op_errno, NULL, 0, NULL, NULL, NULL); - return 0; - } - - if (!local->eexist_count) { - shard_readv_do (frame, this); - } else { - local->call_count = local->eexist_count; - shard_common_lookup_shards (frame, this, local->loc.inode, - shard_post_lookup_shards_readv_handler); - } - return 0; -} - int shard_common_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, @@ -3267,6 +3247,7 @@ done: call_count = shard_call_count_return (frame); if (call_count == 0) { SHARD_UNSET_ROOT_FS_ID (frame, local); + local->create_count = 0; local->post_mknod_handler (frame, this); } @@ -3396,6 +3377,55 @@ err: return 0; } +int +shard_post_mknod_readv_handler (call_frame_t *frame, xlator_t *this); + +int +shard_post_lookup_shards_readv_handler (call_frame_t *frame, xlator_t *this) +{ + shard_local_t *local = NULL; + + local = frame->local; + + if (local->op_ret < 0) { + SHARD_STACK_UNWIND (readv, frame, local->op_ret, + local->op_errno, NULL, 0, NULL, NULL, NULL); + return 0; + } + + if (local->create_count) { + shard_common_resume_mknod (frame, this, + shard_post_mknod_readv_handler); + } else { + shard_readv_do (frame, this); + } + + return 0; +} + +int +shard_post_mknod_readv_handler (call_frame_t *frame, xlator_t *this) +{ + shard_local_t *local = NULL; + + local = frame->local; + + if (local->op_ret < 0) { + SHARD_STACK_UNWIND (readv, frame, local->op_ret, + local->op_errno, NULL, 0, NULL, NULL, NULL); + return 0; + } + + if (!local->eexist_count) { + shard_readv_do (frame, this); + } else { + local->call_count = local->eexist_count; + shard_common_lookup_shards (frame, this, local->loc.inode, + shard_post_lookup_shards_readv_handler); + } + return 0; +} + int shard_post_resolve_readv_handler (call_frame_t *frame, xlator_t *this) { @@ -3422,9 +3452,9 @@ shard_post_resolve_readv_handler (call_frame_t *frame, xlator_t *this) } if (local->call_count) { - local->create_count = local->call_count; - shard_common_resume_mknod (frame, this, - shard_post_mknod_readv_handler); + shard_common_lookup_shards (frame, this, + local->resolver_base_inode, + shard_post_lookup_shards_readv_handler); } else { shard_readv_do (frame, this); } @@ -3576,14 +3606,11 @@ shard_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, shard_lookup_base_file (frame, this, &local->loc, shard_post_lookup_readv_handler); - return 0; - err: SHARD_STACK_UNWIND (readv, frame, -1, ENOMEM, NULL, 0, NULL, NULL, NULL); return 0; - } int @@ -3875,6 +3902,10 @@ next: return 0; } +int +shard_common_inode_write_post_mknod_handler (call_frame_t *frame, + xlator_t *this); + int shard_common_inode_write_post_lookup_shards_handler (call_frame_t *frame, xlator_t *this) @@ -3890,7 +3921,12 @@ shard_common_inode_write_post_lookup_shards_handler (call_frame_t *frame, return 0; } - shard_common_inode_write_do (frame, this); + if (local->create_count) { + shard_common_resume_mknod (frame, this, + shard_common_inode_write_post_mknod_handler); + } else { + shard_common_inode_write_do (frame, this); + } return 0; } @@ -3938,11 +3974,13 @@ shard_common_inode_write_post_lookup_handler (call_frame_t *frame, local->postbuf = local->prebuf; - if (local->create_count) - shard_common_resume_mknod (frame, this, - shard_common_inode_write_post_mknod_handler); - else + if (local->call_count) { + shard_common_lookup_shards (frame, this, + local->resolver_base_inode, + shard_common_inode_write_post_lookup_shards_handler); + } else { shard_common_inode_write_do (frame, this); + } return 0; } @@ -3962,8 +4000,6 @@ shard_common_inode_write_post_resolve_handler (call_frame_t *frame, return 0; } - local->create_count = local->call_count; - shard_lookup_base_file (frame, this, &local->loc, shard_common_inode_write_post_lookup_handler); return 0; diff --git a/xlators/features/shard/src/shard.h b/xlators/features/shard/src/shard.h index 09232a45f24..73195983aa4 100644 --- a/xlators/features/shard/src/shard.h +++ b/xlators/features/shard/src/shard.h @@ -255,6 +255,7 @@ typedef struct shard_local { shard_lock_t *shard_lock; } lock; inode_t *resolver_base_inode; + gf_boolean_t first_lookup_done; } shard_local_t; typedef struct shard_inode_ctx { -- cgit From 104d07555719cd9c4d8e6b9477f6a3b1e1c14a38 Mon Sep 17 00:00:00 2001 From: Jiffin Tony Thottan Date: Mon, 10 Apr 2017 17:36:50 +0530 Subject: doc : release-notes for GlusterFS-3.8.11 BUG: 1431410 Change-Id: Iaf1d9603221bc0c70ad1695f5aa0afc2d651d737 Signed-off-by: Jiffin Tony Thottan Reviewed-on: https://review.gluster.org/17028 CentOS-regression: Gluster Build System Reviewed-by: Niels de Vos NetBSD-regression: NetBSD Build System Smoke: Gluster Build System --- doc/release-notes/3.8.11.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 doc/release-notes/3.8.11.md diff --git a/doc/release-notes/3.8.11.md b/doc/release-notes/3.8.11.md new file mode 100644 index 00000000000..1d368469906 --- /dev/null +++ b/doc/release-notes/3.8.11.md @@ -0,0 +1,26 @@ +# Release notes for Gluster 3.8.11 + +This is a bugfix release. The [Release Notes for 3.8.0](3.8.0.md), +[3.8.1](3.8.1.md), [3.8.2](3.8.2.md), [3.8.3](3.8.3.md), [3.8.4](3.8.4.md), +[3.8.5](3.8.5.md), [3.8.6](3.8.6.md), [3.8.7](3.8.7.md), [3.8.8](3.8.8.md), +[3.8.9](3.8.9.md) and [3.8.10](3.8.10.md) contain a listing of all the new +features that were added and bugs fixed in the GlusterFS 3.8 stable release. + + +## Bugs addressed + +A total of 15 patches have been merged, addressing 13 bugs: + +- [#1422788](https://bugzilla.redhat.com/1422788): [Replicate] "RPC call decoding failed" leading to IO hang & mount inaccessible +- [#1427390](https://bugzilla.redhat.com/1427390): systemic testing: seeing lot of ping time outs which would lead to splitbrains +- [#1430845](https://bugzilla.redhat.com/1430845): build/packaging: Debian and Ubuntu don't have /usr/libexec/; results in bad packages +- [#1431592](https://bugzilla.redhat.com/1431592): memory leak in features/locks xlator +- [#1434298](https://bugzilla.redhat.com/1434298): [Disperse] Metadata version is not healing when a brick is down +- [#1434302](https://bugzilla.redhat.com/1434302): Move spit-brain msg in read txn to debug +- [#1435645](https://bugzilla.redhat.com/1435645): Disperse: Provide description of disperse.eager-lock option. +- [#1436231](https://bugzilla.redhat.com/1436231): Undo pending xattrs only on the up bricks +- [#1436412](https://bugzilla.redhat.com/1436412): Unrecognized filesystems (i.e. btrfs, zfs) log many errors about "getinode size" +- [#1437330](https://bugzilla.redhat.com/1437330): Sharding: Fix a performance bug +- [#1438424](https://bugzilla.redhat.com/1438424): [Ganesha + EC] : Input/Output Error while creating LOTS of smallfiles +- [#1439112](https://bugzilla.redhat.com/1439112): File-level WORM allows ftruncate() on read-only files +- [#1440635](https://bugzilla.redhat.com/1440635): Application VMs with their disk images on sharded-replica 3 volume are unable to boot after performing rebalance -- cgit From 9c7a0aaf73993380c70570f99023b83064a85ddf Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Tue, 10 Jan 2017 00:30:42 -0500 Subject: geo-rep: Handle directory sync failure as hard error If directory creation is failed, return immediately before further processing. Allowing it to further process will fail the entire directory tree syncing to slave. Hence master will log and raise exception if it's directory failure. Earlier, master used to log the failure and proceed. > BUG: 1411607 > Signed-off-by: Kotresh HR > Reviewed-on: http://review.gluster.org/16364 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Aravinda VK Change-Id: Iba2a8b5d3d0092e7a9c8a3c2cdf9e6e29c73ddf0 BUG: 1441933 Signed-off-by: Kotresh HR Reviewed-on: https://review.gluster.org/17051 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Aravinda VK --- geo-replication/syncdaemon/master.py | 3 +++ geo-replication/syncdaemon/resource.py | 23 +++++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py index 6437dcc4295..f7667cf0cf6 100644 --- a/geo-replication/syncdaemon/master.py +++ b/geo-replication/syncdaemon/master.py @@ -783,6 +783,9 @@ class GMasterChangelogMixin(GMasterCommon): num_failures += 1 logging.error('%s FAILED: %s' % (log_prefix, repr(failure))) + if failure[0]['op'] == 'MKDIR': + raise GsyncdError("The above directory failed to sync." + " Please fix it to proceed further.") self.status.inc_value("failures", num_failures) diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py index ecb94d56c7f..2e607799c57 100644 --- a/geo-replication/syncdaemon/resource.py +++ b/geo-replication/syncdaemon/resource.py @@ -630,16 +630,19 @@ class Server(object): # We do this for failing fops on Slave # Master should be logging this if cmd_ret is None: - return + return False if cmd_ret == EEXIST: disk_gfid = cls.gfid_mnt(e['entry']) - if isinstance(disk_gfid, basestring): - if e['gfid'] != disk_gfid: - failures.append((e, cmd_ret, disk_gfid)) + if isinstance(disk_gfid, basestring) and e['gfid'] != disk_gfid: + failures.append((e, cmd_ret, disk_gfid)) + else: + return False else: failures.append((e, cmd_ret)) + return True + failures = [] def matching_disk_gfid(gfid, entry): @@ -809,7 +812,15 @@ class Server(object): [pg, 'glusterfs.gfid.newfile', blob], [EEXIST, ENOENT], [ESTALE, EINVAL]) - collect_failure(e, cmd_ret) + failed = collect_failure(e, cmd_ret) + + # If directory creation is failed, return immediately before + # further processing. Allowing it to further process will + # cause the entire directory tree to fail syncing to slave. + # Hence master will log and raise exception if it's + # directory failure. + if failed and op == 'MKDIR': + return failures # If UID/GID is different than zero that means we are trying # create Entry with different UID/GID. Create Entry with @@ -818,7 +829,7 @@ class Server(object): path = os.path.join(pfx, gfid) cmd_ret = errno_wrap(os.chown, [path, uid, gid], [ENOENT], [ESTALE, EINVAL]) - collect_failure(e, cmd_ret) + collect_failure(e, cmd_ret) return failures -- cgit From 4ec3b624eb265058e3d953e96c1cb2df31c90ebd Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Mon, 20 Mar 2017 05:21:59 -0400 Subject: geo-rep: Retry on EBUSY Do not crash on EBUSY error. Add EBUSY retry errno list. Crash only if the error persists even after max retries. > BUG: 1434018 > Signed-off-by: Kotresh HR > Reviewed-on: https://review.gluster.org/16924 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > Reviewed-by: Aravinda VK > CentOS-regression: Gluster Build System Change-Id: Ia067ccc6547731f28f2a315d400705e616cbf662 BUG: 1441930 Signed-off-by: Kotresh HR Reviewed-on: https://review.gluster.org/17052 Smoke: Gluster Build System CentOS-regression: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Aravinda VK --- geo-replication/syncdaemon/resource.py | 17 +++++++++-------- geo-replication/syncdaemon/syncdutils.py | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py index 2e607799c57..69644bc1e90 100644 --- a/geo-replication/syncdaemon/resource.py +++ b/geo-replication/syncdaemon/resource.py @@ -618,11 +618,12 @@ class Server(object): if not matching_disk_gfid(gfid, entry): return - er = errno_wrap(os.unlink, [entry], [ENOENT, ESTALE, EISDIR]) + er = errno_wrap(os.unlink, [entry], [ENOENT, ESTALE, EISDIR], + [EBUSY]) if isinstance(er, int): if er == EISDIR: er = errno_wrap(os.rmdir, [entry], [ENOENT, ESTALE, - ENOTEMPTY]) + ENOTEMPTY], [EBUSY]) if er == ENOTEMPTY: return er @@ -677,7 +678,7 @@ class Server(object): if not matching_disk_gfid(gfid, entry): return er = errno_wrap(os.remove, [fullname], [ENOENT, ESTALE, - EISDIR]) + EISDIR], [EBUSY]) if er == EISDIR: recursive_rmdir(gfid, entry, fullname) @@ -685,7 +686,7 @@ class Server(object): if not matching_disk_gfid(gfid, entry): return - errno_wrap(os.rmdir, [path], [ENOENT, ESTALE]) + errno_wrap(os.rmdir, [path], [ENOENT, ESTALE], [EBUSY]) def rename_with_disk_gfid_confirmation(gfid, entry, en): if not matching_disk_gfid(gfid, entry): @@ -698,7 +699,7 @@ class Server(object): cmd_ret = errno_wrap(os.rename, [entry, en], - [ENOENT, EEXIST], [ESTALE]) + [ENOENT, EEXIST], [ESTALE, EBUSY]) collect_failure(e, cmd_ret) @@ -788,12 +789,12 @@ class Server(object): # we have a hard link, we can now unlink source try: errno_wrap(os.unlink, [entry], - [ENOENT, ESTALE]) + [ENOENT, ESTALE], [EBUSY]) except OSError as e: if e.errno == EISDIR: try: errno_wrap(os.rmdir, [entry], - [ENOENT, ESTALE]) + [ENOENT, ESTALE], [EBUSY]) except OSError as e: if e.errno == ENOTEMPTY: logging.error( @@ -811,7 +812,7 @@ class Server(object): cmd_ret = errno_wrap(Xattr.lsetxattr, [pg, 'glusterfs.gfid.newfile', blob], [EEXIST, ENOENT], - [ESTALE, EINVAL]) + [ESTALE, EINVAL, EBUSY]) failed = collect_failure(e, cmd_ret) # If directory creation is failed, return immediately before diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py index 987e1bf186e..c2101c4e7e6 100644 --- a/geo-replication/syncdaemon/syncdutils.py +++ b/geo-replication/syncdaemon/syncdutils.py @@ -487,12 +487,12 @@ def errno_wrap(call, arg=[], errnos=[], retry_errnos=[]): # probably a screwed state, cannot do much... logging.warn('reached maximum retries (%s)...%s' % (repr(arg), ex)) - return ex.errno + raise time.sleep(0.250) # retry the call def lstat(e): - return errno_wrap(os.lstat, [e], [ENOENT], [ESTALE]) + return errno_wrap(os.lstat, [e], [ENOENT], [ESTALE, EBUSY]) class NoPurgeTimeAvailable(Exception): pass -- cgit From 649053cd4c5832fd0d3d9039cff9a1a839263408 Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Fri, 7 Apr 2017 05:33:34 -0400 Subject: geo-rep: Fix EBUSY traceback EBUSY was added to retry list of errno_wrap without importing. Fixing the same. > BUG: 1434018 > Signed-off-by: Kotresh HR > Reviewed-on: https://review.gluster.org/17011 > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Smoke: Gluster Build System > Reviewed-by: Aravinda VK Change-Id: Ide81a9ccc9b948a96265b6890da078b722b45d51 BUG: 1441930 Signed-off-by: Kotresh HR Reviewed-on: https://review.gluster.org/17053 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Aravinda VK --- geo-replication/syncdaemon/resource.py | 2 +- geo-replication/syncdaemon/syncdutils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py index 69644bc1e90..3e4be2b9cc9 100644 --- a/geo-replication/syncdaemon/resource.py +++ b/geo-replication/syncdaemon/resource.py @@ -24,7 +24,7 @@ import tempfile import threading import subprocess from errno import EEXIST, ENOENT, ENODATA, ENOTDIR, ELOOP -from errno import EISDIR, ENOTEMPTY, ESTALE, EINVAL +from errno import EISDIR, ENOTEMPTY, ESTALE, EINVAL, EBUSY from select import error as SelectError import shutil diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py index c2101c4e7e6..08450695a84 100644 --- a/geo-replication/syncdaemon/syncdutils.py +++ b/geo-replication/syncdaemon/syncdutils.py @@ -18,7 +18,7 @@ import logging import socket from threading import Lock, Thread as baseThread from errno import EACCES, EAGAIN, EPIPE, ENOTCONN, ECONNABORTED -from errno import EINTR, ENOENT, EPERM, ESTALE, errorcode +from errno import EINTR, ENOENT, EPERM, ESTALE, EBUSY, errorcode from signal import signal, SIGTERM import select as oselect from os import waitpid as owaitpid -- cgit From 05e42cdc0bdfa7a7e9e8e24fd2fc560033a99d6b Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Mon, 17 Apr 2017 08:39:30 -0400 Subject: glusterd: Fix snapshot failure in non-root geo-rep setup Geo-replication session directory name has the form '__'. But in non-root geo-replication setup, while preparing geo-replication session directory name, glusterd is including 'user@' resulting in "__". Hence snapshot is failing to copy geo-rep specific session files. Fixing the same. > BUG: 1442760 > Signed-off-by: Kotresh HR > Reviewed-on: https://review.gluster.org/17067 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > Reviewed-by: Amar Tumballi > CentOS-regression: Gluster Build System > Reviewed-by: Aravinda VK (cherry picked from commit cc839523364e47dea715cd7241772cd68f05f76c) Change-Id: Id214d3186e40997d2827a0bb60d3676ca2552df7 BUG: 1443012 Signed-off-by: Kotresh HR Reviewed-on: https://review.gluster.org/17071 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Atin Mukherjee CentOS-regression: Gluster Build System --- xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c index 36adb7fbfd8..49051182345 100644 --- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c @@ -3500,6 +3500,7 @@ glusterd_get_geo_rep_session (char *slave_key, char *origin_volname, char *slave) { int32_t ret = -1; + int32_t len = 0; char *token = NULL; char *tok = NULL; char *temp = NULL; @@ -3568,8 +3569,10 @@ glusterd_get_geo_rep_session (char *slave_key, char *origin_volname, * 'root@' */ ip_temp = gf_strdup (ip); tok = strtok_r (ip_temp, "@", &save_ptr); - if (tok && !strcmp (tok, "root")) - ip_i = ip + 5; + len = strlen(tok); + tok = strtok_r (NULL, "@", &save_ptr); + if (tok != NULL) + ip_i = ip + len + 1; ret = snprintf (session, PATH_MAX, "%s_%s_%s", origin_volname, ip_i, slave_temp); -- cgit From 57b481a071c13078c603cf2d96f9a04b9ebc39b4 Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Thu, 20 Apr 2017 07:18:52 -0400 Subject: glusterd/geo-rep: Fix snapshot create in geo-rep setup glusterd persists geo-rep sessions in glusterd info file which is represented by dictionary 'volinfo->gsync_slaves' in memory. Glusterd also maintains in memory active geo-rep sessions in dictionary 'volinfo->gsync_active_slaves' whose key is "::". When glusterd is restarted while the geo-rep sessions are active, it builds the 'volinfo->gsync_active_slaves' from persisted glusterd info file. Since slave volume uuid is added to "voinfo->gsync_slaves" with the commit "http://review.gluster.org/13111", it builds it with key ":::" which is wrong. So during snapshot pre-validation which checks whether geo-rep is active or not, it always says it is ACTIVE, as geo-rep stop would not deleted this key. Fixed the same in this patch. > BUG: 1443977 > Signed-off-by: Kotresh HR > Reviewed-on: https://review.gluster.org/17093 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Atin Mukherjee (cherry picked from commit f071d2a285ea4802fe8f328f9f275180983fbbba) Change-Id: I185178910b4b8a62e66aba406d88d12fabc5c122 BUG: 1445213 Signed-off-by: Kotresh HR Reviewed-on: https://review.gluster.org/17109 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Aravinda VK --- xlators/mgmt/glusterd/src/glusterd-utils.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 931683486ab..71956d55c06 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -5005,7 +5005,7 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data) glusterd_conf_t *priv = NULL; gf_boolean_t is_template_in_use = _gf_false; gf_boolean_t is_paused = _gf_false; - char *key1 = NULL; + char key1[1024] = {0,}; xlator_t *this1 = NULL; this1 = THIS; @@ -5100,9 +5100,8 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data) goto out; } - /* Move the pointer two characters ahead to surpass '//' */ - if ((key1 = strchr (slave, '/'))) - key1 = key1 + 2; + /* Form key1 which is "::" */ + snprintf (key1, sizeof (key1), "%s::%s", slave_url, slave_vol); /* Looks for the last status, to find if the session was running * when the node went down. If the session was just created or -- cgit From 767047377acee40f40237d2aca45cd94391cba37 Mon Sep 17 00:00:00 2001 From: Bipin Kunal Date: Mon, 27 Feb 2017 15:23:04 +0530 Subject: nfs: make subdir mounting work for Solaris 10 clients This fixes the segfault caused by solaris client in Gluster/NFS. Volname was not being parsed properly, Instead of volume name complete path was being used in nfs_mntpath_to_xlator(). Fixed it by striping volume name from complete path in nfs_mntpath_to_xlator(). Modified function name nfs3_funge_solaris_zerolen_fh() to nfs3_funge_webnfs_zerolen_fh() as zero-filled filehandle is specific to WebNFS. RFC : https://tools.ietf.org/html/rfc2055 Solaris uses WebNFS, the zero-filled FH is defined in the WebNFS spec. Logic was even added in fuction nfs3_funge_webnfs_zerolen_fh() to send subdir path in function glfs_resolve_at() instead of complete path for subdir mount. > Change-Id: I19aae3547b8910e7ed4974ee5385424cab3e834a > BUG: 1426667 > Signed-off-by: Bipin Kunal > Reviewed-on: https://review.gluster.org/16770 > Reviewed-by: Niels de Vos > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > (cherry picked from commit 40e571339b3c19ab2a5b6a93bc46eadf2252d006) Change-Id: I21ebb1d104b6eb914af5f26a6906f161c132179c BUG: 1440228 Signed-off-by: Bipin Kunal Reviewed-on: https://review.gluster.org/17017 CentOS-regression: Gluster Build System Reviewed-by: Niels de Vos NetBSD-regression: NetBSD Build System Smoke: Gluster Build System --- api/src/glfs-resolve.c | 6 ++- xlators/nfs/server/src/nfs-common.c | 18 +++++-- xlators/nfs/server/src/nfs3.c | 96 +++++++++++++++++++++++++++---------- 3 files changed, 89 insertions(+), 31 deletions(-) diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c index f8b437bab0e..d495cd21413 100644 --- a/api/src/glfs-resolve.c +++ b/api/src/glfs-resolve.c @@ -385,6 +385,9 @@ priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at, int ret = -1; struct iatt ciatt = {0, }; + DECLARE_OLD_THIS; + __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs); + path = gf_strdup (origpath); if (!path) { errno = ENOMEM; @@ -510,9 +513,10 @@ priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at, } out: GF_FREE (path); + __GLFS_EXIT_FS; /* do NOT loc_wipe here as only last component might be missing */ - +invalid_fs: return ret; } diff --git a/xlators/nfs/server/src/nfs-common.c b/xlators/nfs/server/src/nfs-common.c index af37f6b264c..526918872d7 100644 --- a/xlators/nfs/server/src/nfs-common.c +++ b/xlators/nfs/server/src/nfs-common.c @@ -73,10 +73,11 @@ nfs_xlator_to_xlid (xlator_list_t *cl, xlator_t *xl) xlator_t * nfs_mntpath_to_xlator (xlator_list_t *cl, char *path) { - char *volname = NULL; - char *volptr = NULL; - size_t pathlen; + char *volname = NULL; + char *volptr = NULL; + size_t pathlen = -1; xlator_t *targetxl = NULL; + int i = 0; if ((!cl) || (!path)) return NULL; @@ -89,10 +90,17 @@ nfs_mntpath_to_xlator (xlator_list_t *cl, char *path) else volptr = &volname[0]; - if (pathlen && volname[pathlen - 1] == '/') - volname[pathlen - 1] = '\0'; + for (i = 0; i < pathlen; i++) { + if (volname[i] == '/') { + volname[i] = '\0'; + break; + } + } while (cl) { + gf_msg_trace (GF_NFS, 0, "Volptr: %s and cl->xlator->name: %s", + volptr, cl->xlator->name); + if (strcmp (volptr, cl->xlator->name) == 0) { targetxl = cl->xlator; break; diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index 64287c5b1bd..8b1d62b46ac 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -28,6 +28,7 @@ #include "xdr-rpc.h" #include "xdr-generic.h" #include "nfs-messages.h" +#include "glfs-internal.h" #include #include @@ -348,28 +349,68 @@ out: } -#define nfs3_funge_solaris_zerolen_fh(nfs3st, fhd, enam, nfsst, erl) \ - do { \ - xlator_t *fungexl = NULL; \ - uuid_t zero = {0, }; \ - fungexl =nfs_mntpath_to_xlator ((nfs3st)->exportslist,enam);\ - if (!fungexl) { \ - (nfsst) = NFS3ERR_NOENT; \ - goto erl; \ - } \ - \ - gf_uuid_copy ((fhd)->gfid, zero); \ - (fhd)->gfid[15] = 1; \ - (enam) = NULL; \ - if ((gf_nfs_dvm_off (nfs_state (nfs3st->nfsx)))) \ - (fhd)->exportid[15] = nfs_xlator_to_xlid ((nfs3st)->exportslist, fungexl); \ - else { \ - if(__nfs3_get_volume_id ((nfs3st), fungexl, (fhd)->exportid) < 0) { \ - (nfsst) = NFS3ERR_STALE; \ - goto erl; \ - } \ - } \ - } while (0) \ +static enum nfsstat3 +nfs3_funge_webnfs_zerolen_fh (struct nfs3_state *nfs3st, struct nfs3_fh *fhd, + char *name) +{ + xlator_t *fungexl = NULL; + glfs_t *fs = NULL; + loc_t loc = { 0, }; + enum nfsstat3 nfsstat = NFS3ERR_SERVERFAULT; + int ret = -1; + size_t namelen = -1; + + fungexl = nfs_mntpath_to_xlator (nfs3st->exportslist, name); + if (!fungexl) { + nfsstat = NFS3ERR_NOENT; + goto out; + } + + /* glfs_resolve_at copied from UDP MNT support */ + fs = glfs_new_from_ctx (fungexl->ctx); + if (!fs) { + nfsstat = NFS3ERR_NOENT; + goto out; + } + + /* strip volname/ from 'name' */ + namelen = strlen(name); + while (namelen != 0) { + name++; + if (name[0] == '/') { + break; + } + namelen--; + } + gf_msg_debug (GF_NFS, 0, "NAME :%s ", name); + + ret = glfs_resolve_at (fs, fungexl, NULL, name, &loc, NULL, 1, 0); + if (ret != 0) { + nfsstat = NFS3ERR_NOENT; + goto out; + } + + /* resolved subdir, copy gfid for the fh */ + gf_uuid_copy (fhd->gfid, loc.gfid); + loc_wipe (&loc); + + if (gf_nfs_dvm_off (nfs_state (nfs3st->nfsx))) + fhd->exportid[15] = nfs_xlator_to_xlid (nfs3st->exportslist, + fungexl); + else { + if (__nfs3_get_volume_id (nfs3st, fungexl, fhd->exportid) < 0) { + nfsstat = NFS3ERR_STALE; + goto out; + } + } + + nfsstat = NFS3_OK; +out: + if (fs) + glfs_free_from_ctx (fs); + + return nfsstat; +} #define nfs3_volume_started_check(nf3stt, vlm, rtval, erlbl) \ @@ -1495,9 +1536,14 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name) nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "LOOKUP", fh, name); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); - if (nfs3_solaris_zerolen_fh (fh, fhlen)) - nfs3_funge_solaris_zerolen_fh (nfs3, fh, name, stat, nfs3err); - else + if (nfs3_solaris_zerolen_fh (fh, fhlen)) { + stat = nfs3_funge_webnfs_zerolen_fh (nfs3, fh, name); + if (stat != NFS3_OK) + goto nfs3err; + + /* this fh means we're doing a mount, name is no more useful */ + name = NULL; + } else nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); -- cgit From ddf3d4d3785bbd4f964e54ebc72fd445662f21a5 Mon Sep 17 00:00:00 2001 From: Shyam Date: Wed, 5 Apr 2017 14:22:57 -0400 Subject: scripts: Update rfc.sh to check existance of Change-Id in backports Addition to this script is a no-op on master. This would need to be backported to active release branches to be effective. This check is not smart proof, in that someone could proceed knowing that the Change-Id differs from master, but this is not expected to catch that, instead it is to serve more as a reminder that we need the same Change-Id across branches. Contributors not using rfc.sh would not see this, but they are few and possibly far in between. Also contributors using gerrit to cherry-pick changes will not see this. For both cases a server side solution to catch any changes are needed. There is a possiblilty that we will follow this up with a check on the gerrit end and add a comment to the reviews, to aid reviewers to quickly check the sanity of the Change-Id when it differs. > BUG: 1428047 > Signed-off-by: Shyam > Reviewed-on: https://review.gluster.org/17004 > Smoke: Gluster Build System > Reviewed-by: Niels de Vos > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Kaleb KEITHLEY > Reviewed-by: Amar Tumballi Change-Id: I11e371489a4a3cf2ff96d9892256986cd535998b BUG: 1440810 Signed-off-by: Shyam Reviewed-on: https://review.gluster.org/17031 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Kaleb KEITHLEY Reviewed-by: Niels de Vos --- rfc.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/rfc.sh b/rfc.sh index eb03843a173..998918ef04e 100755 --- a/rfc.sh +++ b/rfc.sh @@ -46,6 +46,72 @@ is_num() [ -z "$(echo $num | sed -e 's/[0-9]//g')" ] } +backport_id_message() +{ + echo "" + echo "This commit is to a non-master branch, and hence is treated as a backport." + echo "" + echo "For backports we would like to retain the same gerrit Change-Id across" + echo "branches. On auto inspection it is found that a gerrit Change-Id is" + echo "missing, or the Change-Id is not found on your local master" + echo "" + echo "This could mean a few things:" + echo " 1. This is not a backport, hence choose Y on the prompt to proceed" + echo " 2. Your origin master is not up to date, hence the script is unable" + echo " to find the corresponding Change-Id on master. Either choose N," + echo " 'git fetch', and try again, OR if you are sure you used the" + echo " same Change-Id, choose Y at the prompt to proceed" + echo " 3. You commented or removed the Change-Id in your commit message after" + echo " cherry picking the commit. Choose N, fix the commit message to" + echo " use the same Change-Id as master (git commit --amend), resubmit" + echo "" +} + +check_backport() +{ + moveon='N' + + # Backports are never made to master + if [ $branch = "master" ]; then + return; + fi + + # Extract the change ID from the commit message + changeid=$(git show --format='%b' | grep -i '^Change-Id: ' | awk '{print $2}') + + # If there is no change ID ask if we should continue + if [ -z "$changeid" ]; then + backport_id_message; + echo -n "Did not find a Change-Id for a possible backport. Continue (y/N): " + read moveon + else + # Search master for the same change ID (rebase_changes has run, so we + # should never not find a Change-Id) + mchangeid=$(git log origin/master --format='%b' --grep="^Change-Id: ${changeid}" | grep ${changeid} | awk '{print $2}') + + # Check if we found the change ID on master, else throw a message to + # decide if we should continue. + # NOTE: If master was not rebased, we will not find the Change-ID and + # could hit a false positive case here (or if someone checks out some + # other branch as master). + if [ $mchangeid = $changeid ]; then + moveon="Y" + else + backport_id_message; + echo "Change-Id of commit: $changeid" + echo "Change-Id on master: $mchangeid" + echo -n "Did not find mentioned Change-Id on master for a possible backport. Continue (y/N): " + read moveon + fi + fi + + if [ "${moveon}" = 'Y' ] || [ "${moveon}" = 'y' ]; then + return; + else + exit 1 + fi +} + rebase_changes() { @@ -139,6 +205,8 @@ main() { set_hooks_commit_msg; + # rfc.sh calls itself from rebase_changes, which uses rfc.sh as the EDITOR + # thus, getting the commit message to work with in the editor_mode. if [ -e "$1" ]; then editor_mode "$@"; return; @@ -148,6 +216,8 @@ main() rebase_changes; + check_backport; + assert_diverge; bug=$(git show --format='%b' | grep -i '^BUG: ' | awk '{print $2}'); -- cgit From a6d313d12c98cf533c6bbb10f491dd2ec48ca89c Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Wed, 19 Apr 2017 16:40:05 +0530 Subject: afr: don't do a post-op on a brick if op failed Problem: In afr-v2, self-blaming xattrs are not there by design. But if the FOP failed on a brick due to an error other than ENOTCONN (or even due to ENOTCONN, but we regained connection before postop was wound), we wind the post-op also on the failed brick, leading to setting self-blaming xattrs on that brick. This can lead to undesired results like healing of files in split-brain etc. Fix: If a fop failed on a brick on which pre-op was successful, do not perform post-op on it. This also produces the desired effect of not resetting the dirty xattr on the brick, which is how it should be because if the fop failed on a brick, there is no reason to clear the dirty bit which actually serves as an indication of the failure. > Reviewed-on: https://review.gluster.org/16976 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Pranith Kumar Karampuri Change-Id: I5f1caf4d1b39f36cf8093ccef940118638caa9c4 BUG: 1443319 Signed-off-by: Ravishankar N Reviewed-on: https://review.gluster.org/17082 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Pranith Kumar Karampuri --- .../bug-1438255-do-not-mark-self-accusing-xattrs.t | 46 ++++++++++++++++++++++ xlators/cluster/afr/src/afr-transaction.c | 12 +++++- 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 tests/bugs/replicate/bug-1438255-do-not-mark-self-accusing-xattrs.t diff --git a/tests/bugs/replicate/bug-1438255-do-not-mark-self-accusing-xattrs.t b/tests/bugs/replicate/bug-1438255-do-not-mark-self-accusing-xattrs.t new file mode 100644 index 00000000000..edfd0d7820d --- /dev/null +++ b/tests/bugs/replicate/bug-1438255-do-not-mark-self-accusing-xattrs.t @@ -0,0 +1,46 @@ +#!/bin/bash +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +cleanup; + +NEW_USER=bug1438255 +NEW_UID=1438255 +NEW_GID=1438255 + +TEST groupadd -o -g ${NEW_GID} ${NEW_USER}-${NEW_GID} +TEST useradd -o -M -u ${NEW_UID} -g ${NEW_GID} -K MAIL_DIR=/dev/null ${NEW_USER} + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2} +TEST $CLI volume set $V0 cluster.self-heal-daemon off +TEST $CLI volume set $V0 cluster.data-self-heal off +TEST $CLI volume set $V0 cluster.metadata-self-heal off +TEST $CLI volume set $V0 cluster.entry-self-heal off + +TEST $CLI volume start $V0 +EXPECT 'Started' volinfo_field $V0 'Status' +TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 + +TEST touch $M0/FILE +TEST kill_brick $V0 $H0 $B0/${V0}2 +chown $NEW_UID:$NEW_GID $M0/FILE +EXPECT "000000000000000100000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}0/FILE +EXPECT "000000000000000100000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1/FILE +TEST $CLI volume start $V0 force +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2 + +# setfattr done as NEW_USER fails on 3rd brick with EPERM but suceeds on +# the first 2 and hence on the mount. +su -m bug1438255 -c "setfattr -n user.myattr -v myvalue $M0/FILE" +TEST [ $? -eq 0 ] +EXPECT "000000000000000200000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}0/FILE +EXPECT "000000000000000200000000" get_hex_xattr trusted.afr.$V0-client-2 $B0/${V0}1/FILE +# Brick 3 does not have any self-blaming pending xattr. +TEST ! getfattr -n trusted.afr.$V0-client-2 $B0/${V0}2/FILE + +TEST userdel --force ${NEW_USER} +TEST groupdel ${NEW_USER}-${NEW_GID} +cleanup + + diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index 8178fc0d18b..83e25f3a122 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -588,11 +588,17 @@ afr_locked_nodes_get (afr_transaction_type type, afr_internal_lock_t *int_lock) int afr_changelog_call_count (afr_transaction_type type, unsigned char *pre_op_subvols, + unsigned char *failed_subvols, unsigned int child_count) { + int i = 0; int call_count = 0; - call_count = AFR_COUNT(pre_op_subvols, child_count); + for (i = 0; i < child_count; i++) { + if (pre_op_subvols[i] && !failed_subvols[i]) { + call_count++; + } + } if (type == AFR_ENTRY_RENAME_TRANSACTION) call_count *= 2; @@ -1244,6 +1250,7 @@ afr_changelog_do (call_frame_t *frame, xlator_t *this, dict_t *xattr, call_count = afr_changelog_call_count (local->transaction.type, local->transaction.pre_op, + local->transaction.failed_subvols, priv->child_count); if (call_count == 0) { @@ -1257,7 +1264,8 @@ afr_changelog_do (call_frame_t *frame, xlator_t *this, dict_t *xattr, local->transaction.changelog_resume = changelog_resume; for (i = 0; i < priv->child_count; i++) { - if (!local->transaction.pre_op[i]) + if (!local->transaction.pre_op[i] || + local->transaction.failed_subvols[i]) continue; switch (local->transaction.type) { -- cgit From ba17362ea9eb642614a69c4f8a6ea2c2648cb5d8 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Thu, 20 Apr 2017 10:08:02 +0530 Subject: cluster/dht: Pass the req dict instead of NULL in dht_attr2() Backport of: https://review.gluster.org/17085 This bug was causing VMs to pause during rebalance. When qemu winds down a STAT, shard fills the trusted.glusterfs.shard.file-size attribute in the req dict which DHT doesn't wind its STAT fop with upon detecting the file has undergone migration. As a result shard doesn't find the value to this key in the unwind path, causing it to fail the STAT with EINVAL. Also, the same bug exists in other fops too, which is also fixed in this patch. Change-Id: I56273b1a65347dabd38bc6bdd12d618f68287a00 BUG: 1440635 Signed-off-by: Krutika Dhananjay Reviewed-on: https://review.gluster.org/17121 Smoke: Gluster Build System Reviewed-by: Raghavendra G CentOS-regression: Gluster Build System NetBSD-regression: NetBSD Build System --- xlators/cluster/dht/src/dht-common.c | 61 +++++++++++++------------------ xlators/cluster/dht/src/dht-inode-read.c | 37 +++++++++++++------ xlators/cluster/dht/src/dht-inode-write.c | 33 ++++++++++++----- 3 files changed, 74 insertions(+), 57 deletions(-) diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index a50d6fe5628..a55922f0a74 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -3823,6 +3823,7 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, goto err; } + local->xattr_req = xdata ? dict_ref (xdata) : dict_new (); local->call_cnt = call_cnt = layout->cnt; if (IA_ISDIR (fd->inode->ia_type)) { @@ -3830,7 +3831,7 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, dht_err_cbk, layout->list[i].xlator, layout->list[i].xlator->fops->fsetxattr, - fd, xattr, flags, NULL); + fd, xattr, flags, xdata); } } else { @@ -3839,10 +3840,8 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, local->rebalance.xattr = dict_ref (xattr); local->rebalance.flags = flags; - xdata = xdata ? dict_ref (xdata) : dict_new (); - if (xdata) - ret = dict_set_dynstr_with_alloc (xdata, - DHT_IATT_IN_XDATA_KEY, "yes"); + ret = dict_set_dynstr_with_alloc (local->xattr_req, + DHT_IATT_IN_XDATA_KEY, "yes"); if (ret) { gf_msg_debug (this->name, 0, "Failed to set dictionary key %s for fd=%p", @@ -3850,11 +3849,8 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, } STACK_WIND (frame, dht_file_setxattr_cbk, subvol, - subvol->fops->fsetxattr, fd, xattr, flags, xdata); - - if (xdata) - dict_unref (xdata); - + subvol->fops->fsetxattr, fd, xattr, flags, + local->xattr_req); } return 0; @@ -3950,12 +3946,12 @@ dht_setxattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_file_setxattr_cbk, subvol, subvol->fops->setxattr, &local->loc, local->rebalance.xattr, local->rebalance.flags, - NULL); + local->xattr_req); } else { STACK_WIND (frame, dht_file_setxattr_cbk, subvol, subvol->fops->fsetxattr, local->fd, local->rebalance.xattr, local->rebalance.flags, - NULL); + local->xattr_req); } return 0; @@ -4239,6 +4235,7 @@ dht_setxattr (call_frame_t *frame, xlator_t *this, if (tmp) { return dht_nuke_dir (frame, this, loc, tmp); } + local->xattr_req = xdata ? dict_ref (xdata) : dict_new (); if (IA_ISDIR (loc->inode->ia_type)) { @@ -4255,17 +4252,12 @@ dht_setxattr (call_frame_t *frame, xlator_t *this, local->rebalance.flags = flags; local->call_cnt = 1; - xdata = xdata ? dict_ref (xdata) : dict_new (); - if (xdata) - ret = dict_set_dynstr_with_alloc (xdata, - DHT_IATT_IN_XDATA_KEY, "yes"); + ret = dict_set_dynstr_with_alloc (local->xattr_req, + DHT_IATT_IN_XDATA_KEY, "yes"); STACK_WIND (frame, dht_file_setxattr_cbk, subvol, subvol->fops->setxattr, - loc, xattr, flags, xdata); - - if (xdata) - dict_unref (xdata); + loc, xattr, flags, local->xattr_req); } return 0; @@ -4384,11 +4376,11 @@ dht_removexattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, if (local->fop == GF_FOP_REMOVEXATTR) { STACK_WIND (frame, dht_file_removexattr_cbk, subvol, subvol->fops->removexattr, &local->loc, - local->key, NULL); + local->key, local->xattr_req); } else { STACK_WIND (frame, dht_file_removexattr_cbk, subvol, subvol->fops->fremovexattr, local->fd, - local->key, NULL); + local->key, local->xattr_req); } return 0; @@ -4425,8 +4417,6 @@ dht_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unlock: UNLOCK (&frame->lock); - - this_call_cnt = dht_frame_return (frame); if (is_last_call (this_call_cnt)) { DHT_STACK_UNWIND (removexattr, frame, local->op_ret, @@ -4482,6 +4472,7 @@ dht_removexattr (call_frame_t *frame, xlator_t *this, op_errno = EINVAL; goto err; } + local->xattr_req = (xdata) ? dict_ref (xdata) : dict_new (); local->call_cnt = call_cnt = layout->cnt; local->key = gf_strdup (key); @@ -4491,16 +4482,15 @@ dht_removexattr (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, dht_removexattr_cbk, layout->list[i].xlator, layout->list[i].xlator->fops->removexattr, - loc, key, NULL); + loc, key, local->xattr_req); } } else { local->call_cnt = 1; - xdata = xdata ? dict_ref (xdata) : dict_new (); - if (xdata) - ret = dict_set_dynstr_with_alloc (xdata, - DHT_IATT_IN_XDATA_KEY, "yes"); + + ret = dict_set_dynstr_with_alloc (local->xattr_req, + DHT_IATT_IN_XDATA_KEY, "yes"); if (ret) { gf_msg (this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to " @@ -4510,10 +4500,7 @@ dht_removexattr (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, dht_file_removexattr_cbk, subvol, subvol->fops->removexattr, - loc, key, xdata); - - if (xdata) - dict_unref (xdata); + loc, key, local->xattr_req); } return 0; @@ -6511,7 +6498,7 @@ dht_link2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) local->call_cnt = 2; STACK_WIND (frame, dht_link_cbk, subvol, subvol->fops->link, - &local->loc, &local->loc2, NULL); + &local->loc, &local->loc2, local->xattr_req); return 0; err: @@ -6538,7 +6525,7 @@ dht_link_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this, srcvol = local->linkfile.srcvol; STACK_WIND (frame, dht_link_cbk, srcvol, srcvol->fops->link, - &local->loc, &local->loc2, xdata); + &local->loc, &local->loc2, local->xattr_req); return 0; @@ -6547,7 +6534,7 @@ err: dht_set_fixed_dir_stat (preparent); dht_set_fixed_dir_stat (postparent); DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf, preparent, - postparent, NULL); + postparent, xdata); return 0; } @@ -6598,6 +6585,8 @@ dht_link (call_frame_t *frame, xlator_t *this, op_errno = ENOMEM; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); if (hashed_subvol != cached_subvol) { gf_uuid_copy (local->gfid, oldloc->inode->gfid); diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c index 8abf0d59b88..298eca711b4 100644 --- a/xlators/cluster/dht/src/dht-inode-read.c +++ b/xlators/cluster/dht/src/dht-inode-read.c @@ -76,7 +76,7 @@ dht_open2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) if (we_are_not_migrating (ret)) { /* This DHT layer is not migrating the file */ DHT_STACK_UNWIND (open, frame, -1, local->op_errno, - NULL, NULL); + NULL, local->rebalance.xdata); return 0; } @@ -88,7 +88,7 @@ dht_open2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_open_cbk, subvol, subvol->fops->open, &local->loc, local->rebalance.flags, local->fd, - NULL); + local->xattr_req); return 0; out: @@ -122,6 +122,8 @@ dht_open (call_frame_t *frame, xlator_t *this, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->rebalance.flags = flags; local->call_cnt = 1; @@ -239,10 +241,10 @@ dht_attr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) if (local->fop == GF_FOP_FSTAT) { STACK_WIND (frame, dht_file_attr_cbk, subvol, - subvol->fops->fstat, local->fd, NULL); + subvol->fops->fstat, local->fd, local->xattr_req); } else { STACK_WIND (frame, dht_file_attr_cbk, subvol, - subvol->fops->stat, &local->loc, NULL); + subvol->fops->stat, &local->loc, local->xattr_req); } return 0; @@ -325,6 +327,8 @@ dht_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); if (IA_ISREG (loc->inode->ia_type)) { local->call_cnt = 1; @@ -385,6 +389,8 @@ dht_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); if (IA_ISREG (fd->inode->ia_type)) { local->call_cnt = 1; @@ -506,7 +512,7 @@ dht_readv2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_readv_cbk, subvol, subvol->fops->readv, local->fd, local->rebalance.size, local->rebalance.offset, - local->rebalance.flags, NULL); + local->rebalance.flags, local->xattr_req); return 0; @@ -541,6 +547,8 @@ dht_readv (call_frame_t *frame, xlator_t *this, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->rebalance.offset = off; local->rebalance.size = size; @@ -635,7 +643,7 @@ dht_access2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) local->call_cnt = 2; STACK_WIND (frame, dht_access_cbk, subvol, subvol->fops->access, - &local->loc, local->rebalance.flags, NULL); + &local->loc, local->rebalance.flags, local->xattr_req); return 0; @@ -674,6 +682,8 @@ dht_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_access_cbk, subvol, subvol->fops->access, loc, mask, xdata); @@ -708,9 +718,6 @@ dht_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->op_ret = op_ret; local->op_errno = op_errno; - if (xdata) - local->rebalance.xdata = dict_ref (xdata); - /* If context is set, then send flush() it to the destination */ dht_inode_ctx_get_mig_info (this, local->fd->inode, NULL, &subvol); if (subvol && dht_fd_open_on_dst (this, local->fd, subvol)) { @@ -751,7 +758,7 @@ dht_flush2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_flush_cbk, subvol, subvol->fops->flush, local->fd, - local->rebalance.xdata); + local->xattr_req); return 0; @@ -785,6 +792,8 @@ dht_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->call_cnt = 1; @@ -907,7 +916,7 @@ dht_fsync2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) local->call_cnt = 2; /* This is the second attempt */ STACK_WIND (frame, dht_fsync_cbk, subvol, subvol->fops->fsync, - local->fd, local->rebalance.flags, NULL); + local->fd, local->rebalance.flags, local->xattr_req); return 0; @@ -934,6 +943,8 @@ dht_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync, goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->call_cnt = 1; local->rebalance.flags = datasync; @@ -1024,7 +1035,7 @@ dht_lk2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_lk_cbk, subvol, subvol->fops->lk, local->fd, local->rebalance.lock_cmd, &local->rebalance.flock, - local->rebalance.xdata); + local->xattr_req); return 0; @@ -1059,6 +1070,8 @@ dht_lk (call_frame_t *frame, xlator_t *this, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); local->rebalance.flock = *flock; local->rebalance.lock_cmd = cmd; diff --git a/xlators/cluster/dht/src/dht-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c index 112685b659e..364b66c942e 100644 --- a/xlators/cluster/dht/src/dht-inode-write.c +++ b/xlators/cluster/dht/src/dht-inode-write.c @@ -143,7 +143,7 @@ dht_writev2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) subvol, subvol->fops->writev, local->fd, local->rebalance.vector, local->rebalance.count, local->rebalance.offset, local->rebalance.flags, - local->rebalance.iobref, NULL); + local->rebalance.iobref, local->xattr_req); return 0; @@ -180,7 +180,8 @@ dht_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, op_errno = EINVAL; goto err; } - + if (xdata) + local->xattr_req = dict_ref (xdata); local->rebalance.vector = iov_dup (vector, count); local->rebalance.offset = off; @@ -323,11 +324,11 @@ dht_truncate2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) if (local->fop == GF_FOP_TRUNCATE) { STACK_WIND (frame, dht_truncate_cbk, subvol, subvol->fops->truncate, &local->loc, - local->rebalance.offset, NULL); + local->rebalance.offset, local->xattr_req); } else { STACK_WIND (frame, dht_truncate_cbk, subvol, subvol->fops->ftruncate, local->fd, - local->rebalance.offset, NULL); + local->rebalance.offset, local->xattr_req); } return 0; @@ -366,6 +367,8 @@ dht_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_truncate_cbk, subvol, subvol->fops->truncate, @@ -407,6 +410,8 @@ dht_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_truncate_cbk, subvol, subvol->fops->ftruncate, @@ -533,7 +538,7 @@ dht_fallocate2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND(frame, dht_fallocate_cbk, subvol, subvol->fops->fallocate, local->fd, local->rebalance.flags, local->rebalance.offset, - local->rebalance.size, NULL); + local->rebalance.size, local->xattr_req); return 0; @@ -572,6 +577,8 @@ dht_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_fallocate_cbk, subvol, subvol->fops->fallocate, @@ -698,7 +705,7 @@ dht_discard2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND(frame, dht_discard_cbk, subvol, subvol->fops->discard, local->fd, local->rebalance.offset, local->rebalance.size, - NULL); + local->xattr_req); return 0; @@ -736,6 +743,8 @@ dht_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_discard_cbk, subvol, subvol->fops->discard, fd, offset, len, xdata); @@ -861,7 +870,7 @@ dht_zerofill2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND(frame, dht_zerofill_cbk, subvol, subvol->fops->zerofill, local->fd, local->rebalance.offset, local->rebalance.size, - NULL); + local->xattr_req); return 0; @@ -900,6 +909,8 @@ dht_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); STACK_WIND (frame, dht_zerofill_cbk, subvol, subvol->fops->zerofill, fd, offset, len, xdata); @@ -1004,12 +1015,12 @@ dht_setattr2 (xlator_t *this, xlator_t *subvol, call_frame_t *frame, int ret) STACK_WIND (frame, dht_file_setattr_cbk, subvol, subvol->fops->setattr, &local->loc, &local->rebalance.stbuf, local->rebalance.flags, - NULL); + local->xattr_req); } else { STACK_WIND (frame, dht_file_setattr_cbk, subvol, subvol->fops->fsetattr, local->fd, &local->rebalance.stbuf, local->rebalance.flags, - NULL); + local->xattr_req); } return 0; @@ -1102,6 +1113,8 @@ dht_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); if (IA_ISREG (loc->inode->ia_type)) { /* in the regular file _cbk(), we need to check for @@ -1173,6 +1186,8 @@ dht_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, op_errno = EINVAL; goto err; } + if (xdata) + local->xattr_req = dict_ref (xdata); if (IA_ISREG (fd->inode->ia_type)) { /* in the regular file _cbk(), we need to check for -- cgit From 6a5d9764e687b74b0686d492120584e88a6f8110 Mon Sep 17 00:00:00 2001 From: Saravanakumar Arumugam Date: Fri, 8 Jul 2016 19:10:45 +0530 Subject: geo-rep: filter out xtime attribute during getxattr georep gsyncd's xtime needs to filtered irrespective of any process access. This way, we can avoid (unnecessarily)syncing xtime attribute to slave, which may raise permission denied errors. test case modified to check for xtime xattr only in backend. Back port of> >Change-Id: I2390b703048d5cc747d91fa2ae884dc55de58669 >BUG: 1353952 >Signed-off-by: Saravanakumar Arumugam >Signed-off-by: Mohammed Rafi KC >Reviewed-on: https://review.gluster.org/14880 >Smoke: Gluster Build System >Reviewed-by: Kotresh HR >Tested-by: Kotresh HR >NetBSD-regression: NetBSD Build System >CentOS-regression: Gluster Build System >Reviewed-by: Pranith Kumar Karampuri Change-Id: Ibdee6f3093648a7e0fb1e2b6be8172e604ab657f BUG: 1441574 Signed-off-by: Mohammed Rafi KC Reviewed-on: https://review.gluster.org/17045 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Kotresh HR Reviewed-by: Niels de Vos --- tests/basic/geo-replication/marker-xattrs.t | 17 ++++----- tests/bugs/geo-replication/bug-1296496.t | 3 +- tests/bugs/geo-replication/bug-877293.t | 4 +-- xlators/storage/posix/src/posix-helpers.c | 53 ++++++++++++++++++++++++++++- xlators/storage/posix/src/posix.c | 15 ++++---- xlators/storage/posix/src/posix.h | 3 +- 6 files changed, 73 insertions(+), 22 deletions(-) diff --git a/tests/basic/geo-replication/marker-xattrs.t b/tests/basic/geo-replication/marker-xattrs.t index dd5483d7e95..e5b26a6bd5b 100755 --- a/tests/basic/geo-replication/marker-xattrs.t +++ b/tests/basic/geo-replication/marker-xattrs.t @@ -24,11 +24,11 @@ TEST touch $M0 vol_uuid=$(get_volume_mark $M1) xtime=trusted.glusterfs.$vol_uuid.xtime -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" TEST kill_brick $V0 $H0 $B0/${V0}-0 -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" TEST getfattr -d -m. -e hex $M1 EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 @@ -61,13 +61,13 @@ vol_uuid=$(get_volume_mark $M1) xtime=trusted.glusterfs.$vol_uuid.xtime stime=trusted.glusterfs.$vol_uuid.stime -stime_val=$(getfattr -e hex -n $xtime $M1 | grep ${xtime}= | cut -f2 -d'=') +stime_val=$(getfattr -e hex -n $xtime $B0/${V0}-1 | grep ${xtime}= | cut -f2 -d'=') TEST "setfattr -n $stime -v $stime_val $B0/${V0}-1" -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" TEST kill_brick $V0 $H0 $B0/${V0}-0 -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" TEST "getfattr -n $stime $M1 | grep -q ${stime}=" TEST getfattr -d -m. -e hex $M1 @@ -98,12 +98,9 @@ TEST touch $M0 vol_uuid=$(get_volume_mark $M1) xtime=trusted.glusterfs.$vol_uuid.xtime -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-0 | grep -q ${xtime}=" -TEST kill_brick $V0 $H0 $B0/${V0}-0 - -#Stripe doesn't tolerate ENOTCONN -TEST ! "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M1 diff --git a/tests/bugs/geo-replication/bug-1296496.t b/tests/bugs/geo-replication/bug-1296496.t index 703fda65b84..a157be7849a 100644 --- a/tests/bugs/geo-replication/bug-1296496.t +++ b/tests/bugs/geo-replication/bug-1296496.t @@ -29,7 +29,8 @@ xtime="trusted.glusterfs.$vol_uuid.xtime" #TEST xtime TEST ! getfattr -n $xtime $M0 -TEST getfattr -n $xtime $M1 +TEST getfattr -n $xtime $B0/${V0}-0 +TEST getfattr -n $xtime $B0/${V0}-1 #TEST stime slave_uuid=$(uuidgen) diff --git a/tests/bugs/geo-replication/bug-877293.t b/tests/bugs/geo-replication/bug-877293.t index 542774ab900..c5205e8109e 100755 --- a/tests/bugs/geo-replication/bug-877293.t +++ b/tests/bugs/geo-replication/bug-877293.t @@ -26,11 +26,11 @@ TEST touch $M0 vol_uuid=`getfattr -n trusted.glusterfs.volume-mark -ehex $M1 | sed -n 's/^trusted.glusterfs.volume-mark=0x//p' | cut -b5-36 | sed 's/\([a-f0-9]\{8\}\)\([a-f0-9]\{4\}\)\([a-f0-9]\{4\}\)\([a-f0-9]\{4\}\)/\1-\2-\3-\4-/'` xtime=trusted.glusterfs.$vol_uuid.xtime -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-0 | grep -q ${xtime}=" TEST kill_brick $V0 $H0 $B0/${V0}-0 -TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" +TEST "getfattr -n $xtime $B0/${V0}-1 | grep -q ${xtime}=" EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M1 diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index e7bd2cfd803..47c47dab07e 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -95,6 +95,57 @@ out: return flag; } +int +posix_handle_georep_xattrs (call_frame_t *frame, const char *name, + int *op_errno, gf_boolean_t is_getxattr) +{ + + int i = 0; + int ret = 0; + int pid = 1; + gf_boolean_t filter_xattr = _gf_true; + static const char *georep_xattr[] = { "*.glusterfs.*.stime", + "*.glusterfs.*.xtime", + "*.glusterfs.*.entry_stime", + NULL + }; + if (frame && frame->root) { + pid = frame->root->pid; + } + + if (!name) { + /* No need to do anything here */ + ret = 0; + goto out; + } + + if (pid == GF_CLIENT_PID_GSYNCD && is_getxattr) { + filter_xattr = _gf_false; + + /* getxattr from gsyncd process should return all the + * internal xattr. In other cases ignore such xattrs + */ + } + + for (i = 0; filter_xattr && georep_xattr[i]; i++) { + if (fnmatch (georep_xattr[i] , name, FNM_PERIOD) == 0) { + ret = -1; + if (op_errno) + *op_errno = ENOATTR; + + gf_msg_debug ("posix", ENOATTR, + "Ignoring the key %s as an internal " + "xattrs.", name); + goto out; + } + } + + ret = 0; +out: + return ret; +} + + static gf_boolean_t _is_in_array (char **str_array, char *str) { @@ -728,7 +779,7 @@ _handle_list_xattr (dict_t *xattr_req, const char *real_path, int fdnum, if (posix_special_xattr (marker_xattrs, key)) goto next; - if (!fnmatch (GF_XATTR_STIME_PATTERN, key, 0)) + if (posix_handle_georep_xattrs (NULL, key, NULL, _gf_false)) goto next; if (dict_get (filler->xattr, key)) diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 200a740a09c..503a6512130 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -4379,11 +4379,10 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, op_ret = -1; priv = this->private; - /* Allow access to stime xattr only to geo-rep worker */ - if (frame->root->pid != GF_CLIENT_PID_GSYNCD && name && - fnmatch ("*.glusterfs.*.stime", name, FNM_PERIOD) == 0) { + ret = posix_handle_georep_xattrs (frame, name, &op_errno, _gf_true); + if (ret == -1) { op_ret = -1; - op_errno = ENOATTR; + /* errno should be set from the above function*/ goto out; } @@ -4695,9 +4694,11 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, remaining_size = size; list_offset = 0; while (remaining_size > 0) { - strcpy (keybuffer, list + list_offset); - if (frame->root->pid != GF_CLIENT_PID_GSYNCD && - fnmatch ("*.glusterfs.*.stime", keybuffer, FNM_PERIOD) == 0) + strncpy (keybuffer, list + list_offset, sizeof(keybuffer)); + + ret = posix_handle_georep_xattrs (frame, keybuffer, NULL, + _gf_false); + if (ret == -1) goto ignore; size = sys_lgetxattr (real_path, keybuffer, NULL, 0); diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 4e43b1f2d32..febd4326aa1 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -275,7 +275,8 @@ int posix_get_ancestry (xlator_t *this, inode_t *leaf_inode, gf_dirent_t *head, char **path, int type, int32_t *op_errno, dict_t *xdata); - +int +posix_handle_georep_xattrs (call_frame_t *, const char *, int *, gf_boolean_t); void posix_gfid_unset (xlator_t *this, dict_t *xdata); -- cgit From 5dbe4fa649b8c486b2abdba660a53f7ae1198ef0 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Thu, 27 Apr 2017 11:53:24 +0530 Subject: cluster/dht: Pass the correct xdata in fremovexattr fop Backport of: https://review.gluster.org/17126 Change-Id: Id84bc87e48f435573eba3b24d3fb3c411fd2445d BUG: 1440635 Signed-off-by: Krutika Dhananjay Reviewed-on: https://review.gluster.org/17148 NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Smoke: Gluster Build System Reviewed-by: Niels de Vos --- xlators/cluster/dht/src/dht-common.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index a55922f0a74..c4586c2f9b1 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -4558,6 +4558,7 @@ dht_fremovexattr (call_frame_t *frame, xlator_t *this, op_errno = EINVAL; goto err; } + local->xattr_req = xdata ? dict_ref (xdata) : dict_new (); local->call_cnt = call_cnt = layout->cnt; local->key = gf_strdup (key); @@ -4567,29 +4568,23 @@ dht_fremovexattr (call_frame_t *frame, xlator_t *this, STACK_WIND (frame, dht_removexattr_cbk, layout->list[i].xlator, layout->list[i].xlator->fops->fremovexattr, - fd, key, NULL); + fd, key, local->xattr_req); } } else { local->call_cnt = 1; - xdata = xdata ? dict_ref (xdata) : dict_new (); - if (xdata) - ret = dict_set_dynstr_with_alloc (xdata, - DHT_IATT_IN_XDATA_KEY, "yes"); + ret = dict_set_dynstr_with_alloc (local->xattr_req, + DHT_IATT_IN_XDATA_KEY, "yes"); if (ret) { gf_msg (this->name, GF_LOG_ERROR, ENOMEM, DHT_MSG_DICT_SET_FAILED, "Failed to " "set dictionary key %s for fd=%p", DHT_IATT_IN_XDATA_KEY, fd); } - STACK_WIND (frame, dht_file_removexattr_cbk, subvol, subvol->fops->fremovexattr, - fd, key, xdata); - - if (xdata) - dict_unref (xdata); + fd, key, local->xattr_req); } return 0; -- cgit From 60a320c5167944027cc7f1d2da6b9ff27e45ec30 Mon Sep 17 00:00:00 2001 From: Xavier Hernandez Date: Wed, 5 Apr 2017 09:52:39 +0200 Subject: cluster/ec: fix incorrect answer check in seek fop A bad check in the answer of a seek request caused a segmentation fault when seek reported an error. > Change-Id: Ifb25ae8bf7cc4019d46171c431f7b09b376960e8 > BUG: 1439068 > Signed-off-by: Xavier Hernandez > Reviewed-on: https://review.gluster.org/16998 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Amar Tumballi > Reviewed-by: Pranith Kumar Karampuri Change-Id: Ifb25ae8bf7cc4019d46171c431f7b09b376960e8 BUG: 1442933 Signed-off-by: Xavier Hernandez Reviewed-on: https://review.gluster.org/17231 CentOS-regression: Gluster Build System Reviewed-by: Pranith Kumar Karampuri Smoke: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Niels de Vos --- xlators/cluster/ec/src/ec-inode-read.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c index c3d9c879eb7..fc121bcceb2 100644 --- a/xlators/cluster/ec/src/ec-inode-read.c +++ b/xlators/cluster/ec/src/ec-inode-read.c @@ -1577,23 +1577,16 @@ int32_t ec_manager_seek(ec_fop_data_t *fop, int32_t state) return EC_STATE_PREPARE_ANSWER; case EC_STATE_PREPARE_ANSWER: - cbk = fop->answer; - if (cbk != NULL) { - if (ec_dispatch_one_retry(fop, &cbk)) { - return EC_STATE_DISPATCH; - } - if (cbk->op_ret >= 0) { - ec_t *ec = fop->xl->private; + if (ec_dispatch_one_retry(fop, &cbk)) { + return EC_STATE_DISPATCH; + } + if ((cbk != NULL) && (cbk->op_ret >= 0)) { + ec_t *ec = fop->xl->private; - cbk->offset *= ec->fragments; - if (cbk->offset < fop->user_size) { - cbk->offset = fop->user_size; - } - } else { - ec_fop_set_error(fop, cbk->op_errno); + cbk->offset *= ec->fragments; + if (cbk->offset < fop->user_size) { + cbk->offset = fop->user_size; } - } else { - ec_fop_set_error(fop, EIO); } return EC_STATE_REPORT; -- cgit From ae2f6a650fab30a91357c3f3327a432a0edb5fdf Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Fri, 11 Apr 2014 15:58:47 +0530 Subject: performance/read-ahead: prevent stale data being returned to application. Assume that fd is shared by two application threads/processes. T0 read is triggered from app-thread t1 and read call passes through write-behind. T1 app-thread t2 issues a write. The page on which read from t1 is waiting is marked stale T2 write-behind caches write and indicates to application as write complete. T3 app-thread t2 issues read to same region. Since, there is already a page for that region (created as part of read at T0), this read request waits on that page to be filled (though it is stale, which is a bug). T4 read (triggered at T0) completes from brick (with write still pending). Now both read requests from t1 and t2 are served this data (though data is stale from app-thread t2's perspective - which is a bug) T5 write is flushed to brick by write-behind. Fix is to not to serve data from a stale page, but instead initiate a fresh read to back-end. >Change-Id: Id6af733464fa41bb4e81fd29c7451c73d06453fb >BUG: 1414242 >Signed-off-by: Raghavendra G >Reviewed-on: https://review.gluster.org/7447 >Smoke: Gluster Build System >CentOS-regression: Gluster Build System >Reviewed-by: Csaba Henk >NetBSD-regression: NetBSD Build System >Reviewed-by: Zhou Zhengping >Reviewed-by: Amar Tumballi (cherry picked from commit 2ff39c5cbea6fbda0d7a442f55e6dc2a72efb171) Change-Id: Id6af733464fa41bb4e81fd29c7451c73d06453fb BUG: 1449314 Signed-off-by: Raghavendra G Reviewed-on: https://review.gluster.org/17223 NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Niels de Vos Smoke: Gluster Build System --- xlators/performance/read-ahead/src/page.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/xlators/performance/read-ahead/src/page.c b/xlators/performance/read-ahead/src/page.c index 216e327af74..17e346ec947 100644 --- a/xlators/performance/read-ahead/src/page.c +++ b/xlators/performance/read-ahead/src/page.c @@ -139,6 +139,7 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this, ra_waitq_t *waitq = NULL; fd_t *fd = NULL; uint64_t tmp_file = 0; + gf_boolean_t stale = _gf_false; GF_ASSERT (frame); @@ -174,6 +175,13 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto unlock; } + if (page->stale) { + page->stale = 0; + page->ready = 0; + stale = 1; + goto unlock; + } + /* * "Dirty" means that the request was a pure read-ahead; it's * set for requests we issue ourselves, and cleared when user @@ -219,6 +227,16 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unlock: ra_file_unlock (file); + if (stale) { + STACK_WIND (frame, ra_fault_cbk, + FIRST_CHILD (frame->this), + FIRST_CHILD (frame->this)->fops->readv, + local->fd, local->pending_size, + local->pending_offset, 0, NULL); + + return 0; + } + ra_waitq_return (waitq); fd_unref (local->fd); -- cgit From f453425865d7151f27cd43c4c1e96919ec25a4f8 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Thu, 11 May 2017 12:00:10 +0200 Subject: doc: release-notes for GlusterFS-3.8.12 BUG: 1440754 Change-Id: I6602046ddc12834384e11c41a6e8e0cb7a8d5d71 Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/17252 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: jiffin tony Thottan CentOS-regression: Gluster Build System --- doc/release-notes/3.8.12.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 doc/release-notes/3.8.12.md diff --git a/doc/release-notes/3.8.12.md b/doc/release-notes/3.8.12.md new file mode 100644 index 00000000000..06ed30cc5de --- /dev/null +++ b/doc/release-notes/3.8.12.md @@ -0,0 +1,25 @@ +# Release notes for Gluster 3.8.12 + +This is a bugfix release. The [Release Notes for 3.8.0](3.8.0.md), +[3.8.1](3.8.1.md), [3.8.2](3.8.2.md), [3.8.3](3.8.3.md), [3.8.4](3.8.4.md), +[3.8.5](3.8.5.md), [3.8.6](3.8.6.md), [3.8.7](3.8.7.md), [3.8.8](3.8.8.md), +[3.8.9](3.8.9.md), [3.8.10](3.8.10.md) and [3.8.11](3.8.11.md) contain a +listing of all the new features that were added and bugs fixed in the GlusterFS +3.8 stable release. + + +## Bugs addressed + +A total of 13 patches have been merged, addressing 11 bugs: + +- [#1440228](https://bugzilla.redhat.com/1440228): NFS Sub-directory mount not working on solaris10 client +- [#1440635](https://bugzilla.redhat.com/1440635): Application VMs with their disk images on sharded-replica 3 volume are unable to boot after performing rebalance +- [#1440810](https://bugzilla.redhat.com/1440810): Update rfc.sh to check Change-Id consistency for backports +- [#1441574](https://bugzilla.redhat.com/1441574): [geo-rep]: rsync should not try to sync internal xattrs +- [#1441930](https://bugzilla.redhat.com/1441930): [geo-rep]: Worker crashes with [Errno 16] Device or resource busy: '.gfid/00000000-0000-0000-0000-000000000001/dir.166 while renaming directories +- [#1441933](https://bugzilla.redhat.com/1441933): [Geo-rep] If for some reason MKDIR failed to sync, it should not proceed further. +- [#1442933](https://bugzilla.redhat.com/1442933): Segmentation fault when creating a qcow2 with qemu-img +- [#1443012](https://bugzilla.redhat.com/1443012): snapshot: snapshots appear to be failing with respect to secure geo-rep slave +- [#1443319](https://bugzilla.redhat.com/1443319): Don't wind post-op on a brick where the fop phase failed. +- [#1445213](https://bugzilla.redhat.com/1445213): Unable to take snapshot on a geo-replicated volume, even after stopping the session +- [#1449314](https://bugzilla.redhat.com/1449314): [whql][virtio-block+glusterfs]"Disk Stress" and "Disk Verification" job always failed on win7-32/win2012/win2k8R2 guest -- cgit From f3022d7a0bc55be0aba3c6bc0fafcdcd96b936e5 Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Wed, 10 May 2017 10:03:08 +0530 Subject: afr: propagate correct errno for fop failures in arbiter Problem: If quorum is not met in fop cbk, arbiter sends an ENOTCONN error to the upper xlators. In a VM workload with sharding enabled, this was leading to the VM pausing when replace-brick was performed as described in the BZ. Fix: Move the fop cbk arbitration logic to afr_handle_quorum() because in normal replica volumes, that is the function that has the quorum and errno checks in the fop cbk path before doing a post-op. Thanks to Pranith for suggesting this approach. > Reviewed-on: https://review.gluster.org/17235 > Smoke: Gluster Build System > Reviewed-by: Pranith Kumar Karampuri > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System (cherry picked from commit 93c850dd2a513fab75408df9634ad3c970a0e859) Change-Id: Ie6315db30c5e36326b71b90a01da824109e86796 BUG: 1450937 Signed-off-by: Ravishankar N Reviewed-on: https://review.gluster.org/17296 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Pranith Kumar Karampuri Reviewed-by: jiffin tony Thottan --- xlators/cluster/afr/src/afr-dir-write.c | 1 - xlators/cluster/afr/src/afr-inode-write.c | 1 - xlators/cluster/afr/src/afr-transaction.c | 23 ++++++++++++----------- xlators/cluster/afr/src/afr-transaction.h | 2 -- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c index 8e483c382c4..9099b8c1eee 100644 --- a/xlators/cluster/afr/src/afr-dir-write.c +++ b/xlators/cluster/afr/src/afr-dir-write.c @@ -183,7 +183,6 @@ __afr_dir_write_finalize (call_frame_t *frame, xlator_t *this) } } - afr_txn_arbitrate_fop_cbk (frame, this); } diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c index ddc257dbde4..8c312a89e53 100644 --- a/xlators/cluster/afr/src/afr-inode-write.c +++ b/xlators/cluster/afr/src/afr-inode-write.c @@ -131,7 +131,6 @@ __afr_inode_write_finalize (call_frame_t *frame, xlator_t *this) } } - afr_txn_arbitrate_fop_cbk (frame, this); afr_set_in_flight_sb_status (this, local, local->inode); } diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index 83e25f3a122..9b5063d8aa8 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -301,22 +301,21 @@ afr_compute_pre_op_sources (call_frame_t *frame, xlator_t *this) } } -void -afr_txn_arbitrate_fop_cbk (call_frame_t *frame, xlator_t *this) +gf_boolean_t +afr_has_arbiter_fop_cbk_quorum (call_frame_t *frame) { afr_local_t *local = NULL; afr_private_t *priv = NULL; + xlator_t *this = NULL; gf_boolean_t fop_failed = _gf_false; unsigned char *pre_op_sources = NULL; int i = 0; local = frame->local; + this = frame->this; priv = this->private; pre_op_sources = local->transaction.pre_op_sources; - if (priv->arbiter_count != 1 || local->op_ret < 0) - return; - /* If the fop failed on the brick, it is not a source. */ for (i = 0; i < priv->child_count; i++) if (local->transaction.failed_subvols[i]) @@ -332,12 +331,10 @@ afr_txn_arbitrate_fop_cbk (call_frame_t *frame, xlator_t *this) break; } - if (fop_failed) { - local->op_ret = -1; - local->op_errno = ENOTCONN; - } + if (fop_failed) + return _gf_false; - return; + return _gf_true; } void @@ -785,8 +782,12 @@ afr_handle_quorum (call_frame_t *frame) * no split-brain with the fix. The problem is eliminated completely. */ - if (afr_has_fop_cbk_quorum (frame)) + if (priv->arbiter_count) { + if (afr_has_arbiter_fop_cbk_quorum (frame)) + return; + } else if (afr_has_fop_cbk_quorum (frame)) { return; + } for (i = 0; i < priv->child_count; i++) { if (local->transaction.pre_op[i]) diff --git a/xlators/cluster/afr/src/afr-transaction.h b/xlators/cluster/afr/src/afr-transaction.h index ca8fcfefa89..dcdadbc84f4 100644 --- a/xlators/cluster/afr/src/afr-transaction.h +++ b/xlators/cluster/afr/src/afr-transaction.h @@ -16,8 +16,6 @@ void afr_transaction_fop_failed (call_frame_t *frame, xlator_t *this, int child_index); -void -afr_txn_arbitrate_fop_cbk (call_frame_t *frame, xlator_t *this); int afr_lock_server_count (afr_private_t *priv, afr_transaction_type type); -- cgit From ae9af37538c38baa9a949f30400b945a85571f52 Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Tue, 9 May 2017 02:31:39 +0530 Subject: afr: send the correct iatt values in fsync cbk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: afr unwinds the fsync fop with an iatt buffer from one of its children on whom fsync was successful. But that child might not be a valid read subvolume for that inode because of pending heals or because it happens to be the arbiter brick etc. Thus we end up sending the wrong iatt to mdcache which will in turn serve it to the application on a subsequent stat call as reported in the BZ. Fix: Pick a child on whom the fsync was successful *and* that is readable as indicated in the inode context. > Reviewed-on: https://review.gluster.org/17227 > CentOS-regression: Gluster Build System > Reviewed-by: Pranith Kumar Karampuri > NetBSD-regression: NetBSD Build System > Smoke: Gluster Build System (cherry picked from commit 1a8fa910ccba7aa941f673302c1ddbd7bd818e39) Change-Id: Ie8647289219cebe02dde4727e19a729b3353ebcf BUG: 1449941 RCA'ed-by: Miklós Fokin Signed-off-by: Ravishankar N Reviewed-on: https://review.gluster.org/17248 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Pranith Kumar Karampuri CentOS-regression: Gluster Build System Reviewed-by: jiffin tony Thottan --- xlators/cluster/afr/src/afr-common.c | 68 +++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index c324c02c008..5ebe86bb368 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -3130,47 +3130,65 @@ afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct iatt *postbuf, dict_t *xdata) { afr_local_t *local = NULL; + afr_private_t *priv = NULL; + int i = 0; int call_count = -1; int child_index = (long) cookie; int read_subvol = 0; call_stub_t *stub = NULL; local = frame->local; - - read_subvol = afr_data_subvol_get (local->inode, this, NULL, NULL, - NULL, NULL); + priv = this->private; LOCK (&frame->lock); { + local->replies[child_index].valid = 1; + local->replies[child_index].op_ret = op_ret; + local->replies[child_index].op_errno = op_errno; if (op_ret == 0) { - if (local->op_ret == -1) { - local->op_ret = 0; - - local->cont.inode_wfop.prebuf = *prebuf; - local->cont.inode_wfop.postbuf = *postbuf; - - if (xdata) - local->xdata_rsp = dict_ref (xdata); - } - - if (child_index == read_subvol) { - local->cont.inode_wfop.prebuf = *prebuf; - local->cont.inode_wfop.postbuf = *postbuf; - if (xdata) { - if (local->xdata_rsp) - dict_unref (local->xdata_rsp); - local->xdata_rsp = dict_ref (xdata); - } - } - } else { - local->op_errno = op_errno; - } + if (prebuf) + local->replies[child_index].prestat = *prebuf; + if (postbuf) + local->replies[child_index].poststat = *postbuf; + if (xdata) + local->replies[child_index].xdata = + dict_ref (xdata); + } } UNLOCK (&frame->lock); call_count = afr_frame_return (frame); if (call_count == 0) { + local->op_ret = -1; + local->op_errno = afr_final_errno (local, priv); + read_subvol = afr_data_subvol_get (local->inode, this, NULL, + local->readable, NULL, NULL); + /* Pick a reply that is valid and readable, with a preference + * given to read_subvol. */ + for (i = 0; i < priv->child_count; i++) { + if (!local->replies[i].valid) + continue; + if (local->replies[i].op_ret != 0) + continue; + if (!local->readable[i]) + continue; + local->op_ret = local->replies[i].op_ret; + local->op_errno = local->replies[i].op_errno; + local->cont.inode_wfop.prebuf = + local->replies[i].prestat; + local->cont.inode_wfop.postbuf = + local->replies[i].poststat; + if (local->replies[i].xdata) { + if (local->xdata_rsp) + dict_unref (local->xdata_rsp); + local->xdata_rsp = + dict_ref (local->replies[i].xdata); + } + if (i == read_subvol) + break; + } + /* Make a stub out of the frame, and register it with the waking up post-op. When the call-stub resumes, we are guaranteed that there was no post-op pending -- cgit From 6c4255c701160d10f71c9be11983f309086165c7 Mon Sep 17 00:00:00 2001 From: "Kaleb S. KEITHLEY" Date: Thu, 11 May 2017 09:25:05 -0400 Subject: common-ha: adding a node to existing cluster failed to start pacemaker selected fixes back-ported from release-3.10 Change-Id: I44876305630a82e471824c085ed9ac58df08caa2 BUG: 1450055 Signed-off-by: Kaleb S. KEITHLEY Reviewed-on: https://review.gluster.org/17256 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System --- extras/ganesha/scripts/ganesha-ha.sh | 44 ++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh index 0692df8f5dd..4b9d8a3891a 100644 --- a/extras/ganesha/scripts/ganesha-ha.sh +++ b/extras/ganesha/scripts/ganesha-ha.sh @@ -161,25 +161,8 @@ determine_servers() } -setup_cluster() +start_cluster() { - local name=${1} - local num_servers=${2} - local servers=${3} - local unclean="" - local quorum_policy="stop" - - - logger "setting up cluster ${name} with the following ${servers}" - - pcs cluster auth ${servers} - # pcs cluster setup --name ${name} ${servers} - pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --transport udpu ${servers} - if [ $? -ne 0 ]; then - logger "pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} ${servers} failed" - exit 1; - fi - # BZ 1284404, 1425110, allow time for SSL certs to propagate, until then # pcsd will not accept connections. sleep 12 @@ -202,6 +185,29 @@ setup_cluster() unclean=$(pcs status | grep -u "UNCLEAN") done sleep 1 +} + + +setup_cluster() +{ + local name=${1} + local num_servers=${2} + local servers=${3} + local unclean="" + local quorum_policy="stop" + + + logger "setting up cluster ${name} with the following ${servers}" + + pcs cluster auth ${servers} + # pcs cluster setup --name ${name} ${servers} + pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --transport udpu ${servers} + if [ $? -ne 0 ]; then + logger "pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} ${servers} failed" + exit 1; + fi + + start_cluster if [ ${num_servers} -lt 3 ]; then quorum_policy="ignore" @@ -1047,7 +1053,7 @@ main() # from the entries in the ganesha-ha.conf file. Adding the # newly added node to the file so that the resources specfic # to this node is correctly recreated in the future. - clean_node=${node//[-.]/_} + clean_node=${node//[.]/_} echo "VIP_$clean_node=\"${vip}\"" >> ${HA_CONFDIR}/ganesha-ha.conf NEW_NODES="$HA_CLUSTER_NODES,${node}" -- cgit From f11ef6869d7fbe6ba91297ed814593b909da9c88 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Fri, 13 Jan 2017 16:05:02 +0100 Subject: nfs/nlm: unref rpc-client after nlm4svc_send_granted() nlm4svc_send_granted() uses the rpc_clnt by getting it from the call-state structure. It is safer to unref the rpc_clnt after the function is done with it. Cherry picked from commit 52c28c0c04722a9ffaa7c39c49ffebdf0a5c75e1: > Change-Id: I7cb7c4297801463d21259c58b50d7df7c57aec5e > BUG: 1381970 > Signed-off-by: Niels de Vos > Reviewed-on: https://review.gluster.org/17187 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: soumya k > Reviewed-by: Jeff Darcy Change-Id: I7cb7c4297801463d21259c58b50d7df7c57aec5e BUG: 1450380 Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/17274 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: jiffin tony Thottan Reviewed-by: Kaleb KEITHLEY --- xlators/nfs/server/src/nlm4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c index 3da3b2d1c05..1675116c461 100644 --- a/xlators/nfs/server/src/nlm4.c +++ b/xlators/nfs/server/src/nlm4.c @@ -934,8 +934,8 @@ nlm_rpcclnt_notify (struct rpc_clnt *rpc_clnt, void *mydata, "rpc clnt"); goto err; } - rpc_clnt_unref (rpc_clnt); nlm4svc_send_granted (cs); + rpc_clnt_unref (rpc_clnt); break; -- cgit From 9701e19fb6103b5c3d5ad38a1995c3f8f184e3a6 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Fri, 13 Jan 2017 14:02:45 +0100 Subject: nfs/nlm: ignore notify when there is no matching rpc request In certain (unclear) occasions it seems to happen that there are notifications sent to the Gluster/NFS NLM service, but no call-state can be found. Instead of segfaulting, log an error but keep on running. Cherry picked from commit e997d752ba08f80b1b00d2c0035874befafe5200: > Change-Id: I0f186e56e46a86ca40314d230c1cc7719c61f0b5 > BUG: 1381970 > Signed-off-by: Niels de Vos > Reviewed-on: https://review.gluster.org/17185 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: soumya k > Reviewed-by: jiffin tony Thottan > Reviewed-by: Jeff Darcy Change-Id: I0f186e56e46a86ca40314d230c1cc7719c61f0b5 BUG: 1450380 Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/17275 NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Smoke: Gluster Build System Reviewed-by: jiffin tony Thottan Reviewed-by: Kaleb KEITHLEY --- xlators/nfs/server/src/nlm4.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c index 1675116c461..0e4a4d824fa 100644 --- a/xlators/nfs/server/src/nlm4.c +++ b/xlators/nfs/server/src/nlm4.c @@ -923,10 +923,16 @@ nlm_rpcclnt_notify (struct rpc_clnt *rpc_clnt, void *mydata, nfs3_call_state_t *cs = NULL; cs = mydata; - caller_name = cs->args.nlm4_lockargs.alock.caller_name; switch (fn) { case RPC_CLNT_CONNECT: + if (!cs->req) { + gf_msg (GF_NLM, GF_LOG_ERROR, EINVAL, + NFS_MSG_RPC_CLNT_ERROR, "Spurious notify?!"); + goto err; + } + + caller_name = cs->args.nlm4_lockargs.alock.caller_name; ret = nlm_set_rpc_clnt (rpc_clnt, caller_name); if (ret == -1) { gf_msg (GF_NLM, GF_LOG_ERROR, 0, -- cgit From 6aaa4cd9a0eb75d791a47d88dd43fbea90285245 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Fri, 13 Jan 2017 14:46:17 +0100 Subject: nfs/nlm: log the caller_name if nlm_client_t can be found In order to help tracking possible misbehaving clients down, log the 'caller_name' (hostname of the NFS client) that does not have a matching nlm_client_t structure. Cherry picked from commit 9bfb74a39954a7e63bfd762c816efc7e64b9df65: > Change-Id: Ib514a78d1809719a3d0274acc31ee632727d746d > BUG: 1381970 > Signed-off-by: Niels de Vos > Reviewed-on: https://review.gluster.org/17186 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: soumya k > Reviewed-by: Jeff Darcy Change-Id: Ib514a78d1809719a3d0274acc31ee632727d746d BUG: 1450380 Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/17276 NetBSD-regression: NetBSD Build System Smoke: Gluster Build System Reviewed-by: jiffin tony Thottan Reviewed-by: Kaleb KEITHLEY CentOS-regression: Gluster Build System --- xlators/nfs/server/src/nlm4.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c index 0e4a4d824fa..903262eff54 100644 --- a/xlators/nfs/server/src/nlm4.c +++ b/xlators/nfs/server/src/nlm4.c @@ -1736,18 +1736,20 @@ nlm4_unlock_resume (void *carg) int ret = -1; nfs3_call_state_t *cs = NULL; nlm_client_t *nlmclnt = NULL; + char *caller_name = NULL; if (!carg) return ret; cs = (nfs3_call_state_t *)carg; nlm4_check_fh_resolve_status (cs, stat, nlm4err); + caller_name = cs->args.nlm4_unlockargs.alock.caller_name; - nlmclnt = nlm_get_uniq (cs->args.nlm4_unlockargs.alock.caller_name); + nlmclnt = nlm_get_uniq (caller_name); if (nlmclnt == NULL) { stat = nlm4_granted; gf_msg (GF_NLM, GF_LOG_WARNING, ENOLCK, NFS_MSG_NO_MEMORY, - "nlm_get_uniq() returned NULL"); + "nlm_get_uniq() returned NULL for %s", caller_name); goto nlm4err; } cs->fd = fd_lookup_uint64 (cs->resolvedloc.inode, (uint64_t)nlmclnt); -- cgit From cfa46e1774178d0af7cabc010d397d62fc0501a6 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Fri, 20 Jan 2017 14:15:31 +0100 Subject: nfs/nlm: free the nlm_client upon RPC_DISCONNECT When an NLM client disconnects, it should be removed from the list and free'd. > Cherry picked from commit 6897ba5c51b29c05b270c447adb1a34cb8e61911: > Change-Id: Ib427c896bfcdc547a3aee42a652578ffd076e2ad > BUG: 1381970 > Signed-off-by: Niels de Vos > Reviewed-on: https://review.gluster.org/17189 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > Reviewed-by: Kaleb KEITHLEY > CentOS-regression: Gluster Build System > Reviewed-by: jiffin tony Thottan Change-Id: Ib427c896bfcdc547a3aee42a652578ffd076e2ad BUG: 1450380 Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/17277 NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Smoke: Gluster Build System Reviewed-by: jiffin tony Thottan Reviewed-by: Kaleb KEITHLEY --- xlators/nfs/server/src/nlm4.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c index 903262eff54..cff9a3f5044 100644 --- a/xlators/nfs/server/src/nlm4.c +++ b/xlators/nfs/server/src/nlm4.c @@ -45,7 +45,7 @@ /* TODO: * 1) 2 opens racing .. creating an fd leak. - * 2) use mempool for nlmclnt - destroy if no fd exists, create during 1st call + * 2) use GF_REF_* for nlm_clnt_t */ typedef ssize_t (*nlm4_serializer) (struct iovec outmsg, void *args); @@ -333,6 +333,24 @@ ret: return rpc_clnt; } +static void +nlm_client_free (nlm_client_t *nlmclnt) +{ + list_del (&nlmclnt->fdes); + list_del (&nlmclnt->nlm_clients); + list_del (&nlmclnt->shares); + + GF_FREE (nlmclnt->caller_name); + + if (nlmclnt->rpc_clnt) { + /* cleanup the saved-frames before last unref */ + rpc_clnt_connection_cleanup (&nlmclnt->rpc_clnt->conn); + /* rpc_clnt_connection_cleanup() calls rpc_clnt_unref() */ + } + + GF_FREE (nlmclnt); +} + int nlm_set_rpc_clnt (rpc_clnt_t *rpc_clnt, char *caller_name) { @@ -375,26 +393,16 @@ int nlm_unset_rpc_clnt (rpc_clnt_t *rpc) { nlm_client_t *nlmclnt = NULL; - rpc_clnt_t *rpc_clnt = NULL; LOCK (&nlm_client_list_lk); list_for_each_entry (nlmclnt, &nlm_client_list, nlm_clients) { if (rpc == nlmclnt->rpc_clnt) { - rpc_clnt = nlmclnt->rpc_clnt; - nlmclnt->rpc_clnt = NULL; + nlm_client_free (nlmclnt); break; } } UNLOCK (&nlm_client_list_lk); - if (rpc_clnt == NULL) { - return -1; - } - if (rpc_clnt) { - /* cleanup the saved-frames before last unref */ - rpc_clnt_connection_cleanup (&rpc_clnt->conn); - rpc_clnt_unref (rpc_clnt); - } return 0; } -- cgit From 96ff4eab53814c483d8cf7b2dd4026b0f6576436 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Fri, 13 Jan 2017 13:02:23 +0100 Subject: nfs/nlm: remove lock request from the list after cancel Once an NLM client cancels a lock request, it should be removed from the list. The list can also be cleaned of unneeded entries once the client does not have any outstanding lock/share requests/granted. Cherry picked from commit 71cb7f3eb4fb706aab7f83906592942a2ff2e924: > Change-Id: I2f2b666b627dcb52cddc6d5b95856e420b2b2e26 > BUG: 1381970 > Signed-off-by: Niels de Vos > Reviewed-on: https://review.gluster.org/17188 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > Reviewed-by: Kaleb KEITHLEY > CentOS-regression: Gluster Build System > Reviewed-by: jiffin tony Thottan Change-Id: I2f2b666b627dcb52cddc6d5b95856e420b2b2e26 BUG: 1450380 Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/17278 NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Smoke: Gluster Build System Reviewed-by: jiffin tony Thottan Reviewed-by: Kaleb KEITHLEY --- xlators/nfs/server/src/nlm4.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c index cff9a3f5044..8580448b762 100644 --- a/xlators/nfs/server/src/nlm4.c +++ b/xlators/nfs/server/src/nlm4.c @@ -1213,7 +1213,7 @@ ret: } void -nlm_search_and_delete (fd_t *fd, char *caller_name) +nlm_search_and_delete (fd_t *fd, nlm4_lock *lk) { nlm_fde_t *fde = NULL; nlm_client_t *nlmclnt = NULL; @@ -1224,7 +1224,7 @@ nlm_search_and_delete (fd_t *fd, char *caller_name) LOCK (&nlm_client_list_lk); list_for_each_entry (nlmclnt, &nlm_client_list, nlm_clients) { - if (!strcmp(caller_name, nlmclnt->caller_name)) { + if (!strcmp (lk->caller_name, nlmclnt->caller_name)) { nlmclnt_found = 1; break; } @@ -1247,6 +1247,9 @@ nlm_search_and_delete (fd_t *fd, char *caller_name) goto ret; list_del (&fde->fde_list); + if (list_empty (&nlmclnt->fdes) && list_empty (&nlmclnt->shares)) + nlm_client_free (nlmclnt); + ret: UNLOCK (&nlm_client_list_lk); @@ -1362,7 +1365,8 @@ nlm4svc_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1) { if (transit_cnt == 0) - nlm_search_and_delete (cs->fd, caller_name); + nlm_search_and_delete (cs->fd, + &cs->args.nlm4_lockargs.alock); stat = nlm4_errno_to_nlm4stat (op_errno); goto err; } else { @@ -1553,8 +1557,10 @@ nlm4svc_cancel_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1) { stat = nlm4_errno_to_nlm4stat (op_errno); goto err; - } else + } else { stat = nlm4_granted; + nlm_search_and_delete (cs->fd, &cs->args.nlm4_lockargs.alock); + } err: nlm4_generic_reply (cs->req, cs->args.nlm4_cancargs.cookie, @@ -1707,7 +1713,7 @@ nlm4svc_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = nlm4_granted; if (flock->l_type == F_UNLCK) nlm_search_and_delete (cs->fd, - cs->args.nlm4_unlockargs.alock.caller_name); + &cs->args.nlm4_unlockargs.alock); } err: -- cgit From 5a48cf93a0383d79b6525268cee93158dbee8132 Mon Sep 17 00:00:00 2001 From: Soumya Koduri Date: Thu, 8 Jun 2017 22:19:17 +0530 Subject: posix-acl: Whitelist virtual ACL xattrs Similar to system.posix_acl_* xattrs, all users should get permission to be able to read glusterfs.posix.acl* xattrs too. This is backport of below mainline patch - https://review.gluster.org/17493 >BUG: 1459971 >Signed-off-by: Soumya Koduri >Reviewed-on: https://review.gluster.org/17493 >Smoke: Gluster Build System >Reviewed-by: jiffin tony Thottan >NetBSD-regression: NetBSD Build System >CentOS-regression: Gluster Build System >Reviewed-by: Raghavendra Talur >Reviewed-by: Niels de Vos >(cherry picked from commit 68f2192df570b5ee615d440c2e0c88d49a75a34f) BUG: 1460650 Change-Id: I1fc2b67c8a12113910e4ec57cd114e4baefe0d38 Signed-off-by: Soumya Koduri Reviewed-on: https://review.gluster.org/17514 Smoke: Gluster Build System CentOS-regression: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: jiffin tony Thottan --- xlators/system/posix-acl/src/posix-acl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c index 8a212020a5f..1c82e8b2239 100644 --- a/xlators/system/posix-acl/src/posix-acl.c +++ b/xlators/system/posix-acl/src/posix-acl.c @@ -62,6 +62,10 @@ whitelisted_xattr (const char *key) return 1; if (strcmp (POSIX_ACL_DEFAULT_XATTR, key) == 0) return 1; + if (strcmp (GF_POSIX_ACL_ACCESS, key) == 0) + return 1; + if (strcmp (GF_POSIX_ACL_DEFAULT, key) == 0) + return 1; return 0; } -- cgit From 5d13784dc6aa406f69061f2608a19ef0c8a80581 Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Mon, 5 Jun 2017 09:40:51 +0530 Subject: afr: add errno to afr_inode_refresh_done() Backport of https://review.gluster.org/17413 and https://review.gluster.org/17436 Problem: When parellel `rm -rf`s were being done from cifs clients, opendir might fail on some replicas with ENOENT. DHT ignores partial opendir failures in dht_fd_cbk() and winds readdirs on those replicas. Afr inode refresh (as a part of readdirp read_txn) sees in its fd context that the state of the fds is *not* AFR_FD_OPENED and bails out to afr_inode_refresh_done() without doing a refresh. When this happens, the errno is set as EIO due to lack of readable subvols, logging split-brain messages in the logs. Fix: Introduce an errno argument to afr_inode_refresh_do() to bail out with the right error value when inode refresh is not performed. Change-Id: I8eed4d6e6c85332c1f5813c74cb54ae73693a369 BUG: 1460661 Signed-off-by: Ravishankar N Reviewed-on: https://review.gluster.org/17518 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Pranith Kumar Karampuri --- xlators/cluster/afr/src/afr-common.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 5ebe86bb368..7532b014ff7 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -1076,7 +1076,7 @@ refresh_done: } int -afr_inode_refresh_done (call_frame_t *frame, xlator_t *this) +afr_inode_refresh_done (call_frame_t *frame, xlator_t *this, int error) { call_frame_t *heal_frame = NULL; afr_local_t *local = NULL; @@ -1086,6 +1086,11 @@ afr_inode_refresh_done (call_frame_t *frame, xlator_t *this) int ret = 0; int err = 0; + if (error != 0) { + err = error; + goto refresh_done; + } + local = frame->local; ret = afr_replies_interpret (frame, this, local->refreshinode, @@ -1149,7 +1154,7 @@ afr_inode_refresh_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this, call_count = afr_frame_return (frame); if (call_count == 0) { afr_set_need_heal (this, local); - afr_inode_refresh_done (frame, this); + afr_inode_refresh_done (frame, this, 0); } } @@ -1240,20 +1245,21 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this) if (local->fd) { fd_ctx = afr_fd_ctx_get (local->fd, this); if (!fd_ctx) { - afr_inode_refresh_done (frame, this); + afr_inode_refresh_done (frame, this, EINVAL); return 0; } } xdata = dict_new (); if (!xdata) { - afr_inode_refresh_done (frame, this); + afr_inode_refresh_done (frame, this, ENOMEM); return 0; } - if (afr_xattr_req_prepare (this, xdata) != 0) { + ret = afr_xattr_req_prepare (this, xdata); + if (ret != 0) { dict_unref (xdata); - afr_inode_refresh_done (frame, this); + afr_inode_refresh_done (frame, this, -ret); return 0; } @@ -1286,7 +1292,10 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this) call_count = local->call_count; if (!call_count) { dict_unref (xdata); - afr_inode_refresh_done (frame, this); + if (local->fd && AFR_COUNT(local->child_up, priv->child_count)) + afr_inode_refresh_done (frame, this, EBADFD); + else + afr_inode_refresh_done (frame, this, ENOTCONN); return 0; } for (i = 0; i < priv->child_count; i++) { -- cgit From 2dcb19813e7dbb2afd2f482ed9a3401371325b1d Mon Sep 17 00:00:00 2001 From: Sanoj Unnikrishnan Date: Wed, 22 Mar 2017 15:02:12 +0530 Subject: Fixes quota aux mount failure The aux mount is created on the first limit/remove_limit/list command and it remains until volume is stopped / deleted / (quota is disabled) , where we do a lazy unmount. If the process is uncleanly terminated, then the mount entry remains and we get (Transport disconnected) error on subsequent attempts to run quota list/limit-usage/remove commands. Second issue, There is also a risk of inadvertent rm -rf on the /var/run/gluster causing data loss for the user. Ideally, /var/run is a temp path for application use and should not cause any data loss to persistent storage. Solution: 1) unmount the aux mount after each use. 2) clean stale mount before mounting, if any. One caveat with doing mount/unmount on each command is that we cannot use same mount point for both list and limit commands. The reason for this is that list command needs mount to be accessible in cli after response from glusterd, So it could be unmounted by a limit command if executed in parallel (had we used same mount point) Hence we use separate mount points for list and limit commands. > Reviewed-on: https://review.gluster.org/16938 > NetBSD-regression: NetBSD Build System > Smoke: Gluster Build System > Reviewed-by: Manikandan Selvaganesh > CentOS-regression: Gluster Build System > Reviewed-by: Raghavendra G > Reviewed-by: Atin Mukherjee > (cherry picked from commit 2ae4b4058691b324535d802f4e6d24cce89a10e5) Change-Id: I4f9e39da2ac2b65941399bffb6440db8a6ba59d0 BUG: 1449782 Signed-off-by: Sanoj Unnikrishnan Reviewed-on: https://review.gluster.org/17242 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Raghavendra G --- cli/src/cli-rpc-ops.c | 29 +++++++++++- cli/src/cli.h | 7 +-- tests/basic/ec/quota.t | 1 - tests/basic/quota-ancestry-building.t | 1 - tests/basic/quota-anon-fd-nfs.t | 1 - tests/basic/quota-nfs.t | 1 - tests/basic/quota.t | 6 --- tests/basic/quota_aux_mount.t | 53 ++++++++++++++++++++++ tests/bugs/cli/bug-1022905.t | 1 - tests/bugs/distribute/bug-1099890.t | 1 - tests/bugs/distribute/bug-1161156.t | 1 - ...ve-quota-related-option-after-disabling-quota.t | 1 - tests/bugs/glusterfs/bug-848251.t | 1 - tests/bugs/posix/bug-990028.t | 1 - tests/bugs/quota/bug-1087198.t | 1 - ...436-calculate-quota-cksum-during-snap-restore.t | 1 - tests/volume.rc | 19 +++++++- xlators/mgmt/glusterd/src/glusterd-quota.c | 49 +++++++++++--------- xlators/mgmt/glusterd/src/glusterd-utils.c | 11 +---- xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 24 ---------- xlators/mgmt/glusterd/src/glusterd.h | 24 ++++++++-- 21 files changed, 151 insertions(+), 83 deletions(-) create mode 100755 tests/basic/quota_aux_mount.t diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 602d3ff1611..07a63364ebe 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -3399,6 +3399,26 @@ out: return ret; } +int +gluster_remove_auxiliary_mount (char *volname) +{ + int ret = -1; + char mountdir[PATH_MAX] = {0,}; + xlator_t *this = NULL; + + this = THIS; + GF_ASSERT (this); + + GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH (mountdir, volname, "/"); + ret = gf_umount_lazy (this->name, mountdir, 1); + if (ret) { + gf_log("cli", GF_LOG_ERROR, "umount on %s failed, " + "reason : %s", mountdir, strerror (errno)); + } + + return ret; +} + int gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname, dict_t *dict, char *default_sl, int count, @@ -3447,7 +3467,7 @@ gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname, ret = gf_canonicalize_path (path); if (ret) goto out; - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, path); + GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH (mountdir, volname, path); ret = print_quota_list_from_mountdir (local, mountdir, default_sl, path, type); } @@ -3930,6 +3950,7 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov, } xml_output: + if (global_state->mode & GLUSTER_MODE_XML) { ret = cli_xml_output_str ("volQuota", NULL, rsp.op_ret, rsp.op_errno, rsp.op_errstr); @@ -3945,6 +3966,12 @@ xml_output: ret = rsp.op_ret; out: + + if ((type == GF_QUOTA_OPTION_TYPE_LIST) + || (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)) { + gluster_remove_auxiliary_mount (volname); + } + cli_cmd_broadcast_response (ret); if (dict) dict_unref (dict); diff --git a/cli/src/cli.h b/cli/src/cli.h index 8acec640c83..b59e254d44f 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -62,9 +62,10 @@ typedef enum { #define GLUSTER_MODE_WIGNORE (1 << 3) -#define GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH(abspath, volname, path) \ - snprintf (abspath, sizeof (abspath)-1, \ - DEFAULT_VAR_RUN_DIRECTORY"/%s%s", volname, path); +#define GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH(abspath, volname, path) do { \ + snprintf (abspath, sizeof (abspath)-1, \ + DEFAULT_VAR_RUN_DIRECTORY"/%s_quota_list%s", volname, path);\ + } while (0) struct cli_state; struct cli_cmd_word; diff --git a/tests/basic/ec/quota.t b/tests/basic/ec/quota.t index b023240b87e..c9612c8b76a 100755 --- a/tests/basic/ec/quota.t +++ b/tests/basic/ec/quota.t @@ -40,7 +40,6 @@ EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "8.0MB" quotausage "/test" TEST rm $M0/test/file2.txt EXPECT_WITHIN $MARKER_UPDATE_TIMEOUT "0Bytes" quotausage "/test" TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD cleanup; diff --git a/tests/basic/quota-ancestry-building.t b/tests/basic/quota-ancestry-building.t index 99c971859e8..5d2f4a7dd66 100755 --- a/tests/basic/quota-ancestry-building.t +++ b/tests/basic/quota-ancestry-building.t @@ -65,7 +65,6 @@ exec 5>&- exec 6>&- TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD cleanup; diff --git a/tests/basic/quota-anon-fd-nfs.t b/tests/basic/quota-anon-fd-nfs.t index c6b01553b02..d911cc90b87 100755 --- a/tests/basic/quota-anon-fd-nfs.t +++ b/tests/basic/quota-anon-fd-nfs.t @@ -98,7 +98,6 @@ $CLI volume statedump $V0 all EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $N0 TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD diff --git a/tests/basic/quota-nfs.t b/tests/basic/quota-nfs.t index 74fde400bd1..663a8da90ad 100755 --- a/tests/basic/quota-nfs.t +++ b/tests/basic/quota-nfs.t @@ -58,7 +58,6 @@ TEST rm -f $N0/$deep/newfile_2 EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" umount_nfs $N0 TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD cleanup; diff --git a/tests/basic/quota.t b/tests/basic/quota.t index 17d571060e1..7f8b21de6f8 100755 --- a/tests/basic/quota.t +++ b/tests/basic/quota.t @@ -40,12 +40,8 @@ EXPECT 'on' volinfo_field $V0 'features.quota' EXPECT 'on' volinfo_field $V0 'features.inode-quota' EXPECT 'on' volinfo_field $V0 'features.quota-deem-statfs' -#Wait for the auxiliarymount to come up -sleep 3 TEST $CLI volume quota $V0 limit-usage /test_dir 100MB -# Checking for auxiliary mount -EXPECT "0" get_aux TEST $CLI volume quota $V0 limit-usage /test_dir/in_test_dir 150MB @@ -231,9 +227,7 @@ EXPECT 'off' volinfo_field $V0 'features.quota' EXPECT 'off' volinfo_field $V0 'features.inode-quota' EXPECT '' volinfo_field $V0 'features.quota-deem-statfs' -# aux mount should be removed TEST $CLI volume stop $V0; -EXPECT "1" get_aux rm -f $QDD cleanup; diff --git a/tests/basic/quota_aux_mount.t b/tests/basic/quota_aux_mount.t new file mode 100755 index 00000000000..78d7f47e373 --- /dev/null +++ b/tests/basic/quota_aux_mount.t @@ -0,0 +1,53 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +##------------------------------------------------------------- +## Tests to verify that aux mount is unmounted after each quota +## command executes. +##------------------------------------------------------------- + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2,3,4}; + +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT '4' brick_count $V0 + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +TEST $GFS -s $H0 --volfile-id $V0 $M0; + +TEST mkdir -p $M0/test_dir/ + +TEST $CLI volume quota $V0 enable +EXPECT 'on' volinfo_field $V0 'features.quota' +EXPECT 'on' volinfo_field $V0 'features.inode-quota' + +TEST $CLI volume quota $V0 limit-usage /test_dir 150MB +EXPECT "1" get_limit_aux +TEST $CLI volume quota $V0 limit-objects /test_dir 10 +EXPECT "1" get_limit_aux +EXPECT "150.0MB" quota_hard_limit "/test_dir"; +EXPECT "1" get_list_aux +EXPECT "10" quota_object_hard_limit "/test_dir"; +EXPECT "1" get_list_aux + +TEST $CLI volume quota $V0 remove /test_dir/ +EXPECT "1" get_limit_aux +TEST $CLI volume quota $V0 remove-objects /test_dir +EXPECT "1" get_limit_aux + +TEST $CLI volume quota $V0 disable + +TEST $CLI volume stop $V0; + +cleanup; +#G_TESTDEF_TEST_STATUS_NETBSD7=BAD_TEST,BUG=1447344 diff --git a/tests/bugs/cli/bug-1022905.t b/tests/bugs/cli/bug-1022905.t index 1d8981e0e9c..ee629e970d9 100644 --- a/tests/bugs/cli/bug-1022905.t +++ b/tests/bugs/cli/bug-1022905.t @@ -32,7 +32,6 @@ TEST $CLI volume set $V0 diagnostics.client-log-level DEBUG TEST $CLI volume reset $V0 force; TEST $CLI volume stop $V0 -EXPECT "1" get_aux TEST $CLI volume delete $V0 cleanup; diff --git a/tests/bugs/distribute/bug-1099890.t b/tests/bugs/distribute/bug-1099890.t index 40f70d4938b..1a19ba880c0 100644 --- a/tests/bugs/distribute/bug-1099890.t +++ b/tests/bugs/distribute/bug-1099890.t @@ -123,7 +123,6 @@ EXPECT "1" is_dht_linkfile "$B0/${V0}1/zz" force_umount $M0 TEST $CLI volume stop $V0 -EXPECT "1" get_aux UMOUNT_LOOP ${B0}/${V0}{1,2} rm -f ${B0}/brick{1,2} diff --git a/tests/bugs/distribute/bug-1161156.t b/tests/bugs/distribute/bug-1161156.t index 44a234c60dc..fed90e7f478 100755 --- a/tests/bugs/distribute/bug-1161156.t +++ b/tests/bugs/distribute/bug-1161156.t @@ -50,7 +50,6 @@ TEST ! mv $N0/dir/newfile_3 $N0/newdir/ umount_nfs $N0 TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD diff --git a/tests/bugs/glusterd/bug-765230-remove-quota-related-option-after-disabling-quota.t b/tests/bugs/glusterd/bug-765230-remove-quota-related-option-after-disabling-quota.t index 9fe55a3d9df..de48c091c7e 100755 --- a/tests/bugs/glusterd/bug-765230-remove-quota-related-option-after-disabling-quota.t +++ b/tests/bugs/glusterd/bug-765230-remove-quota-related-option-after-disabling-quota.t @@ -54,7 +54,6 @@ EXPECT '' volinfo_field $V0 'features.quota-deem-statfs' ## Finish up TEST $CLI volume stop $V0 -EXPECT "1" get_aux EXPECT 'Stopped' volinfo_field $V0 'Status'; TEST $CLI volume delete $V0; diff --git a/tests/bugs/glusterfs/bug-848251.t b/tests/bugs/glusterfs/bug-848251.t index ed3caa34b01..69ffe680f7f 100644 --- a/tests/bugs/glusterfs/bug-848251.t +++ b/tests/bugs/glusterfs/bug-848251.t @@ -48,6 +48,5 @@ EXPECT "80%" quota_list EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $MOUNTDIR TEST rm -rf $MOUNTDIR TEST $CLI volume stop $V0 -EXPECT "1" get_aux cleanup; diff --git a/tests/bugs/posix/bug-990028.t b/tests/bugs/posix/bug-990028.t index d04bb2b4af1..c86421492cd 100755 --- a/tests/bugs/posix/bug-990028.t +++ b/tests/bugs/posix/bug-990028.t @@ -153,6 +153,5 @@ __init; links_in_same_directory; links_across_directories; TEST $CLI volume stop $V0 -EXPECT "1" get_aux cleanup diff --git a/tests/bugs/quota/bug-1087198.t b/tests/bugs/quota/bug-1087198.t index 0694b251d9f..95133085f13 100644 --- a/tests/bugs/quota/bug-1087198.t +++ b/tests/bugs/quota/bug-1087198.t @@ -78,7 +78,6 @@ TEST grep -e "\"Usage is above soft limit:.*used by /\"" -- $BRICK_LOG_DIR/* EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $N0 TEST $CLI volume stop $V0 -EXPECT "1" get_aux rm -f $QDD diff --git a/tests/bugs/snapshot/bug-1202436-calculate-quota-cksum-during-snap-restore.t b/tests/bugs/snapshot/bug-1202436-calculate-quota-cksum-during-snap-restore.t index 366937245f2..addc05917d8 100644 --- a/tests/bugs/snapshot/bug-1202436-calculate-quota-cksum-during-snap-restore.t +++ b/tests/bugs/snapshot/bug-1202436-calculate-quota-cksum-during-snap-restore.t @@ -27,7 +27,6 @@ EXPECT '1' get_snap_count CLI_1 $V0 TEST $CLI_1 volume stop $V0 EXPECT 'Stopped' volinfo_field $V0 'Status' -EXPECT "1" get_aux TEST $CLI_1 snapshot restore $($CLI_1 snapshot list) EXPECT '0' get_snap_count CLI_1 $V0 diff --git a/tests/volume.rc b/tests/volume.rc index 5ea75a51d22..f95c0013b2e 100644 --- a/tests/volume.rc +++ b/tests/volume.rc @@ -561,8 +561,9 @@ function num_graphs function get_aux() { ##Check if a auxiliary mount is there +local aux_suffix=$1 local rundir=$(gluster --print-statedumpdir) -local pidfile="${rundir}/${V0}.pid" +local pidfile="${rundir}/${V0}$aux_suffix.pid" if [ -f $pidfile ]; then local pid=$(cat ${rundir}/${V0}.pid) @@ -579,6 +580,18 @@ else fi } +function get_list_aux() +{ +# check for quota list aux mount + get_aux "_quota_list" +} + +function get_limit_aux() +{ +# check for quota list aux mount + get_aux "_quota_limit" +} + function get_bitd_count { ps auxww | grep glusterfs | grep bitd.pid | grep -v grep | wc -l } @@ -657,6 +670,10 @@ function quota_hl_exceeded() } +function quota_object_hard_limit() +{ + quota_object_list_field $1 2 +} function scrub_status() { diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 08fc74f396b..0f973520e58 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -702,11 +702,6 @@ glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr, } } - //Remove aux mount of the volume on every node in the cluster - ret = glusterd_remove_auxiliary_mount (volinfo->volname); - if (ret) - goto out; - *crawl = _gf_true; (void) glusterd_clean_up_quota_store (volinfo); @@ -736,7 +731,7 @@ glusterd_set_quota_limit (char *volname, char *path, char *hard_limit, priv = this->private; GF_ASSERT (priv); - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (abspath, volname, path); + GLUSTERD_GET_QUOTA_LIMIT_MOUNT_PATH (abspath, volname, path); ret = gf_lstat_dir (abspath, NULL); if (ret) { gf_asprintf (op_errstr, "Failed to find the directory %s. " @@ -1361,7 +1356,7 @@ glusterd_remove_quota_limit (char *volname, char *path, char **op_errstr, priv = this->private; GF_ASSERT (priv); - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (abspath, volname, path); + GLUSTERD_GET_QUOTA_LIMIT_MOUNT_PATH (abspath, volname, path); ret = gf_lstat_dir (abspath, NULL); if (ret) { gf_asprintf (op_errstr, "Failed to find the directory %s. " @@ -1692,6 +1687,16 @@ glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) ret = 0; out: + if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE || + type == GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS || + type == GF_QUOTA_OPTION_TYPE_REMOVE || + type == GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS) { + /* During a list operation we need the aux mount to be + * accessible until the listing is done at the cli + */ + glusterd_remove_auxiliary_mount (volinfo->volname); + } + return ret; } @@ -1850,7 +1855,7 @@ out: } static int -glusterd_create_quota_auxiliary_mount (xlator_t *this, char *volname) +glusterd_create_quota_auxiliary_mount (xlator_t *this, char *volname, int type) { int ret = -1; int retry = 0; @@ -1861,28 +1866,30 @@ glusterd_create_quota_auxiliary_mount (xlator_t *this, char *volname) char *volfileserver = NULL; glusterd_conf_t *priv = NULL; struct stat buf = {0,}; + FILE *file = NULL; GF_VALIDATE_OR_GOTO ("glusterd", this, out); priv = this->private; GF_VALIDATE_OR_GOTO (this->name, priv, out); - GLUSTERFS_GET_AUX_MOUNT_PIDFILE (pidfile_path, volname); - if (gf_is_service_running (pidfile_path, NULL)) { - gf_msg_debug (this->name, 0, "Aux mount of volume %s is running" - " already", volname); - ret = 0; - goto out; + if (type == GF_QUOTA_OPTION_TYPE_LIST || + type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS) { + GLUSTERFS_GET_QUOTA_LIST_MOUNT_PIDFILE (pidfile_path, volname); + GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH (mountdir, volname, "/"); + } else { + GLUSTERFS_GET_QUOTA_LIMIT_MOUNT_PIDFILE (pidfile_path, volname); + GLUSTERD_GET_QUOTA_LIMIT_MOUNT_PATH (mountdir, volname, "/"); } - if (glusterd_is_fuse_available () == _gf_false) { - gf_msg (this->name, GF_LOG_ERROR, 0, - GD_MSG_MOUNT_REQ_FAIL, "Fuse unavailable"); - ret = -1; - goto out; + file = fopen (pidfile_path, "r"); + if (file) { + /* Previous command did not clean up pid file. + * remove aux mount if it exists*/ + gf_umount_lazy (this->name, mountdir, 1); + fclose(file); } - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, "/"); ret = sys_mkdir (mountdir, 0777); if (ret && errno != EEXIST) { gf_msg (this->name, GF_LOG_ERROR, errno, @@ -2036,7 +2043,7 @@ glusterd_op_stage_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) */ if (is_origin_glusterd (dict)) { ret = glusterd_create_quota_auxiliary_mount (this, - volname); + volname, type); if (ret) { *op_errstr = gf_strdup ("Failed to start aux " "mount"); diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 71956d55c06..c7100cab70b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -10567,21 +10567,12 @@ glusterd_remove_auxiliary_mount (char *volname) { int ret = -1; char mountdir[PATH_MAX] = {0,}; - char pidfile[PATH_MAX] = {0,}; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); - GLUSTERFS_GET_AUX_MOUNT_PIDFILE (pidfile, volname); - - if (!gf_is_service_running (pidfile, NULL)) { - gf_msg_debug (this->name, 0, "Aux mount of volume %s " - "absent, hence returning", volname); - return 0; - } - - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, "/"); + GLUSTERD_GET_QUOTA_LIMIT_MOUNT_PATH (mountdir, volname, "/"); ret = gf_umount_lazy (this->name, mountdir, 1); if (ret) { gf_msg (this->name, GF_LOG_ERROR, errno, diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index bade4ffb06d..62de6b31b64 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -2671,8 +2671,6 @@ glusterd_stop_volume (glusterd_volinfo_t *volinfo) { int ret = -1; glusterd_brickinfo_t *brickinfo = NULL; - char mountdir[PATH_MAX] = {0,}; - char pidfile[PATH_MAX] = {0,}; xlator_t *this = NULL; glusterd_svc_t *svc = NULL; @@ -2701,24 +2699,6 @@ glusterd_stop_volume (glusterd_volinfo_t *volinfo) goto out; } - /* If quota auxiliary mount is present, unmount it */ - GLUSTERFS_GET_AUX_MOUNT_PIDFILE (pidfile, volinfo->volname); - - if (!gf_is_service_running (pidfile, NULL)) { - gf_msg_debug (this->name, 0, "Aux mount of volume %s " - "absent", volinfo->volname); - } else { - GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volinfo->volname, - "/"); - - ret = gf_umount_lazy (this->name, mountdir, 0); - if (ret) - gf_msg (this->name, GF_LOG_ERROR, errno, - GD_MSG_UNOUNT_FAILED, - "umount on %s failed", - mountdir); - } - if (!volinfo->is_snap_volume) { svc = &(volinfo->snapd.svc); ret = svc->manager (svc, volinfo, PROC_START_NO_WAIT); @@ -2803,10 +2783,6 @@ glusterd_op_delete_volume (dict_t *dict) goto out; } - ret = glusterd_remove_auxiliary_mount (volname); - if (ret) - goto out; - ret = glusterd_delete_volume (volinfo); out: gf_msg_debug (this->name, 0, "returning %d", ret); diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index bb6af7f378f..5bdf2ad0d4b 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -592,9 +592,15 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args); #define GLUSTERD_GET_QUOTAD_DIR(path, priv) \ snprintf (path, PATH_MAX, "%s/quotad", priv->workdir); -#define GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH(abspath, volname, path) \ - snprintf (abspath, sizeof (abspath)-1, \ - DEFAULT_VAR_RUN_DIRECTORY"/%s%s", volname, path); +#define GLUSTERD_GET_QUOTA_LIMIT_MOUNT_PATH(abspath, volname, path) do { \ + snprintf (abspath, sizeof (abspath)-1, \ + DEFAULT_VAR_RUN_DIRECTORY"/%s_quota_limit%s", volname, path);\ + } while (0) + +#define GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH(abspath, volname, path) do { \ + snprintf (abspath, sizeof (abspath)-1, \ + DEFAULT_VAR_RUN_DIRECTORY"/%s_quota_list%s", volname, path);\ + } while (0) #define GLUSTERD_GET_TMP_PATH(abspath, path) do { \ snprintf (abspath, sizeof (abspath)-1, \ @@ -683,11 +689,19 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args); uuid_utoa(MY_UUID)); \ } while (0) -#define GLUSTERFS_GET_AUX_MOUNT_PIDFILE(pidfile, volname) { \ +#define GLUSTERFS_GET_QUOTA_LIMIT_MOUNT_PIDFILE(pidfile, volname) { \ snprintf (pidfile, PATH_MAX-1, \ - DEFAULT_VAR_RUN_DIRECTORY"/%s.pid", volname); \ + DEFAULT_VAR_RUN_DIRECTORY"/%s_quota_limit.pid", \ + volname); \ } +#define GLUSTERFS_GET_QUOTA_LIST_MOUNT_PIDFILE(pidfile, volname) { \ + snprintf (pidfile, PATH_MAX-1, \ + DEFAULT_VAR_RUN_DIRECTORY"/%s_quota_list.pid", \ + volname); \ + } + + #define GLUSTERD_GET_UUID_NOHYPHEN(ret_string, uuid) do { \ char *snap_volname_ptr = ret_string; \ char *snap_volid_ptr = uuid_utoa(uuid); \ -- cgit From ba5115bccdc08f395a88d682d3df4af0e4bbfb0a Mon Sep 17 00:00:00 2001 From: Gaurav Yadav Date: Mon, 22 May 2017 23:25:47 +0530 Subject: libglusterfs : Fix crash in glusterd while peer probing glusterd crashes when port is being set explcitly to a range which is outside greater than short data type range. Eg. sysctl net.ipv4.ip_local_reserved_ports="49152-49156" In above case glusterd crashes while parsing the port. With this fix glusterd will be able to handle port range between INT_MIN to INT_MAX > Reviewed-on: https://review.gluster.org/17359 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Samikshan Bairagya > Reviewed-by: Atin Mukherjee > Reviewed-by: Niels de Vos > Reviewed-by: Jeff Darcy Change-Id: I7c75ee67937b0e3384502973d96b1c36c89e0fe1 BUG: 1447523 Signed-off-by: Gaurav Yadav Reviewed-on: https://review.gluster.org/17505 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Atin Mukherjee --- libglusterfs/src/common-utils.c | 10 +++++----- tests/bugs/glusterd/bug-1454418-seg-fault.t | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 tests/bugs/glusterd/bug-1454418-seg-fault.t diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 18f445ae265..d7cd0ad015d 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -3029,14 +3029,14 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling) { gf_boolean_t result = _gf_false; char *range_port = NULL; - int16_t tmp_port1 = -1; - int16_t tmp_port2 = -1; + int32_t tmp_port1 = -1; + int32_t tmp_port2 = -1; if (strstr (blocked_port, "-") == NULL) { /* get rid of the new line character*/ if (blocked_port[strlen(blocked_port) -1] == '\n') blocked_port[strlen(blocked_port) -1] = '\0'; - if (gf_string2int16 (blocked_port, &tmp_port1) == 0) { + if (gf_string2int32 (blocked_port, &tmp_port1) == 0) { if (tmp_port1 > ceiling || tmp_port1 < 0) { gf_msg ("glusterfs-socket", GF_LOG_WARNING, 0, @@ -3062,7 +3062,7 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling) result = _gf_true; goto out; } - if (gf_string2int16 (range_port, &tmp_port1) == 0) { + if (gf_string2int32 (range_port, &tmp_port1) == 0) { if (tmp_port1 > ceiling) tmp_port1 = ceiling; if (tmp_port1 < 0) @@ -3076,7 +3076,7 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling) /* get rid of the new line character*/ if (range_port[strlen(range_port) -1] == '\n') range_port[strlen(range_port) - 1] = '\0'; - if (gf_string2int16 (range_port, &tmp_port2) == 0) { + if (gf_string2int32 (range_port, &tmp_port2) == 0) { if (tmp_port2 > ceiling) tmp_port2 = ceiling; if (tmp_port2 < 0) diff --git a/tests/bugs/glusterd/bug-1454418-seg-fault.t b/tests/bugs/glusterd/bug-1454418-seg-fault.t new file mode 100644 index 00000000000..eafaa55ede8 --- /dev/null +++ b/tests/bugs/glusterd/bug-1454418-seg-fault.t @@ -0,0 +1,25 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../cluster.rc + + +cleanup; + +## Setting Port number in specific range +sysctl net.ipv4.ip_local_reserved_ports="24007-24008,32765-32768,49152-49156" + +## Start a 2 node virtual cluster +TEST launch_cluster 2; + + +## Peer probe server 2 from server 1 cli +TEST $CLI_1 peer probe $H2; + +EXPECT_WITHIN $PROBE_TIMEOUT 1 peer_count + +sysctl net.ipv4.ip_local_reserved_ports=" +" + +cleanup; + -- cgit From 0903b76c88ed47d819372763fdccbe1486bf4943 Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Mon, 29 May 2017 21:38:14 +0530 Subject: posix: use the correct op_errno MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: If readdir/fstat was performed on a directory that was removed, posix_fd_ctx_get() fails with ENOENT but we incorrectly use the ret value (-1 in this case) as op_errno, logging "Operation not permitted" messages in the brick logs. Also in case of fstat, the -1 op_errno was also propagated to the client via stack unwind, causing the message to appear in protocol/client logs as well. Fix: Use the right op_errno in readdir, fstat and writev. A̶l̶s̶o̶,̶ ̶i̶f̶ p̶o̶s̶i̶x̶_̶f̶d̶_̶c̶t̶x̶_̶g̶e̶t̶(̶)̶ ̶f̶a̶i̶l̶e̶d̶ ̶w̶i̶t̶h̶ ̶E̶N̶O̶E̶N̶T̶,̶ ̶c̶o̶n̶v̶e̶r̶t̶ ̶i̶t̶ ̶i̶n̶t̶o̶ ̶E̶B̶A̶D̶F̶ ̶b̶e̶c̶a̶u̶s̶e̶ ̶E̶N̶O̶E̶N̶T̶ i̶s̶ ̶n̶o̶t̶ ̶a̶ ̶v̶a̶l̶i̶d̶ ̶e̶r̶r̶o̶r̶ ̶f̶o̶r̶ ̶a̶n̶ ̶f̶d̶ ̶o̶p̶e̶r̶a̶t̶i̶o̶n̶.̶ Don't do this as it breaks DHT.See 17565 > Reviewed-on: https://review.gluster.org/17414 > Smoke: Gluster Build System > Reviewed-by: Pranith Kumar Karampuri > Tested-by: Pranith Kumar Karampuri > NetBSD-regression: NetBSD Build System > Reviewed-by: Amar Tumballi > CentOS-regression: Gluster Build System (cherry picked from commit de92c363c95d16966dbcc9d8763fd4448dd84d13) Change-Id: Ie43c0789d5040ec73b7cf885d015a183b8c64d70 BUG: 1460661 Signed-off-by: Ravishankar N Reviewed-on: https://review.gluster.org/17517 Smoke: Gluster Build System Reviewed-by: Pranith Kumar Karampuri NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System --- xlators/storage/posix/src/posix-helpers.c | 9 +++++++-- xlators/storage/posix/src/posix.c | 4 +--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 47c47dab07e..678e3770769 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -1695,6 +1695,10 @@ __posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd_p, dir = sys_opendir (real_path); if (!dir) { op_errno = errno; + gf_msg (this->name, GF_LOG_ERROR, op_errno, + P_MSG_READ_FAILED, + "Failed to get anonymous fd for " + "real_path: %s.", real_path); GF_FREE (pfd); pfd = NULL; goto out; @@ -1718,8 +1722,9 @@ __posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd_p, op_errno = errno; gf_msg (this->name, GF_LOG_ERROR, op_errno, P_MSG_READ_FAILED, - "Failed to get anonymous " - "real_path: %s _fd = %d", real_path, _fd); + "Failed to get anonymous fd for " + "real_path: %s.", real_path); + GF_FREE (pfd); pfd = NULL; goto out; diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 503a6512130..fa41c4c90c8 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -3385,7 +3385,6 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, if (ret < 0) { gf_msg (this->name, GF_LOG_WARNING, ret, P_MSG_PFD_NULL, "pfd is NULL from fd=%p", fd); - op_errno = -ret; goto out; } @@ -5916,7 +5915,6 @@ posix_fstat (call_frame_t *frame, xlator_t *this, if (ret < 0) { gf_msg (this->name, GF_LOG_WARNING, op_errno, P_MSG_PFD_NULL, "pfd is NULL, fd=%p", fd); - op_errno = -ret; goto out; } @@ -6348,7 +6346,7 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this, ret = posix_fd_ctx_get (fd, this, &pfd, &op_errno); if (ret < 0) { - gf_msg (this->name, GF_LOG_WARNING, -ret, P_MSG_PFD_NULL, + gf_msg (this->name, GF_LOG_WARNING, op_errno, P_MSG_PFD_NULL, "pfd is NULL, fd=%p", fd); goto out; } -- cgit From cfba812b3e16202249ec70b45d466ffe8b26344f Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Thu, 22 Jun 2017 15:58:48 +0200 Subject: doc: release-notes for GlusterFS-3.8.13 BUG: 1449988 Change-Id: I45feeaf31ac7502736448855923eccbdc8dfdb0c Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/17610 CentOS-regression: Gluster Build System Smoke: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Markus Ueberall Reviewed-by: Kaleb KEITHLEY --- doc/release-notes/3.8.13.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 doc/release-notes/3.8.13.md diff --git a/doc/release-notes/3.8.13.md b/doc/release-notes/3.8.13.md new file mode 100644 index 00000000000..15f85598626 --- /dev/null +++ b/doc/release-notes/3.8.13.md @@ -0,0 +1,22 @@ +# Release notes for Gluster 3.8.13 + +This is a bugfix release. The [Release Notes for 3.8.0](3.8.0.md), +[3.8.1](3.8.1.md), [3.8.2](3.8.2.md), [3.8.3](3.8.3.md), [3.8.4](3.8.4.md), +[3.8.5](3.8.5.md), [3.8.6](3.8.6.md), [3.8.7](3.8.7.md), [3.8.8](3.8.8.md), +[3.8.9](3.8.9.md), [3.8.10](3.8.10.md), [3.8.11](3.8.11.md) and +[3.8.12](3.8.12.md) contain a listing of all the new features that were added +and bugs fixed in the GlusterFS 3.8 stable release. + + +## Bugs addressed + +A total of 13 patches have been merged, addressing 8 bugs: + +- [#1447523](https://bugzilla.redhat.com/1447523): Glusterd segmentation fault in ' _Unwind_Backtrace' while running peer probe +- [#1449782](https://bugzilla.redhat.com/1449782): quota: limit-usage command failed with error " Failed to start aux mount" +- [#1449941](https://bugzilla.redhat.com/1449941): When either killing or restarting a brick with performance.stat-prefetch on, stat sometimes returns a bad st_size value. +- [#1450055](https://bugzilla.redhat.com/1450055): [GANESHA] Adding a node to existing cluster failed to start pacemaker service on new node +- [#1450380](https://bugzilla.redhat.com/1450380): GNFS crashed while taking lock on a file from 2 different clients having same volume mounted from 2 different servers +- [#1450937](https://bugzilla.redhat.com/1450937): [New] - Replacing an arbiter brick while I/O happens causes vm pause +- [#1460650](https://bugzilla.redhat.com/1460650): posix-acl: Whitelist virtual ACL xattrs +- [#1460661](https://bugzilla.redhat.com/1460661): "split-brain observed [Input/output error]" error messages in samba logs during parallel rm -rf -- cgit From 3d5ef4e2cf31f611e3cbcd865c0367bab44a9552 Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Sun, 25 Jun 2017 21:50:09 +0530 Subject: glfsheal: prevent background self-heals Problem: For a file in gfid split-brain, the parent directory ('/' during testing) was detected as possibly undergoing heal instead of split-brain in `heal-info` output. Also, it was not being displayed in `info split-brain` output for the same reason. The problem was that when `glfsheal` was run, lookup on '/' triggered a background self-heal due to which processing of '/' during `heal info` failed to acquire locks with errno=EAGAIN. Fix: Set background-self-heal-count to zero while launching glfsheal. > Reviewed-on: https://review.gluster.org/13772 > CentOS-regression: Gluster Build System > NetBSD-regression: NetBSD Build System > Smoke: Gluster Build System > Reviewed-by: Jeff Darcy (cherry picked from commit b4db625d0ccb4fdc6537ed9f6e8ebeaffd1c4873) Change-Id: I153a7c75af71f213a4eefacf504a0f9806c528a5 BUG: 1467272 Signed-off-by: Ravishankar N Reviewed-on: https://review.gluster.org/17678 Smoke: Gluster Build System CentOS-regression: Gluster Build System Reviewed-by: Pranith Kumar Karampuri Reviewed-by: Niels de Vos --- heal/src/glfs-heal.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c index c65682a5517..8236c693b8e 100644 --- a/heal/src/glfs-heal.c +++ b/heal/src/glfs-heal.c @@ -876,6 +876,11 @@ glfsh_set_heal_options (glfs_t *fs, gf_xl_afr_op_t heal_op) { int ret = 0; + ret = glfs_set_xlator_option (fs, "*-replicate-*", + "background-self-heal-count", "0"); + if (ret) + goto out; + if ((heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE) && (heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) && (heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME)) @@ -892,6 +897,7 @@ glfsh_set_heal_options (glfs_t *fs, gf_xl_afr_op_t heal_op) ret = glfs_set_xlator_option (fs, "*-replicate-*", "entry-self-heal", "on"); + out: return ret; } -- cgit From 9d5328e0e07353501392b33e9553300bd34a32ad Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Mon, 10 Jul 2017 09:45:02 +0200 Subject: rpc/clnt: remove locks while notifying CONNECT/DISCONNECT Locking during notify was introduced as part of commit aa22f24f5db7659387704998ae01520708869873 [1]. The fix was introduced to fix out-of-order CONNECT/DISCONNECT events from rpc-clnt to parent xlators [2]. However as part of handling DISCONNECT protocol/client does unwind saved frames (with failure) waiting for responses. This saved_frames_unwind can be a costly operation and hence ideally shouldn't be included in the critical section of notifylock, as it unnecessarily delays the reconnection to same brick. Also, its not a good practise to pass control to other xlators holding a lock as it can lead to deadlocks. So, this patch removes locking in rpc-clnt while notifying parent xlators. To fix [2], two changes are present in this patch: * notify DISCONNECT before cleaning up rpc connection (same as commit a6b63e11b7758cf1bfcb6798, patch [3]). * protocol/client uses rpc_clnt_cleanup_and_start, which cleans up rpc connection and does a start while handling a DISCONNECT event from rpc. Note that patch [3] was reverted as rpc_clnt_start called in quick_reconnect path of protocol/client didn't invoke connect on transport as the connection was not cleaned up _yet_ (as cleanup was moved post notification in rpc-clnt). This resulted in clients never attempting connect to bricks. Note that one of the neater ways to fix [2] (without using locks) is to introduce generation numbers to map CONNECT and DISCONNECTS across epochs and ignore DISCONNECT events if they don't belong to current epoch. However, this approach is a bit complex to implement and requires time. So, current patch is a hacky stop-gap fix till we come up with a more cleaner solution. [1] http://review.gluster.org/15916 [2] https://bugzilla.redhat.com/show_bug.cgi?id=1386626 [3] http://review.gluster.org/15681 Cherry picked from commit 773f32caf190af4ee48818279b6e6d3c9f2ecc79: > Change-Id: I62daeee8bb1430004e28558f6eb133efd4ccf418 > Signed-off-by: Raghavendra G > BUG: 1427012 > Reviewed-on: https://review.gluster.org/16784 > Smoke: Gluster Build System > Reviewed-by: Milind Changire > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System Change-Id: I62daeee8bb1430004e28558f6eb133efd4ccf418 Reported-by: Markus Stockhausen Signed-off-by: Niels de Vos BUG: 1462447 Reviewed-on: https://review.gluster.org/17733 Smoke: Gluster Build System CentOS-regression: Gluster Build System Reviewed-by: Milind Changire Reviewed-by: Raghavendra G --- rpc/rpc-lib/src/rpc-clnt.c | 94 ++++++++++++++++++++++++------------ rpc/rpc-lib/src/rpc-clnt.h | 4 +- xlators/protocol/client/src/client.c | 2 +- 3 files changed, 68 insertions(+), 32 deletions(-) diff --git a/rpc/rpc-lib/src/rpc-clnt.c b/rpc/rpc-lib/src/rpc-clnt.c index fe099f92f60..b0995ef1373 100644 --- a/rpc/rpc-lib/src/rpc-clnt.c +++ b/rpc/rpc-lib/src/rpc-clnt.c @@ -550,6 +550,7 @@ rpc_clnt_connection_cleanup (rpc_clnt_connection_t *conn) /*reset rpc msgs stats*/ conn->pingcnt = 0; conn->msgcnt = 0; + conn->cleanup_gen++; } pthread_mutex_unlock (&conn->lock); @@ -875,10 +876,29 @@ rpc_clnt_destroy (struct rpc_clnt *rpc); static int rpc_clnt_handle_disconnect (struct rpc_clnt *clnt, rpc_clnt_connection_t *conn) { - struct timespec ts = {0, }; - gf_boolean_t unref_clnt = _gf_false; + struct timespec ts = {0, }; + gf_boolean_t unref_clnt = _gf_false; + uint64_t pre_notify_gen = 0, post_notify_gen = 0; - rpc_clnt_connection_cleanup (conn); + pthread_mutex_lock (&conn->lock); + { + pre_notify_gen = conn->cleanup_gen; + } + pthread_mutex_unlock (&conn->lock); + + if (clnt->notifyfn) + clnt->notifyfn (clnt, clnt->mydata, RPC_CLNT_DISCONNECT, NULL); + + pthread_mutex_lock (&conn->lock); + { + post_notify_gen = conn->cleanup_gen; + } + pthread_mutex_unlock (&conn->lock); + + if (pre_notify_gen == post_notify_gen) { + /* program didn't invoke cleanup, so rpc has to do it */ + rpc_clnt_connection_cleanup (conn); + } pthread_mutex_lock (&conn->lock); { @@ -898,8 +918,6 @@ rpc_clnt_handle_disconnect (struct rpc_clnt *clnt, rpc_clnt_connection_t *conn) } pthread_mutex_unlock (&conn->lock); - if (clnt->notifyfn) - clnt->notifyfn (clnt, clnt->mydata, RPC_CLNT_DISCONNECT, NULL); if (unref_clnt) rpc_clnt_ref (clnt); @@ -932,11 +950,7 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata, switch (event) { case RPC_TRANSPORT_DISCONNECT: { - pthread_mutex_lock (&clnt->notifylock); - { - rpc_clnt_handle_disconnect (clnt, conn); - } - pthread_mutex_unlock (&clnt->notifylock); + rpc_clnt_handle_disconnect (clnt, conn); break; } @@ -991,21 +1005,19 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata, case RPC_TRANSPORT_CONNECT: { - pthread_mutex_lock (&clnt->notifylock); - { - /* Every time there is a disconnection, processes - * should try to connect to 'glusterd' (ie, default - * port) or whichever port given as 'option remote-port' - * in volume file. */ - /* Below code makes sure the (re-)configured port lasts - * for just one successful attempt */ - conn->config.remote_port = 0; - - if (clnt->notifyfn) - ret = clnt->notifyfn (clnt, clnt->mydata, - RPC_CLNT_CONNECT, NULL); - } - pthread_mutex_unlock (&clnt->notifylock); + + /* Every time there is a disconnection, processes + * should try to connect to 'glusterd' (ie, default + * port) or whichever port given as 'option remote-port' + * in volume file. */ + /* Below code makes sure the (re-)configured port lasts + * for just one successful attempt */ + conn->config.remote_port = 0; + + if (clnt->notifyfn) + ret = clnt->notifyfn (clnt, clnt->mydata, + RPC_CLNT_CONNECT, NULL); + break; } @@ -1129,7 +1141,6 @@ rpc_clnt_new (dict_t *options, xlator_t *owner, char *name, } pthread_mutex_init (&rpc->lock, NULL); - pthread_mutex_init (&rpc->notifylock, NULL); rpc->ctx = ctx; rpc->owner = owner; @@ -1139,7 +1150,6 @@ rpc_clnt_new (dict_t *options, xlator_t *owner, char *name, rpc->reqpool = mem_pool_new (struct rpc_req, reqpool_size); if (rpc->reqpool == NULL) { pthread_mutex_destroy (&rpc->lock); - pthread_mutex_destroy (&rpc->notifylock); GF_FREE (rpc); rpc = NULL; goto out; @@ -1149,7 +1159,6 @@ rpc_clnt_new (dict_t *options, xlator_t *owner, char *name, reqpool_size); if (rpc->saved_frames_pool == NULL) { pthread_mutex_destroy (&rpc->lock); - pthread_mutex_destroy (&rpc->notifylock); mem_pool_destroy (rpc->reqpool); GF_FREE (rpc); rpc = NULL; @@ -1159,7 +1168,6 @@ rpc_clnt_new (dict_t *options, xlator_t *owner, char *name, ret = rpc_clnt_connection_init (rpc, ctx, options, name); if (ret == -1) { pthread_mutex_destroy (&rpc->lock); - pthread_mutex_destroy (&rpc->notifylock); mem_pool_destroy (rpc->reqpool); mem_pool_destroy (rpc->saved_frames_pool); GF_FREE (rpc); @@ -1204,6 +1212,33 @@ rpc_clnt_start (struct rpc_clnt *rpc) } +int +rpc_clnt_cleanup_and_start (struct rpc_clnt *rpc) +{ + struct rpc_clnt_connection *conn = NULL; + + if (!rpc) + return -1; + + conn = &rpc->conn; + + rpc_clnt_connection_cleanup (conn); + + pthread_mutex_lock (&conn->lock); + { + rpc->disabled = 0; + } + pthread_mutex_unlock (&conn->lock); + /* Corresponding unref will be either on successful timer cancel or last + * rpc_clnt_reconnect fire event. + */ + rpc_clnt_ref (rpc); + rpc_clnt_reconnect (conn); + + return 0; +} + + int rpc_clnt_register_notify (struct rpc_clnt *rpc, rpc_clnt_notify_t fn, void *mydata) @@ -1755,7 +1790,6 @@ rpc_clnt_destroy (struct rpc_clnt *rpc) saved_frames_destroy (rpc->conn.saved_frames); pthread_mutex_destroy (&rpc->lock); pthread_mutex_destroy (&rpc->conn.lock); - pthread_mutex_destroy (&rpc->notifylock); /* mem-pool should be destroyed, otherwise, it will cause huge memory leaks */ diff --git a/rpc/rpc-lib/src/rpc-clnt.h b/rpc/rpc-lib/src/rpc-clnt.h index 3a5b287cd49..df19a0c403f 100644 --- a/rpc/rpc-lib/src/rpc-clnt.h +++ b/rpc/rpc-lib/src/rpc-clnt.h @@ -150,6 +150,7 @@ struct rpc_clnt_connection { int32_t ping_timeout; uint64_t pingcnt; uint64_t msgcnt; + uint64_t cleanup_gen; }; typedef struct rpc_clnt_connection rpc_clnt_connection_t; @@ -172,7 +173,6 @@ struct rpc_req { typedef struct rpc_clnt { pthread_mutex_t lock; - pthread_mutex_t notifylock; rpc_clnt_notify_t notifyfn; rpc_clnt_connection_t conn; void *mydata; @@ -199,6 +199,8 @@ struct rpc_clnt *rpc_clnt_new (dict_t *options, xlator_t *owner, int rpc_clnt_start (struct rpc_clnt *rpc); +int rpc_clnt_cleanup_and_start (struct rpc_clnt *rpc); + int rpc_clnt_register_notify (struct rpc_clnt *rpc, rpc_clnt_notify_t fn, void *mydata); diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index 3cb5e231fbe..66f15b8a67c 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -2314,7 +2314,7 @@ client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, if (conf->quick_reconnect) { conf->quick_reconnect = 0; - rpc_clnt_start (rpc); + rpc_clnt_cleanup_and_start (rpc); } else { rpc->conn.config.remote_port = 0; -- cgit From 96e7452155c3fd1b160a97d88c03f1bf31b0be97 Mon Sep 17 00:00:00 2001 From: Atin Mukherjee Date: Sat, 18 Mar 2017 16:29:10 +0530 Subject: rpc: bump up conn->cleanup_gen in rpc_clnt_reconnect_cleanup Commit 086436a introduced generation number (cleanup_gen) to ensure that rpc layer doesn't end up cleaning up the connection object if application layer has already destroyed it. Bumping up cleanup_gen was done only in rpc_clnt_connection_cleanup (). However the same is needed in rpc_clnt_reconnect_cleanup () too as with out it if the object gets destroyed through the reconnect event in the application layer, rpc layer will still end up in trying to delete the object resulting into double free and crash. Peer probing an invalid host/IP was the basic test to catch this issue. Cherry picked from commit 39e09ad1e0e93f08153688c31433c38529f93716: > Change-Id: Id5332f3239cb324cead34eb51cf73d426733bd46 > BUG: 1433578 > Signed-off-by: Atin Mukherjee > Reviewed-on: https://review.gluster.org/16914 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > Reviewed-by: Milind Changire > CentOS-regression: Gluster Build System > Reviewed-by: Jeff Darcy Change-Id: Id5332f3239cb324cead34eb51cf73d426733bd46 BUG: 1462447 Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/17743 Smoke: Gluster Build System Reviewed-by: Milind Changire CentOS-regression: Gluster Build System --- rpc/rpc-lib/src/rpc-clnt.c | 4 +++- .../glusterd/bug-1433578-invalid-peer-glusterd-crash.t | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/bugs/glusterd/bug-1433578-invalid-peer-glusterd-crash.t diff --git a/rpc/rpc-lib/src/rpc-clnt.c b/rpc/rpc-lib/src/rpc-clnt.c index b0995ef1373..d3df5560a8b 100644 --- a/rpc/rpc-lib/src/rpc-clnt.c +++ b/rpc/rpc-lib/src/rpc-clnt.c @@ -495,8 +495,10 @@ rpc_clnt_reconnect_cleanup (rpc_clnt_connection_t *conn) if (conn->reconnect) { ret = gf_timer_call_cancel (clnt->ctx, conn->reconnect); - if (!ret) + if (!ret) { reconnect_unref = _gf_true; + conn->cleanup_gen++; + } conn->reconnect = NULL; } diff --git a/tests/bugs/glusterd/bug-1433578-invalid-peer-glusterd-crash.t b/tests/bugs/glusterd/bug-1433578-invalid-peer-glusterd-crash.t new file mode 100644 index 00000000000..1aea8bc134d --- /dev/null +++ b/tests/bugs/glusterd/bug-1433578-invalid-peer-glusterd-crash.t @@ -0,0 +1,14 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc + +cleanup; + +## Start glusterd +TEST glusterd; +TEST pidof glusterd; + +TEST ! $CLI peer probe invalid-peer + +TEST pidof glusterd; +cleanup; -- cgit From c4057aa93eb751ce7860b1fa8923afb8d7b26aba Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Tue, 11 Jul 2017 15:44:14 +0200 Subject: doc: release-notes for GlusterFS-3.8.14 BUG: 1464927 Change-Id: I2ce12274e4d0ed1135370341eacd9f9f66993559 Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/17748 CentOS-regression: Gluster Build System Reviewed-by: Michael Scherer Smoke: Gluster Build System --- doc/release-notes/3.8.14.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 doc/release-notes/3.8.14.md diff --git a/doc/release-notes/3.8.14.md b/doc/release-notes/3.8.14.md new file mode 100644 index 00000000000..46868c21675 --- /dev/null +++ b/doc/release-notes/3.8.14.md @@ -0,0 +1,16 @@ +# Release notes for Gluster 3.8.14 + +This is a bugfix release. The [Release Notes for 3.8.0](3.8.0.md), +[3.8.1](3.8.1.md), [3.8.2](3.8.2.md), [3.8.3](3.8.3.md), [3.8.4](3.8.4.md), +[3.8.5](3.8.5.md), [3.8.6](3.8.6.md), [3.8.7](3.8.7.md), [3.8.8](3.8.8.md), +[3.8.9](3.8.9.md), [3.8.10](3.8.10.md), [3.8.11](3.8.11.md), +[3.8.12](3.8.12.md) and [3.8.13](3.8.13.md) contain a listing of all the new +features that were added and bugs fixed in the GlusterFS 3.8 stable release. + + +## Bugs addressed + +A total of 3 patches have been merged, addressing 2 bugs: + +- [#1462447](https://bugzilla.redhat.com/1462447): brick maintenance - no client reconnect +- [#1467272](https://bugzilla.redhat.com/1467272): Heal info shows incorrect status -- cgit From 117daf0c792f52b4c3fbc685b2f6b15841c81772 Mon Sep 17 00:00:00 2001 From: Ravishankar N <> Date: Mon, 17 Jul 2017 11:23:43 +0530 Subject: afr: mark non sources as sinks in metadata heal Backport of https://review.gluster.org/#/c/17717/ Problem: In a 3 way replica, when the source brick does not have pending xattrs for the sinks, but the 2 sinks blame each other, metadata heal was not happpening because we were not setting all non-sources as sinks. Fix: Mark all non-sources as sinks, like it is done in data and entry heal. Change-Id: I534978940f5087302e307fcc810a48ffe898ce08 BUG: 1471613 Signed-off-by: Ravishankar N Reviewed-on: https://review.gluster.org/17784 Smoke: Gluster Build System Reviewed-by: Pranith Kumar Karampuri CentOS-regression: Gluster Build System --- .../bug-1468279-source-not-blaming-sinks.t | 64 ++++++++++++++++++++++ xlators/cluster/afr/src/afr-self-heal-data.c | 2 +- xlators/cluster/afr/src/afr-self-heal-metadata.c | 6 +- 3 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 tests/bugs/replicate/bug-1468279-source-not-blaming-sinks.t diff --git a/tests/bugs/replicate/bug-1468279-source-not-blaming-sinks.t b/tests/bugs/replicate/bug-1468279-source-not-blaming-sinks.t new file mode 100644 index 00000000000..054a4adb90d --- /dev/null +++ b/tests/bugs/replicate/bug-1468279-source-not-blaming-sinks.t @@ -0,0 +1,64 @@ +#!/bin/bash +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2} +TEST $CLI volume start $V0 +TEST $CLI volume set $V0 cluster.self-heal-daemon off +TEST $CLI volume set $V0 cluster.metadata-self-heal off +TEST $GFS --volfile-id=$V0 --volfile-server=$H0 --attribute-timeout=0 --entry-timeout=0 $M0; +TEST touch $M0/file + +# Kill B1, create a pending metadata heal. +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST setfattr -n user.xattr -v value1 $M0/file +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1/file +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2/file + +# Kill B2, heal from B3 to B1. +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 0 +TEST kill_brick $V0 $H0 $B0/${V0}1 +TEST $CLI volume set $V0 cluster.self-heal-daemon on +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 2 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0 +$CLI volume heal $V0 +EXPECT_WITHIN $HEAL_TIMEOUT "00000000" afr_get_specific_changelog_xattr $B0/${V0}2/file trusted.afr.$V0-client-0 "metadata" +TEST $CLI volume set $V0 cluster.self-heal-daemon off + +# Create another pending metadata heal. +TEST setfattr -n user.xattr -v value2 $M0/file +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}0/file +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2/file + +# Kill B1, heal from B3 to B2 +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1 +TEST kill_brick $V0 $H0 $B0/${V0}0 +TEST $CLI volume set $V0 cluster.self-heal-daemon on +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 2 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1 +$CLI volume heal $V0 +EXPECT_WITHIN $HEAL_TIMEOUT "00000000" afr_get_specific_changelog_xattr $B0/${V0}2/file trusted.afr.$V0-client-1 "metadata" +TEST $CLI volume set $V0 cluster.self-heal-daemon off + +# ALL bricks up again. +TEST $CLI volume start $V0 force +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1 +EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1 +# B1 and B2 blame each other, B3 doesn't blame anyone. +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}0/file +EXPECT "0000000000000010000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}1/file +EXPECT "0000000000000000000000" get_hex_xattr trusted.afr.$V0-client-0 $B0/${V0}2/file +EXPECT "0000000000000000000000" get_hex_xattr trusted.afr.$V0-client-1 $B0/${V0}2/file +TEST $CLI volume set $V0 cluster.self-heal-daemon on +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 2 +TEST $CLI volume heal $V0 +EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V0 + +cleanup; diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c index b025c0e9781..cf03a9ec680 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -560,7 +560,7 @@ __afr_selfheal_data_finalize_source (call_frame_t *frame, xlator_t *this, AFR_DATA_TRANSACTION, locked_on, replies); - return source; + goto out; } /* No split brain at this point. If we were called from diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c index d5d95ef8852..db1b1cc889f 100644 --- a/xlators/cluster/afr/src/afr-self-heal-metadata.c +++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c @@ -230,7 +230,7 @@ __afr_selfheal_metadata_finalize_source (call_frame_t *frame, xlator_t *this, undid_pending, AFR_METADATA_TRANSACTION, locked_on, replies); - return source; + goto out; } /* If this is a directory mtime/ctime only split brain @@ -244,7 +244,7 @@ __afr_selfheal_metadata_finalize_source (call_frame_t *frame, xlator_t *this, uuid_utoa (replies[source].poststat.ia_gfid)); sources[source] = 1; healed_sinks[source] = 0; - return source; + goto out; } if (!priv->metadata_splitbrain_forced_heal) { @@ -303,6 +303,8 @@ __afr_selfheal_metadata_finalize_source (call_frame_t *frame, xlator_t *this, } } +out: + afr_mark_active_sinks (this, sources, locked_on, healed_sinks); return source; } -- cgit From 982480ecbc0085d4e6bbbc976d2549abbd5f3e61 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Wed, 19 Jul 2017 16:14:59 +0530 Subject: storage/posix: Use the ret value of posix_gfid_heal() ... to make the change in commit acf8cfdf truly useful. Without this, a race between entry creation fops and lookup at posix layer can cause lookups to fail with ENODATA, as opposed to ENOENT. Backport of: > Change-Id: I44a226872283a25f1f4812f03f68921c5eb335bb > Reviewed-on: https://review.gluster.org/17821 > BUG: 1472758 > cherry-picked from 669868d23eaeba42809fca7be134137c607d64ed Change-Id: I44a226872283a25f1f4812f03f68921c5eb335bb BUG: 1480193 Signed-off-by: Krutika Dhananjay Reviewed-on: https://review.gluster.org/18015 Smoke: Gluster Build System CentOS-regression: Gluster Build System Reviewed-by: Raghavendra Bhat Reviewed-by: Niels de Vos --- xlators/storage/posix/src/posix-helpers.c | 16 +++++++--------- xlators/storage/posix/src/posix.c | 7 ++++++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 678e3770769..76e32a31594 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -1531,23 +1531,21 @@ posix_gfid_heal (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req struct stat stat = {0, }; if (!xattr_req) - goto out; + return 0; - if (sys_lstat (path, &stat) != 0) - goto out; + if (sys_lstat (path, &stat) != 0) { + return -errno; + } ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16); if (ret != 16) { if (is_fresh_file (&stat)) { - ret = -1; - errno = ENOENT; - goto out; + return -ENOENT; } } - ret = posix_gfid_set (this, path, loc, xattr_req); -out: - return ret; + posix_gfid_set (this, path, loc, xattr_req); + return 0; } diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index fa41c4c90c8..dfb7e05e49a 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -189,7 +189,12 @@ posix_lookup (call_frame_t *frame, xlator_t *this, MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &buf); if (gf_uuid_is_null (loc->inode->gfid)) { - posix_gfid_heal (this, real_path, loc, xdata); + op_ret = posix_gfid_heal (this, real_path, loc, xdata); + if (op_ret < 0) { + op_errno = -op_ret; + op_ret = -1; + goto out; + } MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &buf); } -- cgit From b7b13c8cd295fa2e9fba9cc77211e576469e9581 Mon Sep 17 00:00:00 2001 From: Atin Mukherjee Date: Wed, 5 Jul 2017 14:58:50 +0530 Subject: cli/xml: fix return handling The return code of xmlTextWriter* APIs says it returns either the bytes written (may be 0 because of buffering) or -1 in case of error. Now if the volume of the xml data payload is not huge then most of the time the data to be written gets buffered, however when this grows sometimes this APIs will return the total number of bytes written and then it becomes absolutely mandatory that every such call is followed by XML_RET_CHECK_AND_GOTO otherwise we may end up returning a non zero ret code which would result into the overall xml generation to fail. >Reviewed-on: https://review.gluster.org/17702 >Smoke: Gluster Build System >Reviewed-by: Amar Tumballi >CentOS-regression: Gluster Build System >Reviewed-by: Gaurav Yadav Change-Id: I02ee7076e1d8c26cf654d3dc3e77b1eb17cbdab0 BUG: 1470495 Signed-off-by: Atin Mukherjee Reviewed-on: https://review.gluster.org/17766 Smoke: Gluster Build System CentOS-regression: Gluster Build System Reviewed-by: Samikshan Bairagya Reviewed-by: Niels de Vos --- cli/src/cli-xml-output.c | 91 +++++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 4eafc0b5e68..0704174c211 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -194,6 +194,8 @@ cli_xml_output_data_pair (dict_t *this, char *key, data_t *value, ret = xmlTextWriterWriteFormatElement (*writer, (xmlChar *)key, "%s", value->data); + XML_RET_CHECK_AND_GOTO (ret, out); +out: return ret; } #endif @@ -324,7 +326,7 @@ cli_xml_output_vol_status_common (xmlTextWriterPtr writer, dict_t *dict, ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"port", "%s", "N/A"); - + XML_RET_CHECK_AND_GOTO (ret, out); ret = xmlTextWriterStartElement (writer, (xmlChar *)"ports"); if (*online == 1 && (port != 0 || rdma_port != 0)) { @@ -337,7 +339,7 @@ cli_xml_output_vol_status_common (xmlTextWriterPtr writer, dict_t *dict, (xmlChar *)"tcp", "%s", "N/A"); } - + XML_RET_CHECK_AND_GOTO (ret, out); if (rdma_port) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"rdma", @@ -347,14 +349,16 @@ cli_xml_output_vol_status_common (xmlTextWriterPtr writer, dict_t *dict, (xmlChar *)"rdma", "%s", "N/A"); } - + XML_RET_CHECK_AND_GOTO (ret, out); } else { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"tcp", "%s", "N/A"); + XML_RET_CHECK_AND_GOTO (ret, out); ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"rdma", "%s", "N/A"); + XML_RET_CHECK_AND_GOTO (ret, out); } ret = xmlTextWriterEndElement (writer); @@ -392,77 +396,86 @@ cli_xml_output_vol_status_detail (xmlTextWriterPtr writer, dict_t *dict, snprintf (key, sizeof (key), "brick%d.total", brick_index); ret = dict_get_uint64 (dict, key, &size_total); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"sizeTotal", "%"PRIu64, size_total); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.free", brick_index); ret = dict_get_uint64 (dict, key, &size_free); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"sizeFree", "%"PRIu64, size_free); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.device", brick_index); ret = dict_get_str (dict, key, &device); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"device", "%s", device); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.block_size", brick_index); ret = dict_get_uint64 (dict, key, &block_size); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"blockSize", "%"PRIu64, block_size); - XML_RET_CHECK_AND_GOTO (ret, out); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.mnt_options", brick_index); ret = dict_get_str (dict, key, &mnt_options); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"mntOptions", "%s", mnt_options); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.fs_name", brick_index); ret = dict_get_str (dict, key, &fs_name); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"fsName", "%s", fs_name); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.inode_size", brick_index); ret = dict_get_str (dict, key, &inode_size); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"inodeSize", "%s", fs_name); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.total_inodes", brick_index); ret = dict_get_uint64 (dict, key, &inodes_total); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"inodesTotal", "%"PRIu64, inodes_total); - + XML_RET_CHECK_AND_GOTO (ret, out); + } memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.free_inodes", brick_index); ret = dict_get_uint64 (dict, key, &inodes_free); - if (!ret) + if (!ret) { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"inodesFree", "%"PRIu64, inodes_free); - else + XML_RET_CHECK_AND_GOTO (ret, out); + } else { ret = 0; + } out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); @@ -1366,6 +1379,7 @@ cli_xml_output_vol_status_callpool (xmlTextWriterPtr writer, dict_t *dict, goto out; ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"count", "%d", call_count); + XML_RET_CHECK_AND_GOTO (ret, out); for (i = 0; i < call_count; i++) { memset (key, 0, sizeof (key)); @@ -1476,7 +1490,7 @@ cli_xml_output_remove_brick_task_params (xmlTextWriterPtr writer, dict_t *dict, /* */ ret = xmlTextWriterEndElement (writer); - + XML_RET_CHECK_AND_GOTO (ret, out); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -1560,7 +1574,7 @@ cli_xml_output_vol_status_tasks (cli_local_t *local, dict_t *dict) { /* */ ret = xmlTextWriterEndElement (local->writer); - + XML_RET_CHECK_AND_GOTO (ret, out); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -1637,8 +1651,8 @@ cli_xml_output_vol_status (cli_local_t *local, dict_t *dict) ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"nodeCount", "%d", brick_count); - if (ret) - goto out; + + XML_RET_CHECK_AND_GOTO (ret, out); ret = dict_get_uint32 (dict, "cmd", &cmd); if (ret) @@ -2018,6 +2032,7 @@ cli_xml_output_vol_top (dict_t *dict, int op_ret, int op_errno, ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"timeTaken", "%f", time_taken); + XML_RET_CHECK_AND_GOTO (ret, out); } break; @@ -2320,8 +2335,7 @@ cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno, (writer, (xmlChar *)"clearStats", "%s", stats_cleared ? "Cleared stats." : "Failed to clear stats."); - if (ret) - goto out; + XML_RET_CHECK_AND_GOTO (ret, out); } else { snprintf (key, sizeof (key), "%d-cumulative", i); ret = dict_get_int32 (dict, key, &interval); @@ -2832,6 +2846,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"hotBrickType", "%s", cli_vol_type_str[tier_vol_type]); + XML_RET_CHECK_AND_GOTO (ret, out); ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"hotreplicaCount", @@ -2852,7 +2867,6 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) (local->writer, (xmlChar *)"numberOfBricks", "%d", value[HOT_BRICK_COUNT]); - XML_RET_CHECK_AND_GOTO (ret, out); } else { ret = xmlTextWriterWriteFormatElement (local->writer, @@ -2863,6 +2877,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) hot_dist_count, value[HOT_BRICK_COUNT]); } + XML_RET_CHECK_AND_GOTO (ret, out); while (index <= value[HOT_BRICK_COUNT]) { snprintf (key, 1024, "volume%d.brick%d", i, @@ -2924,6 +2939,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"coldBrickType", "%s", cli_vol_type_str[tier_vol_type]); + XML_RET_CHECK_AND_GOTO (ret, out); ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"coldreplicaCount", @@ -2953,8 +2969,6 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) (local->writer, (xmlChar *)"numberOfBricks", "%d", value[COLD_BRICK_COUNT]); - XML_RET_CHECK_AND_GOTO (ret, out); - } else if (value[COLD_TYPE] == GF_CLUSTER_TYPE_DISPERSE) { ret = xmlTextWriterWriteFormatElement @@ -2979,6 +2993,7 @@ cli_xml_output_vol_info (cli_local_t *local, dict_t *dict) } start_index = index = value[HOT_BRICK_COUNT] + 1; + XML_RET_CHECK_AND_GOTO (ret, out); while (index <= brick_count) { snprintf (key, 1024, "volume%d.brick%d", i, @@ -3170,7 +3185,7 @@ cli_xml_output_vol_info_end (cli_local_t *local) ret = xmlTextWriterWriteFormatElement (local->writer, (xmlChar *)"count", "%d", local->vol_count); - + XML_RET_CHECK_AND_GOTO (ret, out); /* */ ret = xmlTextWriterEndElement (local->writer); XML_RET_CHECK_AND_GOTO (ret, out); @@ -3196,9 +3211,7 @@ cli_xml_output_vol_quota_limit_list_end (cli_local_t *local) int ret = -1; ret = xmlTextWriterEndElement (local->writer); - if (ret) { - goto out; - } + XML_RET_CHECK_AND_GOTO (ret, out); ret = cli_end_xml_output (local->writer, local->doc); @@ -3266,7 +3279,7 @@ cli_xml_output_peer_hostnames (xmlTextWriterPtr writer, dict_t *dict, /* */ ret = xmlTextWriterEndElement (writer); - + XML_RET_CHECK_AND_GOTO (ret, out); out: gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; @@ -3470,6 +3483,7 @@ cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict, ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"nodeName", "%s", node_name); + XML_RET_CHECK_AND_GOTO (ret, out); memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "node-uuid-%d", i); @@ -3554,6 +3568,7 @@ cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict, (xmlChar *)"statusStr", "%s", cli_vol_task_status_str[status_rcd]); + XML_RET_CHECK_AND_GOTO (ret, out); memset (key, 0, 256); snprintf (key, 256, "run-time-%d", i); @@ -5767,7 +5782,6 @@ cli_xml_snapshot_delete (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict, ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "status", "Success"); - XML_RET_CHECK_AND_GOTO (ret, xmlend); } else { ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "status", @@ -5777,9 +5791,8 @@ cli_xml_snapshot_delete (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict, ret = cli_xml_output_common (writer, rsp->op_ret, rsp->op_errno, rsp->op_errstr); - XML_RET_CHECK_AND_GOTO (ret, xmlend); } - + XML_RET_CHECK_AND_GOTO (ret, xmlend); ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name", "%s", str_value); -- cgit From 3f26a7ba8d74af3c2f1c149160124e91fac534f8 Mon Sep 17 00:00:00 2001 From: "Kaleb S. KEITHLEY" Date: Mon, 14 Aug 2017 16:27:57 -0400 Subject: api: memory leak in glfs_h_acl_get(), missing dict unref master review https://review.gluster.org/17092 circa April 2017 Fix already exists in release-3.12 and release-3.11 branches Hat tip to Shyam (srangana[at]redhat.com) who found the existing fix after sitting and debugging it with me for several hours. Reported-by: Kinglong Mee Change-Id: Ic7169fd05aff7bf46108e8ac7b1f29688a7f2358 BUG: 1481398 Signed-off-by: Kaleb S. KEITHLEY Reviewed-on: https://review.gluster.org/18037 Smoke: Gluster Build System Reviewed-by: Kinglong Mee CentOS-regression: Gluster Build System Reviewed-by: Prashanth Pai Reviewed-by: Niels de Vos --- api/src/glfs-handleops.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c index a464b2ed195..b5fcfab713c 100644 --- a/api/src/glfs-handleops.c +++ b/api/src/glfs-handleops.c @@ -2297,13 +2297,15 @@ pub_glfs_h_acl_get (struct glfs *fs, struct glfs_object *object, goto out; ret = dict_get_str (xattr, (char *)acl_key, &acl_s); - if (ret == -1) + if (ret) goto out; acl = acl_from_text (acl_s); out: - GF_FREE (acl_s); + if (xattr) + dict_unref (xattr); + if (IA_ISLNK (object->inode->ia_type) && new_object) glfs_h_close (new_object); -- cgit From d174f021a4e0667e60ce6abc038106ad9b74dc74 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Tue, 15 Aug 2017 15:17:21 +0200 Subject: doc: release-notes for GlusterFS-3.8.15 BUG: 1469558 Change-Id: Ia9a4e69e5d7dfd33933b20b7c4ea41e439d3c838 Signed-off-by: Niels de Vos Reviewed-on: https://review.gluster.org/18039 CentOS-regression: Gluster Build System Smoke: Gluster Build System Reviewed-by: jiffin tony Thottan --- doc/release-notes/3.8.15.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 doc/release-notes/3.8.15.md diff --git a/doc/release-notes/3.8.15.md b/doc/release-notes/3.8.15.md new file mode 100644 index 00000000000..f8ddf5c74c4 --- /dev/null +++ b/doc/release-notes/3.8.15.md @@ -0,0 +1,30 @@ +# Release notes for Gluster 3.8.15 + +This is a bugfix release. The [Release Notes for 3.8.0](3.8.0.md), +[3.8.1](3.8.1.md), [3.8.2](3.8.2.md), [3.8.3](3.8.3.md), [3.8.4](3.8.4.md), +[3.8.5](3.8.5.md), [3.8.6](3.8.6.md), [3.8.7](3.8.7.md), [3.8.8](3.8.8.md), +[3.8.9](3.8.9.md), [3.8.10](3.8.10.md), [3.8.11](3.8.11.md), +[3.8.12](3.8.12.md), [3.8.13](3.8.13.md) and [3.8.14](3.8.14.md) contain a +listing of all the new features that were added and bugs fixed in the GlusterFS +3.8 stable release. + + +## End Of Life Notice + +This is most likely the last bugfix release for the GlusterFS 3.8 +Long-Term-Support version. GlusterFS 3.12 is planned to be released at the end +of August 2017 and will be the next Long-Term-Support version. It is highly +recommended to upgrade any Gluster 3.8 environment to either the 3.10 or 3.12 +release. More details about the different Long-Term-Support versions can be +found on the [release +schedule](https://www.gluster.org/community/release-schedule/). + + +## Bugs addressed + +A total of 4 patches have been merged, addressing 4 bugs: + +- [#1470495](https://bugzilla.redhat.com/1470495): gluster volume status --xml fails when there are 100 volumes +- [#1471613](https://bugzilla.redhat.com/1471613): metadata heal not happening despite having an active sink +- [#1480193](https://bugzilla.redhat.com/1480193): Running sysbench on vm disk from plain distribute gluster volume causes disk corruption +- [#1481398](https://bugzilla.redhat.com/1481398): libgfapi: memory leak in glfs_h_acl_get -- cgit