From 911cf6c7be066dfb6c15e6c512d6d3d1f35b9faf Mon Sep 17 00:00:00 2001 From: Sunil Kumar Acharya Date: Thu, 27 Jun 2019 22:48:39 -0400 Subject: [PATCH] autobuild v6.0-7 Resolves: bz#1573077 bz#1600918 bz#1703423 bz#1704207 bz#1704562 Resolves: bz#1708064 bz#1709301 bz#1711939 bz#1713664 bz#1716760 Resolves: bz#1717784 bz#1720163 bz#1720192 bz#1720551 bz#1721351 Resolves: bz#1721357 bz#1721477 bz#1721802 bz#1722131 bz#1722331 Resolves: bz#1722509 bz#1722801 Signed-off-by: Sunil Kumar Acharya --- ...ec-fixed-python-dependency-for-rhel6.patch | 42 + ...to-have-unique-call-stacks-in-all-ca.patch | 144 +++ ...lusterfs-ganesha-for-rhel7-and-above.patch | 89 ++ ...-posix-ctime-Fix-ctime-upgrade-issue.patch | 384 ++++++ ...osix-fix-crash-in-posix_cs_set_state.patch | 71 ++ ...er-ec-Prevent-double-pre-op-xattrops.patch | 119 ++ ...ding-notifications-for-invalid-inode.patch | 80 ++ ...ect-initialization-of-upcall-syncop-.patch | 206 ++++ ...issions-for-GEOREP_DIR-in-non-root-s.patch | 44 + ...ace-between-mux_proc-unlink-and-stop.patch | 46 + ...-Change-shd-logfile-to-a-unique-name.patch | 233 ++++ ...ionally-clear-txn_opinfo-in-stage-op.patch | 60 + ...un-rebalance-due-to-long-unix-socket.patch | 195 +++ ...user.-options-from-compatibility-che.patch | 41 + ...sterd-fix-use-after-free-of-a-dict_t.patch | 44 + 0208-mem-pool-remove-dead-code.patch | 161 +++ ...dynamic-TLS-allocation-when-possible.patch | 1059 +++++++++++++++++ 0210-mem-pool.-c-h-minor-changes.patch | 129 ++ ...-compilation-when-disable-mempool-is.patch | 41 + 0212-core-fix-memory-allocation-issues.patch | 169 +++ 0213-cluster-dht-Strip-out-dht-xattrs.patch | 42 + ...Upgrading-config-file-to-new-version.patch | 114 ++ ...rage.reserve-option-to-take-size-and.patch | 319 +++++ ...-Test-case-fixe-for-downstream-3.5.0.patch | 29 + ...tar-issue-with-ctime-and-uss-enabled.patch | 75 ++ ...usterfs_graph_deactivate-to-free-the.patch | 88 ++ ...d-posix_set_ctime-in-posix_ftruncate.patch | 35 + ...p-down-approach-while-cleaning-xlato.patch | 190 +++ ...propagte-GF_EVENT_CHILD_PING-only-fo.patch | 75 ++ glusterfs.spec | 57 +- 30 files changed, 4375 insertions(+), 6 deletions(-) create mode 100644 0193-spec-fixed-python-dependency-for-rhel6.patch create mode 100644 0194-stack-Make-sure-to-have-unique-call-stacks-in-all-ca.patch create mode 100644 0195-build-package-glusterfs-ganesha-for-rhel7-and-above.patch create mode 100644 0196-posix-ctime-Fix-ctime-upgrade-issue.patch create mode 100644 0197-posix-fix-crash-in-posix_cs_set_state.patch create mode 100644 0198-cluster-ec-Prevent-double-pre-op-xattrops.patch create mode 100644 0199-upcall-Avoid-sending-notifications-for-invalid-inode.patch create mode 100644 0200-gfapi-fix-incorrect-initialization-of-upcall-syncop-.patch create mode 100644 0201-geo-rep-Fix-permissions-for-GEOREP_DIR-in-non-root-s.patch create mode 100644 0202-shd-mux-Fix-race-between-mux_proc-unlink-and-stop.patch create mode 100644 0203-glusterd-shd-Change-shd-logfile-to-a-unique-name.patch create mode 100644 0204-glusterd-conditionally-clear-txn_opinfo-in-stage-op.patch create mode 100644 0205-glusterd-Can-t-run-rebalance-due-to-long-unix-socket.patch create mode 100644 0206-glusterd-ignore-user.-options-from-compatibility-che.patch create mode 100644 0207-glusterd-fix-use-after-free-of-a-dict_t.patch create mode 100644 0208-mem-pool-remove-dead-code.patch create mode 100644 0209-core-avoid-dynamic-TLS-allocation-when-possible.patch create mode 100644 0210-mem-pool.-c-h-minor-changes.patch create mode 100644 0211-libglusterfs-Fix-compilation-when-disable-mempool-is.patch create mode 100644 0212-core-fix-memory-allocation-issues.patch create mode 100644 0213-cluster-dht-Strip-out-dht-xattrs.patch create mode 100644 0214-geo-rep-Upgrading-config-file-to-new-version.patch create mode 100644 0215-posix-modify-storage.reserve-option-to-take-size-and.patch create mode 100644 0216-Test-case-fixe-for-downstream-3.5.0.patch create mode 100644 0217-uss-Fix-tar-issue-with-ctime-and-uss-enabled.patch create mode 100644 0218-graph-shd-Use-glusterfs_graph_deactivate-to-free-the.patch create mode 100644 0219-posix-add-posix_set_ctime-in-posix_ftruncate.patch create mode 100644 0220-graph-shd-Use-top-down-approach-while-cleaning-xlato.patch create mode 100644 0221-protocol-client-propagte-GF_EVENT_CHILD_PING-only-fo.patch diff --git a/0193-spec-fixed-python-dependency-for-rhel6.patch b/0193-spec-fixed-python-dependency-for-rhel6.patch new file mode 100644 index 0000000..6b00b69 --- /dev/null +++ b/0193-spec-fixed-python-dependency-for-rhel6.patch @@ -0,0 +1,42 @@ +From 58bc818f19cbc8e4dd97097dc3e4ec7af8fa8d4a Mon Sep 17 00:00:00 2001 +From: Rinku Kothiya +Date: Tue, 7 May 2019 05:35:11 +0000 +Subject: [PATCH 193/221] spec: fixed python dependency for rhel6 + +Installing redhat-storage-server was failing with python dependency +for glusterfs-geo-replication package. This patch conditionally sets +the python version for rhel7 and fixes the problem. + +Label: DOWNSTREAM ONLY + +BUG: 1704207 + +Change-Id: Ie3b079fd1ccfa6fd2cbf5b08b7a70bd03f090e01 +fixes: bz#1704207 +Signed-off-by: Rinku Kothiya +Reviewed-on: https://code.engineering.redhat.com/gerrit/169555 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + glusterfs.spec.in | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index c505cd9..1150101 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -500,7 +500,11 @@ Summary: GlusterFS Geo-replication + Requires: %{name}%{?_isa} = %{version}-%{release} + Requires: %{name}-server%{?_isa} = %{version}-%{release} + Requires: python%{_pythonver} ++%if ( 0%{?rhel} && 0%{?rhel} < 7 ) ++Requires: python-prettytable ++%else + Requires: python%{_pythonver}-prettytable ++%endif + Requires: python%{_pythonver}-gluster = %{version}-%{release} + + Requires: rsync +-- +1.8.3.1 + diff --git a/0194-stack-Make-sure-to-have-unique-call-stacks-in-all-ca.patch b/0194-stack-Make-sure-to-have-unique-call-stacks-in-all-ca.patch new file mode 100644 index 0000000..7b8371f --- /dev/null +++ b/0194-stack-Make-sure-to-have-unique-call-stacks-in-all-ca.patch @@ -0,0 +1,144 @@ +From 783f53b0b09845cd6c38f145eac685a094767ce0 Mon Sep 17 00:00:00 2001 +From: Pranith Kumar K +Date: Mon, 27 May 2019 11:43:26 +0530 +Subject: [PATCH 194/221] stack: Make sure to have unique call-stacks in all + cases + +At the moment new stack doesn't populate frame->root->unique in all cases. This +makes it difficult to debug hung frames by examining successive state dumps. +Fuse and server xlators populate it whenever they can, but other xlators won't +be able to assign 'unique' when they need to create a new frame/stack because +they don't know what 'unique' fuse/server xlators already used. What we need is +for unique to be correct. If a stack with same unique is present in successive +statedumps, that means the same operation is still in progress. This makes +'finding hung frames' part of debugging hung frames easier. + + >upstream: bz#1714098 + >Upstream-patch: https://review.gluster.org/c/glusterfs/+/22773 +fixes bz#1716760 +Change-Id: I3e9a8f6b4111e260106c48a2ac3a41ef29361b9e +Signed-off-by: Pranith Kumar K +Reviewed-on: https://code.engineering.redhat.com/gerrit/172304 +Reviewed-by: Atin Mukherjee +Tested-by: RHGS Build Bot +--- + libglusterfs/src/stack.c | 2 ++ + xlators/features/quota/src/quotad-helpers.c | 3 --- + xlators/mount/fuse/src/fuse-bridge.c | 15 ++++++++------- + xlators/mount/fuse/src/fuse-helpers.c | 1 - + xlators/protocol/server/src/server-helpers.c | 3 --- + 5 files changed, 10 insertions(+), 14 deletions(-) + +diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c +index 82b3577..371f60c 100644 +--- a/libglusterfs/src/stack.c ++++ b/libglusterfs/src/stack.c +@@ -17,6 +17,7 @@ create_frame(xlator_t *xl, call_pool_t *pool) + { + call_stack_t *stack = NULL; + call_frame_t *frame = NULL; ++ static uint64_t unique = 0; + + if (!xl || !pool) { + return NULL; +@@ -52,6 +53,7 @@ create_frame(xlator_t *xl, call_pool_t *pool) + { + list_add(&stack->all_frames, &pool->all_frames); + pool->cnt++; ++ stack->unique = unique++; + } + UNLOCK(&pool->lock); + GF_ATOMIC_INC(pool->total_count); +diff --git a/xlators/features/quota/src/quotad-helpers.c b/xlators/features/quota/src/quotad-helpers.c +index be8f908..d9f0351 100644 +--- a/xlators/features/quota/src/quotad-helpers.c ++++ b/xlators/features/quota/src/quotad-helpers.c +@@ -73,7 +73,6 @@ quotad_aggregator_alloc_frame(rpcsvc_request_t *req) + goto out; + + frame->root->state = state; +- frame->root->unique = 0; + + frame->this = this; + out: +@@ -93,8 +92,6 @@ quotad_aggregator_get_frame_from_req(rpcsvc_request_t *req) + + frame->root->op = req->procnum; + +- frame->root->unique = req->xid; +- + frame->root->uid = req->uid; + frame->root->gid = req->gid; + frame->root->pid = req->pid; +diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c +index c3945d7..c05866b 100644 +--- a/xlators/mount/fuse/src/fuse-bridge.c ++++ b/xlators/mount/fuse/src/fuse-bridge.c +@@ -3270,11 +3270,11 @@ fuse_release(xlator_t *this, fuse_in_header_t *finh, void *msg, + + priv = this->private; + +- fuse_log_eh(this, "RELEASE(): %" PRIu64 ":, fd: %p, gfid: %s", finh->unique, +- fd, uuid_utoa(fd->inode->gfid)); ++ fuse_log_eh(this, "RELEASE(): finh->unique: %" PRIu64 ":, fd: %p, gfid: %s", ++ finh->unique, fd, uuid_utoa(fd->inode->gfid)); + +- gf_log("glusterfs-fuse", GF_LOG_TRACE, "%" PRIu64 ": RELEASE %p", +- finh->unique, state->fd); ++ gf_log("glusterfs-fuse", GF_LOG_TRACE, ++ "finh->unique: %" PRIu64 ": RELEASE %p", finh->unique, state->fd); + + fuse_fd_ctx_destroy(this, state->fd); + fd_unref(fd); +@@ -3759,11 +3759,12 @@ fuse_releasedir(xlator_t *this, fuse_in_header_t *finh, void *msg, + + priv = this->private; + +- fuse_log_eh(this, "RELEASEDIR (): %" PRIu64 ": fd: %p, gfid: %s", ++ fuse_log_eh(this, ++ "RELEASEDIR (): finh->unique: %" PRIu64 ": fd: %p, gfid: %s", + finh->unique, state->fd, uuid_utoa(state->fd->inode->gfid)); + +- gf_log("glusterfs-fuse", GF_LOG_TRACE, "%" PRIu64 ": RELEASEDIR %p", +- finh->unique, state->fd); ++ gf_log("glusterfs-fuse", GF_LOG_TRACE, ++ "finh->unique: %" PRIu64 ": RELEASEDIR %p", finh->unique, state->fd); + + fuse_fd_ctx_destroy(this, state->fd); + fd_unref(state->fd); +diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c +index cf4f8e1..5bfc40c 100644 +--- a/xlators/mount/fuse/src/fuse-helpers.c ++++ b/xlators/mount/fuse/src/fuse-helpers.c +@@ -358,7 +358,6 @@ get_call_frame_for_req(fuse_state_t *state) + frame->root->uid = finh->uid; + frame->root->gid = finh->gid; + frame->root->pid = finh->pid; +- frame->root->unique = finh->unique; + set_lk_owner_from_uint64(&frame->root->lk_owner, state->lk_owner); + } + +diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c +index 1a34239..e74a24d 100644 +--- a/xlators/protocol/server/src/server-helpers.c ++++ b/xlators/protocol/server/src/server-helpers.c +@@ -459,7 +459,6 @@ server_alloc_frame(rpcsvc_request_t *req) + + frame->root->client = client; + frame->root->state = state; /* which socket */ +- frame->root->unique = 0; /* which call */ + + frame->this = client->this; + out: +@@ -487,8 +486,6 @@ get_frame_from_request(rpcsvc_request_t *req) + + frame->root->op = req->procnum; + +- frame->root->unique = req->xid; +- + client = req->trans->xl_private; + this = req->trans->xl; + priv = this->private; +-- +1.8.3.1 + diff --git a/0195-build-package-glusterfs-ganesha-for-rhel7-and-above.patch b/0195-build-package-glusterfs-ganesha-for-rhel7-and-above.patch new file mode 100644 index 0000000..949ebb6 --- /dev/null +++ b/0195-build-package-glusterfs-ganesha-for-rhel7-and-above.patch @@ -0,0 +1,89 @@ +From 909a6461c860fffde5f886891dd53752f60eae67 Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Tue, 18 Jun 2019 12:10:55 +0530 +Subject: [PATCH 195/221] build : package glusterfs-ganesha for rhel7 and above + +Label : DOWNSTREAM ONLY + +Change-Id: If845675b18fe055708d905ec566014baf004cb76 +fixes: bz#1720551 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://code.engineering.redhat.com/gerrit/173748 +Reviewed-by: Sreenath Girijan Menon +Tested-by: RHGS Build Bot +Reviewed-by: Kaleb Keithley +--- + glusterfs.spec.in | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 1150101..00603ec 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -302,6 +302,9 @@ Obsoletes: %{name}-ufo + %if ( 0%{!?_with_gnfs:1} ) + Obsoletes: %{name}-gnfs + %endif ++%if ( 0%{?rhel} < 7 ) ++Obsoletes: %{name}-ganesha ++%endif + Provides: %{name}-common = %{version}-%{release} + Provides: %{name}-core = %{version}-%{release} + +@@ -452,7 +455,7 @@ is in user space and easily manageable. + This package provides support to FUSE based clients and inlcudes the + glusterfs(d) binary. + +-%if ( 0%{!?_without_server:1} ) ++%if ( 0%{!?_without_server:1} && 0%{?rhel} > 6 ) + %package ganesha + Summary: NFS-Ganesha configuration + Group: Applications/File +@@ -855,7 +858,7 @@ install -D -p -m 0644 extras/glusterfs-logrotate \ + %{buildroot}%{_sysconfdir}/logrotate.d/glusterfs + + # ganesha ghosts +-%if ( 0%{!?_without_server:1} ) ++%if ( 0%{!?_without_server:1} && 0%{?rhel} > 6 ) + mkdir -p %{buildroot}%{_sysconfdir}/ganesha + touch %{buildroot}%{_sysconfdir}/ganesha/ganesha-ha.conf + mkdir -p %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ +@@ -1165,11 +1168,14 @@ exit 0 + %endif + %endif + +-%if ( 0%{?_without_server:1} ) +-#exclude ganesha related files ++%if ( 0%{?_without_server:1} || 0%{?rhel} < 7 ) ++#exclude ganesha related files for rhel 6 and client builds + %exclude %{_sysconfdir}/ganesha/ganesha-ha.conf.sample + %exclude %{_libexecdir}/ganesha/* + %exclude %{_prefix}/lib/ocf/resource.d/heartbeat/* ++%if ( 0%{!?_without_server:1} ) ++%{_sharedstatedir}/glusterd/hooks/1/start/post/S31ganesha-start.sh ++%endif + %endif + + %exclude %{_datadir}/glusterfs/scripts/setup-thin-arbiter.sh +@@ -1324,7 +1330,7 @@ exit 0 + %exclude %{_datadir}/glusterfs/tests/vagrant + %endif + +-%if ( 0%{!?_without_server:1} ) ++%if ( 0%{!?_without_server:1} && 0%{?rhel} > 6 ) + %files ganesha + %dir %{_libexecdir}/ganesha + %{_sysconfdir}/ganesha/ganesha-ha.conf.sample +@@ -1936,6 +1942,9 @@ fi + %endif + + %changelog ++* Tue Jun 18 2019 Jiffin Tony Thottan ++- build glusterfs-ganesha for rhel 7 and above (#1720551) ++ + * Fri Jun 14 2019 Atin Mukherjee + - Ensure gluster-cli package is part of client build (#1720079) + +-- +1.8.3.1 + diff --git a/0196-posix-ctime-Fix-ctime-upgrade-issue.patch b/0196-posix-ctime-Fix-ctime-upgrade-issue.patch new file mode 100644 index 0000000..1a7b68d --- /dev/null +++ b/0196-posix-ctime-Fix-ctime-upgrade-issue.patch @@ -0,0 +1,384 @@ +From 584ee2dbb8158ee3d3c3f055f1b06ff3d9177192 Mon Sep 17 00:00:00 2001 +From: Kotresh HR +Date: Thu, 13 Jun 2019 16:23:21 +0530 +Subject: [PATCH 196/221] posix/ctime: Fix ctime upgrade issue + +Problem: +On a EC volume, during upgrade from the older version where +ctime feature is not enabled(or not present) to the newer +version where the ctime feature is available (enabled default), +the self heal hangs and doesn't complete. + +Cause: +The ctime feature has both client side code (utime) and +server side code (posix). The feature is driven from client. +Only if the client side sets the time in the frame, should +the server side sets the time attributes in xattr. But posix +setattr/fseattr was not doing that. When one of the server +nodes is updated, since ctime is enabled by default, it +starts setting xattr on setattr/fseattr on the updated node/brick. + +On a EC volume the first two updated nodes(bricks) are not a +problem because there are 4 other bricks with consistent data. +However once the third brick is updated, the new attribute(mdata xattr) +will cause an inconsistency on metadata on 3 bricks, which +prevents the file to be repaired. + +Fix: +Don't create mdata xattr with utimes/utimensat system call. +Only update if already present. + +Backport of: + > Patch: https://review.gluster.org/22858 + > Change-Id: Ieacedecb8a738bb437283ef3e0f042fd49dc4c8c + > fixes: bz#1720201 + > Signed-off-by: Kotresh HR + +Change-Id: Ieacedecb8a738bb437283ef3e0f042fd49dc4c8c +BUG: 1713664 +Signed-off-by: Kotresh HR +Reviewed-on: https://code.engineering.redhat.com/gerrit/174238 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + tests/basic/afr/split-brain-healing.t | 36 ++++--- + tests/utils/get-mdata-xattr.c | 152 +++++++++++++++++++++++++++++ + tests/volume.rc | 30 ++++++ + xlators/storage/posix/src/posix-metadata.c | 21 ++++ + 4 files changed, 223 insertions(+), 16 deletions(-) + create mode 100644 tests/utils/get-mdata-xattr.c + +diff --git a/tests/basic/afr/split-brain-healing.t b/tests/basic/afr/split-brain-healing.t +index c80f900..78553e6 100644 +--- a/tests/basic/afr/split-brain-healing.t ++++ b/tests/basic/afr/split-brain-healing.t +@@ -20,11 +20,14 @@ function get_replicate_subvol_number { + cleanup; + + AREQUAL_PATH=$(dirname $0)/../../utils ++GET_MDATA_PATH=$(dirname $0)/../../utils + CFLAGS="" + test "`uname -s`" != "Linux" && { + CFLAGS="$CFLAGS -lintl"; + } + build_tester $AREQUAL_PATH/arequal-checksum.c $CFLAGS ++build_tester $GET_MDATA_PATH/get-mdata-xattr.c ++ + TEST glusterd + TEST pidof glusterd + TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{1,2,3,4} +@@ -152,13 +155,13 @@ EXPECT $SMALLER_FILE_SIZE stat -c %s file4 + subvolume=$(get_replicate_subvol_number file5) + if [ $subvolume == 0 ] + then +- mtime1=$(stat -c %Y $B0/${V0}1/file5) +- mtime2=$(stat -c %Y $B0/${V0}2/file5) ++ mtime1=$(get_mtime $B0/${V0}1/file5) ++ mtime2=$(get_mtime $B0/${V0}2/file5) + LATEST_MTIME=$(($mtime1 > $mtime2 ? $mtime1:$mtime2)) + elif [ $subvolume == 1 ] + then +- mtime1=$(stat -c %Y $B0/${V0}3/file5) +- mtime2=$(stat -c %Y $B0/${V0}4/file5) ++ mtime1=$(get_mtime $B0/${V0}3/file5) ++ mtime2=$(get_mtime $B0/${V0}4/file5) + LATEST_MTIME=$(($mtime1 > $mtime2 ? $mtime1:$mtime2)) + fi + $CLI volume heal $V0 split-brain latest-mtime /file5 +@@ -166,12 +169,12 @@ EXPECT "0" echo $? + + if [ $subvolume == 0 ] + then +- mtime1_after_heal=$(stat -c %Y $B0/${V0}1/file5) +- mtime2_after_heal=$(stat -c %Y $B0/${V0}2/file5) ++ mtime1_after_heal=$(get_mtime $B0/${V0}1/file5) ++ mtime2_after_heal=$(get_mtime $B0/${V0}2/file5) + elif [ $subvolume == 1 ] + then +- mtime1_after_heal=$(stat -c %Y $B0/${V0}3/file5) +- mtime2_after_heal=$(stat -c %Y $B0/${V0}4/file5) ++ mtime1_after_heal=$(get_mtime $B0/${V0}3/file5) ++ mtime2_after_heal=$(get_mtime $B0/${V0}4/file5) + fi + + #TODO: To below comparisons on full sub-second resolution +@@ -188,14 +191,14 @@ subvolume=$(get_replicate_subvol_number file6) + if [ $subvolume == 0 ] + then + GFID=$(gf_get_gfid_xattr $B0/${V0}1/file6) +- mtime1=$(stat -c %Y $B0/${V0}1/file6) +- mtime2=$(stat -c %Y $B0/${V0}2/file6) ++ mtime1=$(get_mtime $B0/${V0}1/file6) ++ mtime2=$(get_mtime $B0/${V0}2/file6) + LATEST_MTIME=$(($mtime1 > $mtime2 ? $mtime1:$mtime2)) + elif [ $subvolume == 1 ] + then + GFID=$(gf_get_gfid_xattr $B0/${V0}3/file6) +- mtime1=$(stat -c %Y $B0/${V0}3/file6) +- mtime2=$(stat -c %Y $B0/${V0}4/file6) ++ mtime1=$(get_mtime $B0/${V0}3/file6) ++ mtime2=$(get_mtime $B0/${V0}4/file6) + LATEST_MTIME=$(($mtime1 > $mtime2 ? $mtime1:$mtime2)) + fi + GFIDSTR="gfid:$(gf_gfid_xattr_to_str $GFID)" +@@ -204,12 +207,12 @@ EXPECT "0" echo $? + + if [ $subvolume == 0 ] + then +- mtime1_after_heal=$(stat -c %Y $B0/${V0}1/file6) +- mtime2_after_heal=$(stat -c %Y $B0/${V0}2/file6) ++ mtime1_after_heal=$(get_mtime $B0/${V0}1/file6) ++ mtime2_after_heal=$(get_mtime $B0/${V0}2/file6) + elif [ $subvolume == 1 ] + then +- mtime1_after_heal=$(stat -c %Y $B0/${V0}3/file6) +- mtime2_after_heal=$(stat -c %Y $B0/${V0}4/file6) ++ mtime1_after_heal=$(get_mtime $B0/${V0}3/file6) ++ mtime2_after_heal=$(get_mtime $B0/${V0}4/file6) + fi + + #TODO: To below comparisons on full sub-second resolution +@@ -253,4 +256,5 @@ EXPECT "1" echo $? + + cd - + TEST rm $AREQUAL_PATH/arequal-checksum ++TEST rm $GET_MDATA_PATH/get-mdata-xattr + cleanup +diff --git a/tests/utils/get-mdata-xattr.c b/tests/utils/get-mdata-xattr.c +new file mode 100644 +index 0000000..e9f5471 +--- /dev/null ++++ b/tests/utils/get-mdata-xattr.c +@@ -0,0 +1,152 @@ ++/* ++ Copyright (c) 2019 Red Hat, Inc. ++ This file is part of GlusterFS. ++ ++ This file is licensed to you under your choice of the GNU Lesser ++ General Public License, version 3 or any later version (LGPLv3 or ++ later), or the GNU General Public License, version 2 (GPLv2), in all ++ cases as published by the Free Software Foundation. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++typedef struct gf_timespec_disk { ++ uint64_t tv_sec; ++ uint64_t tv_nsec; ++} gf_timespec_disk_t; ++ ++/* posix_mdata_t on disk structure */ ++typedef struct __attribute__((__packed__)) posix_mdata_disk { ++ /* version of structure, bumped up if any new member is added */ ++ uint8_t version; ++ /* flags indicates valid fields in the structure */ ++ uint64_t flags; ++ gf_timespec_disk_t ctime; ++ gf_timespec_disk_t mtime; ++ gf_timespec_disk_t atime; ++} posix_mdata_disk_t; ++ ++/* In memory representation posix metadata xattr */ ++typedef struct { ++ /* version of structure, bumped up if any new member is added */ ++ uint8_t version; ++ /* flags indicates valid fields in the structure */ ++ uint64_t flags; ++ struct timespec ctime; ++ struct timespec mtime; ++ struct timespec atime; ++} posix_mdata_t; ++ ++#define GF_XATTR_MDATA_KEY "trusted.glusterfs.mdata" ++ ++/* posix_mdata_from_disk converts posix_mdata_disk_t into host byte order ++ */ ++static inline void ++posix_mdata_from_disk(posix_mdata_t *out, posix_mdata_disk_t *in) ++{ ++ out->version = in->version; ++ out->flags = be64toh(in->flags); ++ ++ out->ctime.tv_sec = be64toh(in->ctime.tv_sec); ++ out->ctime.tv_nsec = be64toh(in->ctime.tv_nsec); ++ ++ out->mtime.tv_sec = be64toh(in->mtime.tv_sec); ++ out->mtime.tv_nsec = be64toh(in->mtime.tv_nsec); ++ ++ out->atime.tv_sec = be64toh(in->atime.tv_sec); ++ out->atime.tv_nsec = be64toh(in->atime.tv_nsec); ++} ++ ++/* posix_fetch_mdata_xattr fetches the posix_mdata_t from disk */ ++static int ++posix_fetch_mdata_xattr(const char *real_path, posix_mdata_t *metadata) ++{ ++ size_t size = -1; ++ char *value = NULL; ++ char gfid_str[64] = {0}; ++ ++ char *key = GF_XATTR_MDATA_KEY; ++ ++ if (!metadata || !real_path) { ++ goto err; ++ } ++ ++ /* Get size */ ++ size = lgetxattr(real_path, key, NULL, 0); ++ if (size == -1) { ++ goto err; ++ } ++ ++ value = calloc(size + 1, sizeof(char)); ++ if (!value) { ++ goto err; ++ } ++ ++ /* Get xattr value */ ++ size = lgetxattr(real_path, key, value, size); ++ if (size == -1) { ++ goto err; ++ } ++ posix_mdata_from_disk(metadata, (posix_mdata_disk_t *)value); ++ ++out: ++ if (value) ++ free(value); ++ return 0; ++err: ++ if (value) ++ free(value); ++ return -1; ++} ++ ++int ++main(int argc, char *argv[]) ++{ ++ posix_mdata_t metadata; ++ uint64_t result; ++ ++ if (argc != 3) { ++ /* ++ Usage: get_mdata_xattr -c|-m|-a ++ where -c --> ctime ++ -m --> mtime ++ -a --> atime ++ */ ++ printf("-1"); ++ goto err; ++ } ++ ++ if (posix_fetch_mdata_xattr(argv[2], &metadata)) { ++ printf("-1"); ++ goto err; ++ } ++ ++ switch (argv[1][1]) { ++ case 'c': ++ result = metadata.ctime.tv_sec; ++ break; ++ case 'm': ++ result = metadata.mtime.tv_sec; ++ break; ++ case 'a': ++ result = metadata.atime.tv_sec; ++ break; ++ default: ++ printf("-1"); ++ goto err; ++ } ++ printf("%" PRIu64, result); ++ fflush(stdout); ++ return 0; ++err: ++ fflush(stdout); ++ return -1; ++} +diff --git a/tests/volume.rc b/tests/volume.rc +index bb400cc..6a78c37 100644 +--- a/tests/volume.rc ++++ b/tests/volume.rc +@@ -927,3 +927,33 @@ function number_healer_threads_shd { + local pid=$(get_shd_mux_pid $1) + pstack $pid | grep $2 | wc -l + } ++ ++function get_mtime { ++ local time=$(get-mdata-xattr -m $1) ++ if [ $time == "-1" ]; ++ then ++ echo $(stat -c %Y $1) ++ else ++ echo $time ++ fi ++} ++ ++function get_ctime { ++ local time=$(get-mdata-xattr -c $1) ++ if [ $time == "-1" ]; ++ then ++ echo $(stat -c %Z $2) ++ else ++ echo $time ++ fi ++} ++ ++function get_atime { ++ local time=$(get-mdata-xattr -a $1) ++ if [ $time == "-1" ]; ++ then ++ echo $(stat -c %X $1) ++ else ++ echo $time ++ fi ++} +diff --git a/xlators/storage/posix/src/posix-metadata.c b/xlators/storage/posix/src/posix-metadata.c +index e96f222..5a5e6cd 100644 +--- a/xlators/storage/posix/src/posix-metadata.c ++++ b/xlators/storage/posix/src/posix-metadata.c +@@ -416,6 +416,22 @@ posix_set_mdata_xattr(xlator_t *this, const char *real_path, int fd, + * still fine as the times would get eventually + * accurate. + */ ++ ++ /* Don't create xattr with utimes/utimensat, only update if ++ * present. This otherwise causes issues during inservice ++ * upgrade. It causes inconsistent xattr values with in replica ++ * set. The scenario happens during upgrade where clients are ++ * older versions (without the ctime feature) and the server is ++ * upgraded to the new version (with the ctime feature which ++ * is enabled by default). ++ */ ++ ++ if (update_utime) { ++ UNLOCK(&inode->lock); ++ GF_FREE(mdata); ++ return 0; ++ } ++ + mdata->version = 1; + mdata->flags = 0; + mdata->ctime.tv_sec = time->tv_sec; +@@ -527,6 +543,11 @@ posix_update_utime_in_mdata(xlator_t *this, const char *real_path, int fd, + + priv = this->private; + ++ /* NOTE: ++ * This routine (utimes) is intentionally allowed for all internal and ++ * external clients even if ctime is not set. This is because AFR and ++ * WORM uses time attributes for it's internal operations ++ */ + if (inode && priv->ctime) { + if ((valid & GF_SET_ATTR_ATIME) == GF_SET_ATTR_ATIME) { + tv.tv_sec = stbuf->ia_atime; +-- +1.8.3.1 + diff --git a/0197-posix-fix-crash-in-posix_cs_set_state.patch b/0197-posix-fix-crash-in-posix_cs_set_state.patch new file mode 100644 index 0000000..c17e6c2 --- /dev/null +++ b/0197-posix-fix-crash-in-posix_cs_set_state.patch @@ -0,0 +1,71 @@ +From 58070aa568ffbaac267b02428e974b2459ae13b0 Mon Sep 17 00:00:00 2001 +From: Susant Palai +Date: Tue, 18 Jun 2019 16:43:43 +0530 +Subject: [PATCH 197/221] :posix: fix crash in posix_cs_set_state + +> Fixes: bz#1721474 +> Change-Id: Ic2a53fa3d1e9e23424c6898e0986f80d52c5e3f6 +> Signed-off-by: Susant Palai +(cherry-pick of https://review.gluster.org/#/c/glusterfs/+/22892/) + +BUG: 1721477 +Change-Id: Ic2a53fa3d1e9e23424c6898e0986f80d52c5e3f6 +Signed-off-by: Susant Palai +Reviewed-on: https://code.engineering.redhat.com/gerrit/173936 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + xlators/storage/posix/src/posix-helpers.c | 5 +++++ + xlators/storage/posix/src/posix-inode-fd-ops.c | 7 ++++--- + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c +index aecf4f8..849db3d 100644 +--- a/xlators/storage/posix/src/posix-helpers.c ++++ b/xlators/storage/posix/src/posix-helpers.c +@@ -3235,6 +3235,11 @@ posix_cs_set_state(xlator_t *this, dict_t **rsp, gf_cs_obj_state state, + char *value = NULL; + size_t xattrsize = 0; + ++ if (!rsp) { ++ ret = -1; ++ goto out; ++ } ++ + if (!(*rsp)) { + *rsp = dict_new(); + if (!(*rsp)) { +diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c +index 7ca4d26..b92c411 100644 +--- a/xlators/storage/posix/src/posix-inode-fd-ops.c ++++ b/xlators/storage/posix/src/posix-inode-fd-ops.c +@@ -1028,6 +1028,7 @@ posix_glfallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, + struct iatt statpost = { + 0, + }; ++ dict_t *rsp_xdata = NULL; + + #ifdef FALLOC_FL_KEEP_SIZE + if (keep_size) +@@ -1035,15 +1036,15 @@ posix_glfallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, + #endif /* FALLOC_FL_KEEP_SIZE */ + + ret = posix_do_fallocate(frame, this, fd, flags, offset, len, &statpre, +- &statpost, xdata, NULL); ++ &statpost, xdata, &rsp_xdata); + if (ret < 0) + goto err; + +- STACK_UNWIND_STRICT(fallocate, frame, 0, 0, &statpre, &statpost, NULL); ++ STACK_UNWIND_STRICT(fallocate, frame, 0, 0, &statpre, &statpost, rsp_xdata); + return 0; + + err: +- STACK_UNWIND_STRICT(fallocate, frame, -1, -ret, NULL, NULL, NULL); ++ STACK_UNWIND_STRICT(fallocate, frame, -1, -ret, NULL, NULL, rsp_xdata); + return 0; + } + +-- +1.8.3.1 + diff --git a/0198-cluster-ec-Prevent-double-pre-op-xattrops.patch b/0198-cluster-ec-Prevent-double-pre-op-xattrops.patch new file mode 100644 index 0000000..5e7c272 --- /dev/null +++ b/0198-cluster-ec-Prevent-double-pre-op-xattrops.patch @@ -0,0 +1,119 @@ +From 9912a432dc3493007462f76c5933d04a160814ae Mon Sep 17 00:00:00 2001 +From: Pranith Kumar K +Date: Thu, 20 Jun 2019 17:05:49 +0530 +Subject: [PATCH 198/221] cluster/ec: Prevent double pre-op xattrops + +Problem: +Race: +Thread-1 Thread-2 +1) Does ec_get_size_version() to perform +pre-op fxattrop as part of write-1 + 2) Calls ec_set_dirty_flag() in + ec_get_size_version() for write-2. + This sets dirty[] to 1 +3) Completes executing +ec_prepare_update_cbk leading to +ctx->dirty[] = '1' + 4) Takes LOCK(inode->lock) to check if there are + any flags and sets dirty-flag because + lock->waiting_flag is 0 now. This leads to + fxattrop to increment on-disk dirty[] to '2' + +At the end of the writes the file will be marked for heal even when it doesn't need heal. + +Fix: +Perform ec_set_dirty_flag() and other checks inside LOCK() to prevent dirty[] to be marked +as '1' in step 2) above + + > Upstream-patch: https://review.gluster.org/c/glusterfs/+/22907 + +fixes: bz#1600918 +Change-Id: Icac2ab39c0b1e7e154387800fbededc561612865 +Signed-off-by: Pranith Kumar K +Reviewed-on: https://code.engineering.redhat.com/gerrit/174385 +Reviewed-by: Atin Mukherjee +Tested-by: Atin Mukherjee +--- + tests/basic/ec/ec-dirty-flags.t | 23 +++++++++++++++++++++++ + xlators/cluster/ec/src/ec-common.c | 13 +++++++------ + 2 files changed, 30 insertions(+), 6 deletions(-) + create mode 100644 tests/basic/ec/ec-dirty-flags.t + +diff --git a/tests/basic/ec/ec-dirty-flags.t b/tests/basic/ec/ec-dirty-flags.t +new file mode 100644 +index 0000000..68e6610 +--- /dev/null ++++ b/tests/basic/ec/ec-dirty-flags.t +@@ -0,0 +1,23 @@ ++#!/bin/bash ++ ++. $(dirname $0)/../../include.rc ++. $(dirname $0)/../../volume.rc ++ ++# This checks if the fop keeps the dirty flags settings correctly after ++# finishing the fop. ++ ++cleanup ++TEST glusterd ++TEST pidof glusterd ++TEST $CLI volume create $V0 disperse 3 redundancy 1 $H0:$B0/${V0}{0..2} ++TEST $CLI volume heal $V0 disable ++TEST $CLI volume start $V0 ++ ++TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0; ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "3" ec_child_up_count $V0 0 ++cd $M0 ++for i in {1..1000}; do dd if=/dev/zero of=file-${i} bs=512k count=2; done ++cd - ++EXPECT "^0$" get_pending_heal_count $V0 ++ ++cleanup +diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c +index 9cc6395..35c2256 100644 +--- a/xlators/cluster/ec/src/ec-common.c ++++ b/xlators/cluster/ec/src/ec-common.c +@@ -1405,6 +1405,10 @@ ec_get_size_version(ec_lock_link_t *link) + !ec_is_data_fop(fop->id)) + link->optimistic_changelog = _gf_true; + ++ memset(&loc, 0, sizeof(loc)); ++ ++ LOCK(&lock->loc.inode->lock); ++ + set_dirty = ec_set_dirty_flag(link, ctx, dirty); + + /* If ec metadata has already been retrieved, do not try again. */ +@@ -1412,20 +1416,16 @@ ec_get_size_version(ec_lock_link_t *link) + if (ec_is_data_fop(fop->id)) { + fop->healing |= lock->healing; + } +- return; ++ goto unlock; + } + + /* Determine if there's something we need to retrieve for the current + * operation. */ + if (!set_dirty && !lock->query && (lock->loc.inode->ia_type != IA_IFREG) && + (lock->loc.inode->ia_type != IA_INVAL)) { +- return; ++ goto unlock; + } + +- memset(&loc, 0, sizeof(loc)); +- +- LOCK(&lock->loc.inode->lock); +- + changed_flags = ec_set_xattrop_flags_and_params(lock, link, dirty); + if (link->waiting_flags) { + /* This fop needs to wait until all its flags are cleared which +@@ -1436,6 +1436,7 @@ ec_get_size_version(ec_lock_link_t *link) + GF_ASSERT(!changed_flags); + } + ++unlock: + UNLOCK(&lock->loc.inode->lock); + + if (!changed_flags) +-- +1.8.3.1 + diff --git a/0199-upcall-Avoid-sending-notifications-for-invalid-inode.patch b/0199-upcall-Avoid-sending-notifications-for-invalid-inode.patch new file mode 100644 index 0000000..161675e --- /dev/null +++ b/0199-upcall-Avoid-sending-notifications-for-invalid-inode.patch @@ -0,0 +1,80 @@ +From e41b4a45f9f5c07ffa38582d0bb4517f6a66eaa3 Mon Sep 17 00:00:00 2001 +From: Soumya Koduri +Date: Fri, 7 Jun 2019 19:33:07 +0530 +Subject: [PATCH 199/221] upcall: Avoid sending notifications for invalid + inodes + +For nameless LOOKUPs, server creates a new inode which shall +remain invalid until the fop is successfully processed post +which it is linked to the inode table. + +But incase if there is an already linked inode for that entry, +it discards that newly created inode which results in upcall +notification. This may result in client being bombarded with +unnecessary upcalls affecting performance if the data set is huge. + +This issue can be avoided by looking up and storing the upcall +context in the original linked inode (if exists), thus saving up on +those extra callbacks. + +This is backport of below upstream fix - +mainline: https://review.gluster.org/22840 +release-6: https://review.gluster.org/22873 + +Change-Id: I044a1737819bb40d1a049d2f53c0566e746d2a17 +fixes: bz#1717784 +Signed-off-by: Soumya Koduri +Reviewed-on: https://code.engineering.redhat.com/gerrit/173507 +Tested-by: RHGS Build Bot +Reviewed-by: Kaleb Keithley +--- + xlators/features/upcall/src/upcall-internal.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/xlators/features/upcall/src/upcall-internal.c b/xlators/features/upcall/src/upcall-internal.c +index 46cf6f8..7998dd2 100644 +--- a/xlators/features/upcall/src/upcall-internal.c ++++ b/xlators/features/upcall/src/upcall-internal.c +@@ -520,6 +520,7 @@ upcall_cache_invalidate(call_frame_t *frame, xlator_t *this, client_t *client, + upcall_client_t *tmp = NULL; + upcall_inode_ctx_t *up_inode_ctx = NULL; + gf_boolean_t found = _gf_false; ++ inode_t *linked_inode = NULL; + + if (!is_upcall_enabled(this)) + return; +@@ -532,7 +533,20 @@ upcall_cache_invalidate(call_frame_t *frame, xlator_t *this, client_t *client, + return; + } + +- if (inode) ++ /* For nameless LOOKUPs, inode created shall always be ++ * invalid. Hence check if there is any already linked inode. ++ * If yes, update the inode_ctx of that valid inode ++ */ ++ if (inode && (inode->ia_type == IA_INVAL) && stbuf) { ++ linked_inode = inode_find(inode->table, stbuf->ia_gfid); ++ if (linked_inode) { ++ gf_log("upcall", GF_LOG_DEBUG, ++ "upcall_inode_ctx_get of linked inode (%p)", inode); ++ up_inode_ctx = upcall_inode_ctx_get(linked_inode, this); ++ } ++ } ++ ++ if (inode && !up_inode_ctx) + up_inode_ctx = upcall_inode_ctx_get(inode, this); + + if (!up_inode_ctx) { +@@ -600,6 +614,9 @@ upcall_cache_invalidate(call_frame_t *frame, xlator_t *this, client_t *client, + } + pthread_mutex_unlock(&up_inode_ctx->client_list_lock); + out: ++ /* release the ref from inode_find */ ++ if (linked_inode) ++ inode_unref(linked_inode); + return; + } + +-- +1.8.3.1 + diff --git a/0200-gfapi-fix-incorrect-initialization-of-upcall-syncop-.patch b/0200-gfapi-fix-incorrect-initialization-of-upcall-syncop-.patch new file mode 100644 index 0000000..ffef4d4 --- /dev/null +++ b/0200-gfapi-fix-incorrect-initialization-of-upcall-syncop-.patch @@ -0,0 +1,206 @@ +From bd553499909d2d57fd05696dc7604901cef3a36a Mon Sep 17 00:00:00 2001 +From: Soumya Koduri +Date: Fri, 7 Jun 2019 17:20:15 +0530 +Subject: [PATCH 200/221] gfapi: fix incorrect initialization of upcall syncop + arguments + +While sending upcall notifications via synctasks, the argument used to +carry relevant data for these tasks is not initialized properly. This patch +is to fix the same. + +This is backport of below upstream fix - +mainline: https://review.gluster.org/22839 +release-6: https://review.gluster.org/22871 + +Change-Id: I9fa8f841e71d3c37d3819fbd430382928c07176c +fixes: bz#1717784 +Signed-off-by: Soumya Koduri +Reviewed-on: https://code.engineering.redhat.com/gerrit/173508 +Tested-by: RHGS Build Bot +Reviewed-by: Kaleb Keithley +--- + api/src/glfs-fops.c | 109 ++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 72 insertions(+), 37 deletions(-) + +diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c +index 01ba60b..396f18c 100644 +--- a/api/src/glfs-fops.c ++++ b/api/src/glfs-fops.c +@@ -34,7 +34,7 @@ + + struct upcall_syncop_args { + struct glfs *fs; +- struct gf_upcall *upcall_data; ++ struct glfs_upcall *up_arg; + }; + + #define READDIRBUF_SIZE (sizeof(struct dirent) + GF_NAME_MAX + 1) +@@ -5714,12 +5714,28 @@ out: + } + + static int ++upcall_syncop_args_free(struct upcall_syncop_args *args) ++{ ++ if (args && args->up_arg) ++ GLFS_FREE(args->up_arg); ++ GF_FREE(args); ++ return 0; ++} ++ ++static int + glfs_upcall_syncop_cbk(int ret, call_frame_t *frame, void *opaque) + { + struct upcall_syncop_args *args = opaque; + +- GF_FREE(args->upcall_data); +- GF_FREE(args); ++ /* Here we not using upcall_syncop_args_free as application ++ * will be cleaning up the args->up_arg using glfs_free ++ * post processing upcall. ++ */ ++ if (ret) { ++ upcall_syncop_args_free(args); ++ } else ++ GF_FREE(args); ++ + return 0; + } + +@@ -5727,13 +5743,29 @@ static int + glfs_cbk_upcall_syncop(void *opaque) + { + struct upcall_syncop_args *args = opaque; +- int ret = -1; + struct glfs_upcall *up_arg = NULL; + struct glfs *fs; +- struct gf_upcall *upcall_data; + + fs = args->fs; +- upcall_data = args->upcall_data; ++ up_arg = args->up_arg; ++ ++ if (fs->up_cbk && up_arg) { ++ (fs->up_cbk)(up_arg, fs->up_data); ++ return 0; ++ } ++ ++ return -1; ++} ++ ++static struct upcall_syncop_args * ++upcall_syncop_args_init(struct glfs *fs, struct gf_upcall *upcall_data) ++{ ++ struct upcall_syncop_args *args = NULL; ++ int ret = -1; ++ struct glfs_upcall *up_arg = NULL; ++ ++ if (!fs || !upcall_data) ++ goto out; + + up_arg = GLFS_CALLOC(1, sizeof(struct gf_upcall), glfs_release_upcall, + glfs_mt_upcall_entry_t); +@@ -5754,33 +5786,51 @@ glfs_cbk_upcall_syncop(void *opaque) + errno = EINVAL; + } + +- if (!ret && (up_arg->reason != GLFS_UPCALL_EVENT_NULL)) { +- /* It could so happen that the file which got +- * upcall notification may have got deleted by +- * the same client. In such cases up_arg->reason +- * is set to GLFS_UPCALL_EVENT_NULL. No need to +- * send upcall then */ +- (fs->up_cbk)(up_arg, fs->up_data); +- } else if (up_arg->reason == GLFS_UPCALL_EVENT_NULL) { ++ /* It could so happen that the file which got ++ * upcall notification may have got deleted by ++ * the same client. In such cases up_arg->reason ++ * is set to GLFS_UPCALL_EVENT_NULL. No need to ++ * send upcall then ++ */ ++ if (up_arg->reason == GLFS_UPCALL_EVENT_NULL) { + gf_msg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_INVALID_ENTRY, + "Upcall_EVENT_NULL received. Skipping it."); + goto out; +- } else { ++ } else if (ret) { + gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ENTRY, + "Upcall entry validation failed."); + goto out; + } + ++ args = GF_CALLOC(1, sizeof(struct upcall_syncop_args), ++ glfs_mt_upcall_entry_t); ++ if (!args) { ++ gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, ++ "Upcall syncop args allocation failed."); ++ goto out; ++ } ++ ++ /* Note: we are not taking any ref on fs here. ++ * Ideally applications have to unregister for upcall events ++ * or stop polling for upcall events before performing ++ * glfs_fini. And as for outstanding synctasks created, we wait ++ * for all syncenv threads to finish tasks before cleaning up the ++ * fs->ctx. Hence it seems safe to process these callback ++ * notification without taking any lock/ref. ++ */ ++ args->fs = fs; ++ args->up_arg = up_arg; ++ + /* application takes care of calling glfs_free on up_arg post + * their processing */ +- ret = 0; + ++ return args; + out: +- if (ret && up_arg) { ++ if (up_arg) { + GLFS_FREE(up_arg); + } + +- return 0; ++ return NULL; + } + + static void +@@ -5797,24 +5847,10 @@ glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data) + goto out; + } + +- args = GF_CALLOC(1, sizeof(struct upcall_syncop_args), +- glfs_mt_upcall_entry_t); +- if (!args) { +- gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, +- "Upcall syncop args allocation failed."); +- goto out; +- } ++ args = upcall_syncop_args_init(fs, upcall_data); + +- /* Note: we are not taking any ref on fs here. +- * Ideally applications have to unregister for upcall events +- * or stop polling for upcall events before performing +- * glfs_fini. And as for outstanding synctasks created, we wait +- * for all syncenv threads to finish tasks before cleaning up the +- * fs->ctx. Hence it seems safe to process these callback +- * notification without taking any lock/ref. +- */ +- args->fs = fs; +- args->upcall_data = gf_memdup(upcall_data, sizeof(*upcall_data)); ++ if (!args) ++ goto out; + + ret = synctask_new(THIS->ctx->env, glfs_cbk_upcall_syncop, + glfs_upcall_syncop_cbk, NULL, args); +@@ -5823,8 +5859,7 @@ glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data) + gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_UPCALL_SYNCOP_FAILED, + "Synctak for Upcall event_type(%d) and gfid(%s) failed", + upcall_data->event_type, (char *)(upcall_data->gfid)); +- GF_FREE(args->upcall_data); +- GF_FREE(args); ++ upcall_syncop_args_free(args); + } + + out: +-- +1.8.3.1 + diff --git a/0201-geo-rep-Fix-permissions-for-GEOREP_DIR-in-non-root-s.patch b/0201-geo-rep-Fix-permissions-for-GEOREP_DIR-in-non-root-s.patch new file mode 100644 index 0000000..0884a87 --- /dev/null +++ b/0201-geo-rep-Fix-permissions-for-GEOREP_DIR-in-non-root-s.patch @@ -0,0 +1,44 @@ +From a61c2a81e5731e4e0b5136147f404e60d3c72ad0 Mon Sep 17 00:00:00 2001 +From: Sunny Kumar +Date: Tue, 18 Jun 2019 16:25:35 +0530 +Subject: [PATCH 201/221] geo-rep: Fix permissions for GEOREP_DIR in non-root + setup + +During mountbroker setup: 'gluster-mountbroker ' +commad to set the permission and group for GEOREP_DIR directory +(/var/lib/glusterd/geo-replication) fails due to extra argument, which is +enssential for non-root geo-rep setup. + +Backport of: + +>Updtream patch: https://review.gluster.org/#/c/glusterfs/+/22890/ +>fixes: bz#1721441 +>Change-Id: Ia83442733bf0b29f630e8c9e398097316efca092 +>Signed-off-by: Sunny Kumar + +BUG: bz#1722331 +Change-Id: Ia83442733bf0b29f630e8c9e398097316efca092 +Signed-off-by: Sunny Kumar +Reviewed-on: https://code.engineering.redhat.com/gerrit/174169 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + geo-replication/src/peer_mountbroker.py.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/geo-replication/src/peer_mountbroker.py.in b/geo-replication/src/peer_mountbroker.py.in +index ce33f97..96a7264 100644 +--- a/geo-replication/src/peer_mountbroker.py.in ++++ b/geo-replication/src/peer_mountbroker.py.in +@@ -197,7 +197,7 @@ class NodeSetup(Cmd): + execute(["chgrp", "-R", args.group, GEOREP_DIR]) + execute(["chgrp", "-R", args.group, LOG_DIR]) + execute(["chgrp", args.group, CLI_LOG]) +- execute(["chmod", "770", args.group, GEOREP_DIR]) ++ execute(["chmod", "770", GEOREP_DIR]) + execute(["find", LOG_DIR, "-type", "d", "-exec", "chmod", "770", "{}", + "+"]) + execute(["find", LOG_DIR, "-type", "f", "-exec", "chmod", "660", "{}", +-- +1.8.3.1 + diff --git a/0202-shd-mux-Fix-race-between-mux_proc-unlink-and-stop.patch b/0202-shd-mux-Fix-race-between-mux_proc-unlink-and-stop.patch new file mode 100644 index 0000000..7cadb24 --- /dev/null +++ b/0202-shd-mux-Fix-race-between-mux_proc-unlink-and-stop.patch @@ -0,0 +1,46 @@ +From e386fb4f4baf834e6a8fc25cc2fbbb17eb0a7a56 Mon Sep 17 00:00:00 2001 +From: Mohammed Rafi KC +Date: Thu, 20 Jun 2019 20:43:24 +0530 +Subject: [PATCH 202/221] shd/mux: Fix race between mux_proc unlink and stop + +There is a small race window, where we have a shd proc +without having a connection. That is when we stopped the +last shd running on a process. The list was removed +outside of a lock just after stopping the process. + +So there is a window where we stopped the process, but +the shd proc list contains the entry. + +Backport of: https://review.gluster.org/22909 + +>Change-Id: Id82a82509e5cd72acac24e8b7b87197626525441 +>fixes: bz#1722541 +>Signed-off-by: Mohammed Rafi KC + +Change-Id: I794131ede23f32fcfa5f71181149d8c1e7e439b8 +BUG: 1721802 +Signed-off-by: Mohammed Rafi KC +Reviewed-on: https://code.engineering.redhat.com/gerrit/174541 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + xlators/mgmt/glusterd/src/glusterd-shd-svc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c +index d81d760..dbe2560 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c ++++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c +@@ -694,6 +694,9 @@ glusterd_shdsvc_stop(glusterd_svc_t *svc, int sig) + gf_is_service_running(svc->proc.pidfile, &pid); + cds_list_del_init(&svc->mux_svc); + empty = cds_list_empty(&svc_proc->svcs); ++ if (empty) { ++ cds_list_del_init(&svc_proc->svc_proc_list); ++ } + } + pthread_mutex_unlock(&conf->attach_lock); + if (empty) { +-- +1.8.3.1 + diff --git a/0203-glusterd-shd-Change-shd-logfile-to-a-unique-name.patch b/0203-glusterd-shd-Change-shd-logfile-to-a-unique-name.patch new file mode 100644 index 0000000..39c9cd8 --- /dev/null +++ b/0203-glusterd-shd-Change-shd-logfile-to-a-unique-name.patch @@ -0,0 +1,233 @@ +From 541e1400ecaec5fea0f56e8ca18f00c229906d8a Mon Sep 17 00:00:00 2001 +From: Mohammed Rafi KC +Date: Tue, 18 Jun 2019 22:15:37 +0530 +Subject: [PATCH 203/221] glusterd/shd: Change shd logfile to a unique name + +With the shd mux changes, shd was havinga a logfile +with volname of the first started volume. + +This was creating a lot confusion, as other volumes data +is also logging to a logfile which has a different vol name. + +With this changes the logfile will be changed to a unique name +ie "/var/log/glusterfs/glustershd.log". This was the same +logfile name before the shd mux + +Backport of: https://review.gluster.org/22895 + +>Change-Id: I2b94c1f0b2cf3c9493505dddf873687755a46dda +>fixes: bz#1721601 +>Signed-off-by: Mohammed Rafi KC + +Change-Id: Ia659386dd19f533fbadaf5a9d5453c9ef2acac64 +BUG: 1721351 +Signed-off-by: Mohammed Rafi KC +Reviewed-on: https://code.engineering.redhat.com/gerrit/174542 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + .../mgmt/glusterd/src/glusterd-shd-svc-helper.c | 12 -------- + .../mgmt/glusterd/src/glusterd-shd-svc-helper.h | 6 ---- + xlators/mgmt/glusterd/src/glusterd-shd-svc.c | 14 ++++----- + xlators/mgmt/glusterd/src/glusterd-svc-helper.c | 34 +++++++++++++++++----- + xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c | 4 +-- + xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h | 4 +++ + 6 files changed, 40 insertions(+), 34 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.c b/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.c +index 9196758..57ceda9 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.c ++++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.c +@@ -75,18 +75,6 @@ glusterd_svc_build_shd_volfile_path(glusterd_volinfo_t *volinfo, char *path, + } + + void +-glusterd_svc_build_shd_logdir(char *logdir, char *volname, size_t len) +-{ +- snprintf(logdir, len, "%s/shd/%s", DEFAULT_LOG_FILE_DIRECTORY, volname); +-} +- +-void +-glusterd_svc_build_shd_logfile(char *logfile, char *logdir, size_t len) +-{ +- snprintf(logfile, len, "%s/shd.log", logdir); +-} +- +-void + glusterd_shd_svcproc_cleanup(glusterd_shdsvc_t *shd) + { + glusterd_svc_proc_t *svc_proc = NULL; +diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.h b/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.h +index c70702c..59466ec 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.h ++++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.h +@@ -27,12 +27,6 @@ glusterd_svc_build_shd_volfile_path(glusterd_volinfo_t *volinfo, char *path, + int path_len); + + void +-glusterd_svc_build_shd_logdir(char *logdir, char *volname, size_t len); +- +-void +-glusterd_svc_build_shd_logfile(char *logfile, char *logdir, size_t len); +- +-void + glusterd_shd_svcproc_cleanup(glusterd_shdsvc_t *shd); + + int +diff --git a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c +index dbe2560..8ad90a9 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-shd-svc.c ++++ b/xlators/mgmt/glusterd/src/glusterd-shd-svc.c +@@ -90,8 +90,8 @@ glusterd_shdsvc_init(void *data, glusterd_conn_t *mux_conn, + GLUSTERD_GET_SHD_RUNDIR(rundir, volinfo, priv); + glusterd_svc_create_rundir(rundir); + +- glusterd_svc_build_shd_logdir(logdir, volinfo->volname, sizeof(logdir)); +- glusterd_svc_build_shd_logfile(logfile, logdir, sizeof(logfile)); ++ glusterd_svc_build_logfile_path(shd_svc_name, DEFAULT_LOG_FILE_DIRECTORY, ++ logfile, sizeof(logfile)); + + /* Initialize the connection mgmt */ + if (mux_conn && mux_svc->rpc) { +@@ -104,7 +104,7 @@ glusterd_shdsvc_init(void *data, glusterd_conn_t *mux_conn, + if (ret < 0) + goto out; + } else { +- ret = mkdir_p(logdir, 0755, _gf_true); ++ ret = mkdir_p(DEFAULT_LOG_FILE_DIRECTORY, 0755, _gf_true); + if ((ret == -1) && (EEXIST != errno)) { + gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_CREATE_DIR_FAILED, + "Unable to create logdir %s", logdir); +@@ -460,6 +460,7 @@ glusterd_shdsvc_start(glusterd_svc_t *svc, int flags) + return -1; + + glusterd_volinfo_ref(volinfo); ++ + if (!svc->inited) { + ret = glusterd_shd_svc_mux_init(volinfo, svc); + if (ret) +@@ -471,12 +472,11 @@ glusterd_shdsvc_start(glusterd_svc_t *svc, int flags) + /* Unref will happen from glusterd_svc_attach_cbk */ + ret = glusterd_attach_svc(svc, volinfo, flags); + if (ret) { +- glusterd_volinfo_unref(volinfo); + gf_msg("glusterd", GF_LOG_ERROR, 0, GD_MSG_VOLINFO_GET_FAIL, +- "Failed to attach shd svc(volume=%s) to pid=%d. Starting" +- "a new process", ++ "Failed to attach shd svc(volume=%s) to pid=%d", + volinfo->volname, glusterd_proc_get_pid(&svc->proc)); +- ret = glusterd_recover_shd_attach_failure(volinfo, svc, flags); ++ glusterd_shd_svcproc_cleanup(&volinfo->shd); ++ glusterd_volinfo_unref(volinfo); + } + goto out; + } +diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-helper.c b/xlators/mgmt/glusterd/src/glusterd-svc-helper.c +index a6e662f..400826f 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-svc-helper.c ++++ b/xlators/mgmt/glusterd/src/glusterd-svc-helper.c +@@ -469,6 +469,9 @@ glusterd_shd_svc_mux_init(glusterd_volinfo_t *volinfo, glusterd_svc_t *svc) + glusterd_conf_t *conf = NULL; + glusterd_svc_t *parent_svc = NULL; + int pid = -1; ++ char pidfile[PATH_MAX] = { ++ 0, ++ }; + + GF_VALIDATE_OR_GOTO("glusterd", svc, out); + GF_VALIDATE_OR_GOTO("glusterd", volinfo, out); +@@ -478,8 +481,26 @@ glusterd_shd_svc_mux_init(glusterd_volinfo_t *volinfo, glusterd_svc_t *svc) + + pthread_mutex_lock(&conf->attach_lock); + { ++ if (svc->inited && !glusterd_proc_is_running(&(svc->proc))) { ++ /* This is the case when shd process was abnormally killed */ ++ pthread_mutex_unlock(&conf->attach_lock); ++ glusterd_shd_svcproc_cleanup(&volinfo->shd); ++ pthread_mutex_lock(&conf->attach_lock); ++ } ++ + if (!svc->inited) { +- if (gf_is_service_running(svc->proc.pidfile, &pid)) { ++ glusterd_svc_build_shd_pidfile(volinfo, pidfile, sizeof(pidfile)); ++ ret = snprintf(svc->proc.name, sizeof(svc->proc.name), "%s", ++ "glustershd"); ++ if (ret < 0) ++ goto unlock; ++ ++ ret = snprintf(svc->proc.pidfile, sizeof(svc->proc.pidfile), "%s", ++ pidfile); ++ if (ret < 0) ++ goto unlock; ++ ++ if (gf_is_service_running(pidfile, &pid)) { + /* Just connect is required, but we don't know what happens + * during the disconnect. So better to reattach. + */ +@@ -487,10 +508,10 @@ glusterd_shd_svc_mux_init(glusterd_volinfo_t *volinfo, glusterd_svc_t *svc) + } + + if (!mux_proc) { +- if (pid != -1 && sys_access(svc->proc.pidfile, R_OK) == 0) { ++ if (pid != -1 && sys_access(pidfile, R_OK) == 0) { + /* stale pid file, stop and unlink it */ + glusterd_proc_stop(&svc->proc, SIGTERM, PROC_STOP_FORCE); +- glusterd_unlink_file(svc->proc.pidfile); ++ glusterd_unlink_file(pidfile); + } + mux_proc = __gf_find_compatible_svc(GD_NODE_SHD); + } +@@ -684,11 +705,10 @@ glusterd_svc_attach_cbk(struct rpc_req *req, struct iovec *iov, int count, + volinfo->volname, glusterd_proc_get_pid(&svc->proc)); + } else { + gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_SVC_ATTACH_FAIL, +- "svc %s of volume %s failed to " +- "attach to pid %d. Starting a new process", +- svc->name, volinfo->volname, glusterd_proc_get_pid(&svc->proc)); ++ "svc %s of volume %s failed to attach to pid %d", svc->name, ++ volinfo->volname, glusterd_proc_get_pid(&svc->proc)); + if (!strcmp(svc->name, "glustershd")) { +- glusterd_recover_shd_attach_failure(volinfo, svc, *flag); ++ glusterd_shd_svcproc_cleanup(&volinfo->shd); + } + } + out: +diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c +index f32dafc..fa316a6 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c ++++ b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c +@@ -33,14 +33,14 @@ glusterd_svc_create_rundir(char *rundir) + return ret; + } + +-static void ++void + glusterd_svc_build_logfile_path(char *server, char *logdir, char *logfile, + size_t len) + { + snprintf(logfile, len, "%s/%s.log", logdir, server); + } + +-static void ++void + glusterd_svc_build_volfileid_path(char *server, char *volfileid, size_t len) + { + snprintf(volfileid, len, "gluster/%s", server); +diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h +index fbc5225..5a5466a 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h ++++ b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h +@@ -74,6 +74,10 @@ glusterd_svc_build_volfile_path(char *server, char *workdir, char *volfile, + size_t len); + + void ++glusterd_svc_build_logfile_path(char *server, char *logdir, char *logfile, ++ size_t len); ++ ++void + glusterd_svc_build_svcdir(char *server, char *workdir, char *path, size_t len); + + void +-- +1.8.3.1 + diff --git a/0204-glusterd-conditionally-clear-txn_opinfo-in-stage-op.patch b/0204-glusterd-conditionally-clear-txn_opinfo-in-stage-op.patch new file mode 100644 index 0000000..6d05a0b --- /dev/null +++ b/0204-glusterd-conditionally-clear-txn_opinfo-in-stage-op.patch @@ -0,0 +1,60 @@ +From 4d0b11088c4a3a630d71acf902064d1ed10412e8 Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Tue, 25 Jun 2019 11:11:10 +0530 +Subject: [PATCH 204/221] glusterd: conditionally clear txn_opinfo in stage op + +...otherwise this leads to a crash when volume status is run on a +heterogeneous mode. + +> upstream patch : https://review.gluster.org/#/c/glusterfs/+/22939/ + +>Fixes: bz#1723658 +>Change-Id: I0d39f412b2e5e9d3ef0a3462b90b38bb5364b09d +>Signed-off-by: Atin Mukherjee + +BUG: 1722131 +Change-Id: I0d39f412b2e5e9d3ef0a3462b90b38bb5364b09d +Signed-off-by: Atin Mukherjee +Reviewed-on: https://code.engineering.redhat.com/gerrit/174566 +Tested-by: RHGS Build Bot +--- + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index d0c1a2c..9ea695e 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -5714,9 +5714,14 @@ glusterd_op_ac_stage_op(glusterd_op_sm_event_t *event, void *ctx) + glusterd_op_info_t txn_op_info = { + {0}, + }; ++ glusterd_conf_t *priv = NULL; + + this = THIS; + GF_ASSERT(this); ++ ++ priv = this->private; ++ GF_ASSERT(priv); ++ + GF_ASSERT(ctx); + + req_ctx = ctx; +@@ -5768,9 +5773,12 @@ out: + gf_msg_debug(this->name, 0, "Returning with %d", ret); + + /* for no volname transactions, the txn_opinfo needs to be cleaned up +- * as there's no unlock event triggered ++ * as there's no unlock event triggered. However if the originator node of ++ * this transaction is still running with a version lower than 60000, ++ * txn_opinfo can't be cleared as that'll lead to a race of referring op_ctx ++ * after it's being freed. + */ +- if (txn_op_info.skip_locking) ++ if (txn_op_info.skip_locking && priv->op_version >= GD_OP_VERSION_6_0) + ret = glusterd_clear_txn_opinfo(txn_id); + + if (rsp_dict) +-- +1.8.3.1 + diff --git a/0205-glusterd-Can-t-run-rebalance-due-to-long-unix-socket.patch b/0205-glusterd-Can-t-run-rebalance-due-to-long-unix-socket.patch new file mode 100644 index 0000000..2b23236 --- /dev/null +++ b/0205-glusterd-Can-t-run-rebalance-due-to-long-unix-socket.patch @@ -0,0 +1,195 @@ +From b1a4947e382c5e2ba1137ed606ecffc69fcf00e9 Mon Sep 17 00:00:00 2001 +From: Mohit Agrawal +Date: Tue, 25 Jun 2019 17:30:17 +0530 +Subject: [PATCH 205/221] glusterd: Can't run rebalance due to long unix socket + +Problem: glusterd populate unix socket file name based + on volname and if volname is lengthy socket + system call's are failed due to breach maximum length + is defined in the kernel. + +Solution:Convert unix socket name to hash to resolve the issue + +> Change-Id: I5072e8184013095587537dbfa4767286307fff65 +> fixes: bz#1720566 +> (Cherry pick from commit 2d7b77eb971700c1073db2b74f5877c1ae8293fc) +> (Reviewed on upstream link https://review.gluster.org/#/c/glusterfs/+/22869/) + +BUG: 1720192 +Change-Id: I5072e8184013095587537dbfa4767286307fff65 +Signed-off-by: Mohit Agrawal +Reviewed-on: https://code.engineering.redhat.com/gerrit/174557 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + tests/bugs/glusterd/bug-1720566.t | 50 ++++++++++++++++++++++++++ + xlators/mgmt/glusterd/src/glusterd-rebalance.c | 38 +------------------- + xlators/mgmt/glusterd/src/glusterd.h | 23 +++++------- + 3 files changed, 59 insertions(+), 52 deletions(-) + create mode 100644 tests/bugs/glusterd/bug-1720566.t + +diff --git a/tests/bugs/glusterd/bug-1720566.t b/tests/bugs/glusterd/bug-1720566.t +new file mode 100644 +index 0000000..99bcf6f +--- /dev/null ++++ b/tests/bugs/glusterd/bug-1720566.t +@@ -0,0 +1,50 @@ ++#!/bin/bash ++ ++. $(dirname $0)/../../include.rc ++. $(dirname $0)/../../cluster.rc ++. $(dirname $0)/../../volume.rc ++ ++ ++cleanup; ++V0="TestLongVolnamec363b7b536700ff06eedeae0dd9037fec363b7b536700ff06eedeae0dd9037fec363b7b536700ff06eedeae0dd9abcd" ++V1="TestLongVolname3102bd28a16c49440bd5210e4ec4d5d93102bd28a16c49440bd5210e4ec4d5d933102bd28a16c49440bd5210e4ebbcd" ++TEST launch_cluster 2; ++TEST $CLI_1 peer probe $H2; ++ ++EXPECT_WITHIN $PROBE_TIMEOUT 1 peer_count ++ ++$CLI_1 volume create $V0 $H1:$B1/$V0 $H2:$B2/$V0 ++EXPECT 'Created' cluster_volinfo_field 1 $V0 'Status'; ++$CLI_1 volume create $V1 $H1:$B1/$V1 $H2:$B2/$V1 ++EXPECT 'Created' cluster_volinfo_field 1 $V1 'Status'; ++ ++$CLI_1 volume start $V0 ++EXPECT 'Started' cluster_volinfo_field 1 $V0 'Status'; ++ ++$CLI_1 volume start $V1 ++EXPECT 'Started' cluster_volinfo_field 1 $V1 'Status'; ++ ++#Mount FUSE ++TEST glusterfs -s $H1 --volfile-id=$V0 $M0; ++ ++ ++#Mount FUSE ++TEST glusterfs -s $H1 --volfile-id=$V1 $M1; ++ ++TEST mkdir $M0/dir{1..4}; ++TEST touch $M0/dir{1..4}/files{1..4}; ++ ++TEST mkdir $M1/dir{1..4}; ++TEST touch $M1/dir{1..4}/files{1..4}; ++ ++TEST $CLI_1 volume add-brick $V0 $H1:$B1/${V0}_1 $H2:$B2/${V0}_1 ++TEST $CLI_1 volume add-brick $V1 $H1:$B1/${V1}_1 $H2:$B2/${V1}_1 ++ ++ ++TEST $CLI_1 volume rebalance $V0 start ++TEST $CLI_1 volume rebalance $V1 start ++ ++EXPECT_WITHIN $REBALANCE_TIMEOUT "completed" cluster_rebalance_status_field 1 $V0 ++EXPECT_WITHIN $REBALANCE_TIMEOUT "completed" cluster_rebalance_status_field 1 $V1 ++ ++cleanup; +diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c +index cbed9a9..b419a89 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c ++++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c +@@ -266,18 +266,7 @@ glusterd_handle_defrag_start(glusterd_volinfo_t *volinfo, char *op_errstr, + + if (dict_get_strn(this->options, "transport.socket.bind-address", + SLEN("transport.socket.bind-address"), +- &volfileserver) == 0) { +- /*In the case of running multiple glusterds on a single machine, +- *we should ensure that log file and unix socket file should be +- *unique in given cluster */ +- +- GLUSTERD_GET_DEFRAG_SOCK_FILE_OLD(sockfile, volinfo, priv); +- snprintf(logfile, PATH_MAX, "%s/%s-%s-%s.log", +- DEFAULT_LOG_FILE_DIRECTORY, volinfo->volname, +- (cmd == GF_DEFRAG_CMD_START_TIER ? "tier" : "rebalance"), +- uuid_utoa(MY_UUID)); +- +- } else { ++ &volfileserver) != 0) { + volfileserver = "localhost"; + } + +@@ -378,9 +367,6 @@ glusterd_rebalance_rpc_create(glusterd_volinfo_t *volinfo) + glusterd_defrag_info_t *defrag = volinfo->rebal.defrag; + glusterd_conf_t *priv = NULL; + xlator_t *this = NULL; +- struct stat buf = { +- 0, +- }; + + this = THIS; + GF_ASSERT(this); +@@ -396,28 +382,6 @@ glusterd_rebalance_rpc_create(glusterd_volinfo_t *volinfo) + goto out; + + GLUSTERD_GET_DEFRAG_SOCK_FILE(sockfile, volinfo); +- /* Check if defrag sockfile exists in the new location +- * in /var/run/ , if it does not try the old location +- */ +- ret = sys_stat(sockfile, &buf); +- /* TODO: Remove this once we don't need backward compatibility +- * with the older path +- */ +- if (ret && (errno == ENOENT)) { +- gf_msg(this->name, GF_LOG_WARNING, errno, GD_MSG_FILE_OP_FAILED, +- "Rebalance sockfile " +- "%s does not exist. Trying old path.", +- sockfile); +- GLUSTERD_GET_DEFRAG_SOCK_FILE_OLD(sockfile, volinfo, priv); +- ret = sys_stat(sockfile, &buf); +- if (ret && (ENOENT == errno)) { +- gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_REBAL_NO_SOCK_FILE, +- "Rebalance " +- "sockfile %s does not exist", +- sockfile); +- goto out; +- } +- } + + /* Setting frame-timeout to 10mins (600seconds). + * Unix domain sockets ensures that the connection is reliable. The +diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h +index f96bca3..7d07d33 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.h ++++ b/xlators/mgmt/glusterd/src/glusterd.h +@@ -910,30 +910,23 @@ typedef ssize_t (*gd_serialize_t)(struct iovec outmsg, void *args); + } \ + } while (0) + +-#define GLUSTERD_GET_DEFRAG_SOCK_FILE_OLD(path, volinfo, priv) \ +- do { \ +- char defrag_path[PATH_MAX]; \ +- int32_t _sockfile_old_len; \ +- GLUSTERD_GET_DEFRAG_DIR(defrag_path, volinfo, priv); \ +- _sockfile_old_len = snprintf(path, PATH_MAX, "%s/%s.sock", \ +- defrag_path, uuid_utoa(MY_UUID)); \ +- if ((_sockfile_old_len < 0) || (_sockfile_old_len >= PATH_MAX)) { \ +- path[0] = 0; \ +- } \ +- } while (0) +- + #define GLUSTERD_GET_DEFRAG_SOCK_FILE(path, volinfo) \ + do { \ + char operation[NAME_MAX]; \ ++ char tmppath[PATH_MAX] = { \ ++ 0, \ ++ }; \ + int32_t _defrag_sockfile_len; \ + GLUSTERD_GET_DEFRAG_PROCESS(operation, volinfo); \ + _defrag_sockfile_len = snprintf( \ +- path, UNIX_PATH_MAX, \ +- DEFAULT_VAR_RUN_DIRECTORY "/gluster-%s-%s.sock", operation, \ +- uuid_utoa(volinfo->volume_id)); \ ++ tmppath, PATH_MAX, \ ++ DEFAULT_VAR_RUN_DIRECTORY "/gluster-%s-%s-%s.sock", operation, \ ++ volinfo->volname, uuid_utoa(MY_UUID)); \ + if ((_defrag_sockfile_len < 0) || \ + (_defrag_sockfile_len >= PATH_MAX)) { \ + path[0] = 0; \ ++ } else { \ ++ glusterd_set_socket_filepath(tmppath, path, sizeof(path)); \ + } \ + } while (0) + +-- +1.8.3.1 + diff --git a/0206-glusterd-ignore-user.-options-from-compatibility-che.patch b/0206-glusterd-ignore-user.-options-from-compatibility-che.patch new file mode 100644 index 0000000..8908097 --- /dev/null +++ b/0206-glusterd-ignore-user.-options-from-compatibility-che.patch @@ -0,0 +1,41 @@ +From f77d4a024cb9b17de7d5add064b34adfb0455d17 Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Mon, 24 Jun 2019 18:32:52 +0530 +Subject: [PATCH 206/221] glusterd: ignore user.* options from compatibility + check in brick mux + +user.* options are just custom and they don't contribute anything in +terms of determining the volume compatibility in brick multiplexing + +> upstream patch : https://review.gluster.org/#/c/glusterfs/+/22933/ + +>Fixes: bz#1723402 +>Change-Id: Ic7e0181ab72993d29cab345cde64ae1340bf4faf +>Signed-off-by: Atin Mukherjee + +BUG: 1722509 +Change-Id: Ic7e0181ab72993d29cab345cde64ae1340bf4faf +Signed-off-by: Atin Mukherjee +Reviewed-on: https://code.engineering.redhat.com/gerrit/174589 +Tested-by: RHGS Build Bot +--- + xlators/mgmt/glusterd/src/glusterd-utils.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c +index 7768b8e..c6e9bb0 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-utils.c +@@ -2425,6 +2425,9 @@ unsafe_option(dict_t *this, char *key, data_t *value, void *arg) + if (fnmatch("*diagnostics.client-log*", key, 0) == 0) { + return _gf_false; + } ++ if (fnmatch("user.*", key, 0) == 0) { ++ return _gf_false; ++ } + + return _gf_true; + } +-- +1.8.3.1 + diff --git a/0207-glusterd-fix-use-after-free-of-a-dict_t.patch b/0207-glusterd-fix-use-after-free-of-a-dict_t.patch new file mode 100644 index 0000000..5a92d58 --- /dev/null +++ b/0207-glusterd-fix-use-after-free-of-a-dict_t.patch @@ -0,0 +1,44 @@ +From a7a7d497af4230430f8a0cc54d8b49cfea260039 Mon Sep 17 00:00:00 2001 +From: Xavi Hernandez +Date: Tue, 25 Jun 2019 18:00:06 +0200 +Subject: [PATCH 207/221] glusterd: fix use-after-free of a dict_t + +A dict was passed to a function that calls dict_unref() without taking +any additional reference. Given that the same dict is also used after +the function returns, this was causing a use-after-free situation. + +To fix the issue, we simply take an additional reference before calling +the function. + +Upstream patch: +> BUG: 1723890 +> Upstream patch link: https://review.gluster.org/c/glusterfs/+/22943 +> Change-Id: I98c6b76b08fe3fa6224edf281a26e9ba1ffe3017 +> Signed-off-by: Xavi Hernandez + +Change-Id: I98c6b76b08fe3fa6224edf281a26e9ba1ffe3017 +Updates: bz#1722801 +Signed-off-by: Xavi Hernandez +Reviewed-on: https://code.engineering.redhat.com/gerrit/174656 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + xlators/mgmt/glusterd/src/glusterd-utils.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c +index c6e9bb0..4c487d0 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-utils.c +@@ -3697,7 +3697,7 @@ glusterd_add_volumes_to_export_dict(dict_t *peer_data, char **buf, + if (totthread) { + gf_log(this->name, GF_LOG_INFO, + "Finished merger of all dictionraies into single one"); +- dict_arr[totthread++] = peer_data; ++ dict_arr[totthread++] = dict_ref(peer_data); + ret = glusterd_dict_arr_serialize(dict_arr, totthread, buf, length); + gf_log(this->name, GF_LOG_INFO, + "Serialize dictionary data return is %d", ret); +-- +1.8.3.1 + diff --git a/0208-mem-pool-remove-dead-code.patch b/0208-mem-pool-remove-dead-code.patch new file mode 100644 index 0000000..c8678f2 --- /dev/null +++ b/0208-mem-pool-remove-dead-code.patch @@ -0,0 +1,161 @@ +From d7ddc1cd3af86198ffca2d1958871d4c2c04bd9e Mon Sep 17 00:00:00 2001 +From: Yaniv Kaul +Date: Thu, 21 Mar 2019 19:51:30 +0200 +Subject: [PATCH 208/221] mem-pool: remove dead code. + +Upstream patch: +> Change-Id: I3bbda719027b45e1289db2e6a718627141bcbdc8 +> Upstream patch link: https://review.gluster.org/c/glusterfs/+/22394 +> BUG: 1193929 +> Signed-off-by: Yaniv Kaul + +Updates: bz#1722801 +Change-Id: I3bbda719027b45e1289db2e6a718627141bcbdc8 +Signed-off-by: Yaniv Kaul +Reviewed-on: https://code.engineering.redhat.com/gerrit/174710 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + libglusterfs/src/glusterfs/mem-pool.h | 11 ------ + libglusterfs/src/mem-pool.c | 70 ----------------------------------- + 2 files changed, 81 deletions(-) + +diff --git a/libglusterfs/src/glusterfs/mem-pool.h b/libglusterfs/src/glusterfs/mem-pool.h +index 90905fb..0250b59 100644 +--- a/libglusterfs/src/glusterfs/mem-pool.h ++++ b/libglusterfs/src/glusterfs/mem-pool.h +@@ -308,15 +308,4 @@ mem_pool_destroy(struct mem_pool *pool); + void + gf_mem_acct_enable_set(void *ctx); + +-/* hit will be set to : +- * _gf_true if the memory is served from mem pool +- * _gf_false if the requested size was not present in mem pool and hence +- * std alloc'd. +- */ +-void * +-mem_pool_get(unsigned long sizeof_type, gf_boolean_t *hit); +- +-void * +-mem_pool_get0(unsigned long sizeof_type, gf_boolean_t *hit); +- + #endif /* _MEM_POOL_H */ +diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c +index 3934a78..9b4ea52 100644 +--- a/libglusterfs/src/mem-pool.c ++++ b/libglusterfs/src/mem-pool.c +@@ -365,10 +365,6 @@ static size_t pool_list_size; + #define N_COLD_LISTS 1024 + #define POOL_SWEEP_SECS 30 + +-static unsigned long sweep_times; +-static unsigned long sweep_usecs; +-static unsigned long frees_to_system; +- + typedef struct { + struct list_head death_row; + pooled_obj_hdr_t *cold_lists[N_COLD_LISTS]; +@@ -426,7 +422,6 @@ free_obj_list(pooled_obj_hdr_t *victim) + next = victim->next; + free(victim); + victim = next; +- ++frees_to_system; + } + } + +@@ -438,9 +433,6 @@ pool_sweeper(void *arg) + per_thread_pool_list_t *next_pl; + per_thread_pool_t *pt_pool; + unsigned int i; +- struct timeval begin_time; +- struct timeval end_time; +- struct timeval elapsed; + gf_boolean_t poisoned; + + /* +@@ -457,7 +449,6 @@ pool_sweeper(void *arg) + state.n_cold_lists = 0; + + /* First pass: collect stuff that needs our attention. */ +- (void)gettimeofday(&begin_time, NULL); + (void)pthread_mutex_lock(&pool_lock); + list_for_each_entry_safe(pool_list, next_pl, &pool_threads, thr_list) + { +@@ -470,10 +461,6 @@ pool_sweeper(void *arg) + } + } + (void)pthread_mutex_unlock(&pool_lock); +- (void)gettimeofday(&end_time, NULL); +- timersub(&end_time, &begin_time, &elapsed); +- sweep_usecs += elapsed.tv_sec * 1000000 + elapsed.tv_usec; +- sweep_times += 1; + + /* Second pass: free dead pools. */ + (void)pthread_mutex_lock(&pool_free_lock); +@@ -879,63 +866,6 @@ mem_get(struct mem_pool *mem_pool) + #endif /* GF_DISABLE_MEMPOOL */ + } + +-void * +-mem_pool_get(unsigned long sizeof_type, gf_boolean_t *hit) +-{ +-#if defined(GF_DISABLE_MEMPOOL) +- return GF_MALLOC(sizeof_type, gf_common_mt_mem_pool); +-#else +- pooled_obj_hdr_t *retval; +- unsigned int power; +- struct mem_pool_shared *pool = NULL; +- +- if (!sizeof_type) { +- gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, +- "invalid argument"); +- return NULL; +- } +- +- /* We ensure sizeof_type > 1 and the next power of two will be, at least, +- * 2^POOL_SMALLEST */ +- sizeof_type |= (1 << POOL_SMALLEST) - 1; +- power = sizeof(sizeof_type) * 8 - __builtin_clzl(sizeof_type - 1) + 1; +- if (power > POOL_LARGEST) { +- gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, +- "invalid argument"); +- return NULL; +- } +- pool = &pools[power - POOL_SMALLEST]; +- +- retval = mem_get_from_pool(NULL, pool, hit); +- +- return retval + 1; +-#endif /* GF_DISABLE_MEMPOOL */ +-} +- +-void * +-mem_pool_get0(unsigned long sizeof_type, gf_boolean_t *hit) +-{ +- void *ptr = NULL; +- unsigned int power; +- struct mem_pool_shared *pool = NULL; +- +- ptr = mem_pool_get(sizeof_type, hit); +- if (ptr) { +-#if defined(GF_DISABLE_MEMPOOL) +- memset(ptr, 0, sizeof_type); +-#else +- /* We ensure sizeof_type > 1 and the next power of two will be, at +- * least, 2^POOL_SMALLEST */ +- sizeof_type |= (1 << POOL_SMALLEST) - 1; +- power = sizeof(sizeof_type) * 8 - __builtin_clzl(sizeof_type - 1) + 1; +- pool = &pools[power - POOL_SMALLEST]; +- memset(ptr, 0, AVAILABLE_SIZE(pool->power_of_two)); +-#endif +- } +- +- return ptr; +-} +- + void + mem_put(void *ptr) + { +-- +1.8.3.1 + diff --git a/0209-core-avoid-dynamic-TLS-allocation-when-possible.patch b/0209-core-avoid-dynamic-TLS-allocation-when-possible.patch new file mode 100644 index 0000000..f46f1b6 --- /dev/null +++ b/0209-core-avoid-dynamic-TLS-allocation-when-possible.patch @@ -0,0 +1,1059 @@ +From 2f5969a77493814e242e6bac3c6bf7acf3202e0f Mon Sep 17 00:00:00 2001 +From: Xavi Hernandez +Date: Tue, 5 Mar 2019 18:58:20 +0100 +Subject: [PATCH 209/221] core: avoid dynamic TLS allocation when possible + +Some interdependencies between logging and memory management functions +make it impossible to use the logging framework before initializing +memory subsystem because they both depend on Thread Local Storage +allocated through pthread_key_create() during initialization. + +This causes a crash when we try to log something very early in the +initialization phase. + +To prevent this, several dynamically allocated TLS structures have +been replaced by static TLS reserved at compile time using '__thread' +keyword. This also reduces the number of error sources, making +initialization simpler. + +Upstream patch: +> BUG: 1193929 +> Upstream patch link: https://review.gluster.org/c/glusterfs/+/22302 +> Change-Id: I8ea2e072411e30790d50084b6b7e909c7bb01d50 +> Signed-off-by: Xavi Hernandez + +Change-Id: I8ea2e072411e30790d50084b6b7e909c7bb01d50 +Updates: bz#1722801 +Signed-off-by: Xavi Hernandez +Reviewed-on: https://code.engineering.redhat.com/gerrit/174711 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + api/src/glfs.c | 3 +- + cli/src/cli.c | 3 +- + glusterfsd/src/glusterfsd.c | 4 +- + libglusterfs/src/globals.c | 289 ++++----------------- + libglusterfs/src/glusterfs/globals.h | 6 +- + libglusterfs/src/glusterfs/mem-pool.h | 7 +- + libglusterfs/src/libglusterfs.sym | 3 +- + libglusterfs/src/mem-pool.c | 98 +++---- + libglusterfs/src/syncop.c | 133 ++-------- + .../changelog/lib/src/gf-changelog-helpers.c | 51 +--- + xlators/features/changelog/lib/src/gf-changelog.c | 3 +- + xlators/nfs/server/src/mount3udp_svc.c | 6 +- + 12 files changed, 114 insertions(+), 492 deletions(-) + +diff --git a/api/src/glfs.c b/api/src/glfs.c +index 6bbb620..f36616d 100644 +--- a/api/src/glfs.c ++++ b/api/src/glfs.c +@@ -829,8 +829,7 @@ pub_glfs_new(const char *volname) + * Do this as soon as possible in case something else depends on + * pool allocations. + */ +- mem_pools_init_early(); +- mem_pools_init_late(); ++ mem_pools_init(); + + fs = glfs_new_fs(volname); + if (!fs) +diff --git a/cli/src/cli.c b/cli/src/cli.c +index ff39a98..99a16a0 100644 +--- a/cli/src/cli.c ++++ b/cli/src/cli.c +@@ -795,8 +795,7 @@ main(int argc, char *argv[]) + int ret = -1; + glusterfs_ctx_t *ctx = NULL; + +- mem_pools_init_early(); +- mem_pools_init_late(); ++ mem_pools_init(); + + ctx = glusterfs_ctx_new(); + if (!ctx) +diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c +index 6aee4c1..2172af4 100644 +--- a/glusterfsd/src/glusterfsd.c ++++ b/glusterfsd/src/glusterfsd.c +@@ -2722,8 +2722,6 @@ main(int argc, char *argv[]) + }; + cmd_args_t *cmd = NULL; + +- mem_pools_init_early(); +- + gf_check_and_set_mem_acct(argc, argv); + + ctx = glusterfs_ctx_new(); +@@ -2838,7 +2836,7 @@ main(int argc, char *argv[]) + * the parent, but we want to do it as soon as possible after that in + * case something else depends on pool allocations. + */ +- mem_pools_init_late(); ++ mem_pools_init(); + + #ifdef GF_LINUX_HOST_OS + ret = set_oom_score_adj(ctx); +diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c +index 4fec063..02098e6 100644 +--- a/libglusterfs/src/globals.c ++++ b/libglusterfs/src/globals.c +@@ -99,16 +99,19 @@ const char *gf_upcall_list[GF_UPCALL_FLAGS_MAXVALUE] = { + glusterfs_ctx_t *global_ctx = NULL; + pthread_mutex_t global_ctx_mutex = PTHREAD_MUTEX_INITIALIZER; + xlator_t global_xlator; +-static pthread_key_t this_xlator_key; +-static pthread_key_t synctask_key; +-static pthread_key_t uuid_buf_key; +-static char global_uuid_buf[GF_UUID_BUF_SIZE]; +-static pthread_key_t lkowner_buf_key; +-static char global_lkowner_buf[GF_LKOWNER_BUF_SIZE]; +-static pthread_key_t leaseid_buf_key; + static int gf_global_mem_acct_enable = 1; + static pthread_once_t globals_inited = PTHREAD_ONCE_INIT; + ++static pthread_key_t free_key; ++ ++static __thread xlator_t *thread_xlator = NULL; ++static __thread void *thread_synctask = NULL; ++static __thread void *thread_leaseid = NULL; ++static __thread struct syncopctx thread_syncopctx = {}; ++static __thread char thread_uuid_buf[GF_UUID_BUF_SIZE] = {}; ++static __thread char thread_lkowner_buf[GF_LKOWNER_BUF_SIZE] = {}; ++static __thread char thread_leaseid_buf[GF_LEASE_ID_BUF_SIZE] = {}; ++ + int + gf_global_mem_acct_enable_get(void) + { +@@ -122,12 +125,6 @@ gf_global_mem_acct_enable_set(int val) + return 0; + } + +-void +-glusterfs_this_destroy(void *ptr) +-{ +- FREE(ptr); +-} +- + static struct xlator_cbks global_cbks = { + .forget = NULL, + .release = NULL, +@@ -212,18 +209,9 @@ struct volume_options global_xl_options[] = { + + static volume_opt_list_t global_xl_opt_list; + +-int ++void + glusterfs_this_init() + { +- int ret = 0; +- ret = pthread_key_create(&this_xlator_key, glusterfs_this_destroy); +- if (ret != 0) { +- gf_msg("", GF_LOG_WARNING, ret, LG_MSG_PTHREAD_KEY_CREATE_FAILED, +- "failed to create " +- "the pthread key"); +- return ret; +- } +- + global_xlator.name = "glusterfs"; + global_xlator.type = GF_GLOBAL_XLATOR_NAME; + global_xlator.cbks = &global_cbks; +@@ -237,301 +225,120 @@ glusterfs_this_init() + global_xl_opt_list.given_opt = global_xl_options; + + list_add_tail(&global_xl_opt_list.list, &global_xlator.volume_options); +- +- return ret; + } + + xlator_t ** + __glusterfs_this_location() + { +- xlator_t **this_location = NULL; +- int ret = 0; +- +- this_location = pthread_getspecific(this_xlator_key); +- +- if (!this_location) { +- this_location = CALLOC(1, sizeof(*this_location)); +- if (!this_location) +- goto out; ++ xlator_t **this_location; + +- ret = pthread_setspecific(this_xlator_key, this_location); +- if (ret != 0) { +- FREE(this_location); +- this_location = NULL; +- goto out; +- } +- } +-out: +- if (this_location) { +- if (!*this_location) +- *this_location = &global_xlator; ++ this_location = &thread_xlator; ++ if (*this_location == NULL) { ++ thread_xlator = &global_xlator; + } ++ + return this_location; + } + + xlator_t * + glusterfs_this_get() + { +- xlator_t **this_location = NULL; +- +- this_location = __glusterfs_this_location(); +- if (!this_location) +- return &global_xlator; +- +- return *this_location; ++ return *__glusterfs_this_location(); + } + +-int ++void + glusterfs_this_set(xlator_t *this) + { +- xlator_t **this_location = NULL; +- +- this_location = __glusterfs_this_location(); +- if (!this_location) +- return -ENOMEM; +- +- *this_location = this; +- +- return 0; ++ thread_xlator = this; + } + + /* SYNCOPCTX */ +-static pthread_key_t syncopctx_key; +- +-static void +-syncopctx_key_destroy(void *ptr) +-{ +- struct syncopctx *opctx = ptr; +- +- if (opctx) { +- if (opctx->groups) +- GF_FREE(opctx->groups); +- +- GF_FREE(opctx); +- } +- +- return; +-} + + void * + syncopctx_getctx() + { +- void *opctx = NULL; +- +- opctx = pthread_getspecific(syncopctx_key); +- +- return opctx; +-} +- +-int +-syncopctx_setctx(void *ctx) +-{ +- int ret = 0; +- +- ret = pthread_setspecific(syncopctx_key, ctx); +- +- return ret; +-} +- +-static int +-syncopctx_init(void) +-{ +- int ret; +- +- ret = pthread_key_create(&syncopctx_key, syncopctx_key_destroy); +- +- return ret; ++ return &thread_syncopctx; + } + + /* SYNCTASK */ + +-int +-synctask_init() +-{ +- int ret = 0; +- +- ret = pthread_key_create(&synctask_key, NULL); +- +- return ret; +-} +- + void * + synctask_get() + { +- void *synctask = NULL; +- +- synctask = pthread_getspecific(synctask_key); +- +- return synctask; ++ return thread_synctask; + } + +-int ++void + synctask_set(void *synctask) + { +- int ret = 0; +- +- pthread_setspecific(synctask_key, synctask); +- +- return ret; ++ thread_synctask = synctask; + } + + // UUID_BUFFER + +-void +-glusterfs_uuid_buf_destroy(void *ptr) +-{ +- FREE(ptr); +-} +- +-int +-glusterfs_uuid_buf_init() +-{ +- int ret = 0; +- +- ret = pthread_key_create(&uuid_buf_key, glusterfs_uuid_buf_destroy); +- return ret; +-} +- + char * + glusterfs_uuid_buf_get() + { +- char *buf; +- int ret = 0; +- +- buf = pthread_getspecific(uuid_buf_key); +- if (!buf) { +- buf = MALLOC(GF_UUID_BUF_SIZE); +- ret = pthread_setspecific(uuid_buf_key, (void *)buf); +- if (ret) +- buf = global_uuid_buf; +- } +- return buf; ++ return thread_uuid_buf; + } + + /* LKOWNER_BUFFER */ + +-void +-glusterfs_lkowner_buf_destroy(void *ptr) +-{ +- FREE(ptr); +-} +- +-int +-glusterfs_lkowner_buf_init() +-{ +- int ret = 0; +- +- ret = pthread_key_create(&lkowner_buf_key, glusterfs_lkowner_buf_destroy); +- return ret; +-} +- + char * + glusterfs_lkowner_buf_get() + { +- char *buf; +- int ret = 0; +- +- buf = pthread_getspecific(lkowner_buf_key); +- if (!buf) { +- buf = MALLOC(GF_LKOWNER_BUF_SIZE); +- ret = pthread_setspecific(lkowner_buf_key, (void *)buf); +- if (ret) +- buf = global_lkowner_buf; +- } +- return buf; ++ return thread_lkowner_buf; + } + + /* Leaseid buffer */ +-void +-glusterfs_leaseid_buf_destroy(void *ptr) +-{ +- FREE(ptr); +-} +- +-int +-glusterfs_leaseid_buf_init() +-{ +- int ret = 0; +- +- ret = pthread_key_create(&leaseid_buf_key, glusterfs_leaseid_buf_destroy); +- return ret; +-} + + char * + glusterfs_leaseid_buf_get() + { + char *buf = NULL; +- int ret = 0; + +- buf = pthread_getspecific(leaseid_buf_key); +- if (!buf) { +- buf = CALLOC(1, GF_LEASE_ID_BUF_SIZE); +- ret = pthread_setspecific(leaseid_buf_key, (void *)buf); +- if (ret) { +- FREE(buf); +- buf = NULL; +- } ++ buf = thread_leaseid; ++ if (buf == NULL) { ++ buf = thread_leaseid_buf; ++ thread_leaseid = buf; + } ++ + return buf; + } + + char * + glusterfs_leaseid_exist() + { +- return pthread_getspecific(leaseid_buf_key); ++ return thread_leaseid; + } + + static void +-gf_globals_init_once() ++glusterfs_cleanup(void *ptr) + { +- int ret = 0; +- +- ret = glusterfs_this_init(); +- if (ret) { +- gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_TRANSLATOR_INIT_FAILED, +- "ERROR: glusterfs-translator init failed"); +- goto out; +- } +- +- ret = glusterfs_uuid_buf_init(); +- if (ret) { +- gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_UUID_BUF_INIT_FAILED, +- "ERROR: glusterfs uuid buffer init failed"); +- goto out; ++ if (thread_syncopctx.groups != NULL) { ++ GF_FREE(thread_syncopctx.groups); + } + +- ret = glusterfs_lkowner_buf_init(); +- if (ret) { +- gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_LKOWNER_BUF_INIT_FAILED, +- "ERROR: glusterfs lkowner buffer init failed"); +- goto out; +- } ++ mem_pool_thread_destructor(); ++} + +- ret = glusterfs_leaseid_buf_init(); +- if (ret) { +- gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_LEASEID_BUF_INIT_FAILED, +- "ERROR: glusterfs leaseid buffer init failed"); +- goto out; +- } ++static void ++gf_globals_init_once() ++{ ++ int ret = 0; + +- ret = synctask_init(); +- if (ret) { +- gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCTASK_INIT_FAILED, +- "ERROR: glusterfs synctask init failed"); +- goto out; +- } ++ glusterfs_this_init(); + +- ret = syncopctx_init(); +- if (ret) { +- gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCOPCTX_INIT_FAILED, +- "ERROR: glusterfs syncopctx init failed"); +- goto out; +- } +-out: ++ /* This is needed only to cleanup the potential allocation of ++ * thread_syncopctx.groups. */ ++ ret = pthread_key_create(&free_key, glusterfs_cleanup); ++ if (ret != 0) { ++ gf_msg("", GF_LOG_ERROR, ret, LG_MSG_PTHREAD_KEY_CREATE_FAILED, ++ "failed to create the pthread key"); + +- if (ret) { + gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_GLOBAL_INIT_FAILED, + "Exiting as global initialization failed"); ++ + exit(ret); + } + } +diff --git a/libglusterfs/src/glusterfs/globals.h b/libglusterfs/src/glusterfs/globals.h +index e45db14..55476f6 100644 +--- a/libglusterfs/src/glusterfs/globals.h ++++ b/libglusterfs/src/glusterfs/globals.h +@@ -147,7 +147,7 @@ xlator_t ** + __glusterfs_this_location(void); + xlator_t * + glusterfs_this_get(void); +-int ++void + glusterfs_this_set(xlator_t *); + + extern xlator_t global_xlator; +@@ -156,13 +156,11 @@ extern struct volume_options global_xl_options[]; + /* syncopctx */ + void * + syncopctx_getctx(void); +-int +-syncopctx_setctx(void *ctx); + + /* task */ + void * + synctask_get(void); +-int ++void + synctask_set(void *); + + /* uuid_buf */ +diff --git a/libglusterfs/src/glusterfs/mem-pool.h b/libglusterfs/src/glusterfs/mem-pool.h +index 0250b59..c5a486b 100644 +--- a/libglusterfs/src/glusterfs/mem-pool.h ++++ b/libglusterfs/src/glusterfs/mem-pool.h +@@ -279,9 +279,7 @@ struct mem_pool_shared { + }; + + void +-mem_pools_init_early(void); /* basic initialization of memory pools */ +-void +-mem_pools_init_late(void); /* start the pool_sweeper thread */ ++mem_pools_init(void); /* start the pool_sweeper thread */ + void + mem_pools_fini(void); /* cleanup memory pools */ + +@@ -306,6 +304,9 @@ void + mem_pool_destroy(struct mem_pool *pool); + + void ++mem_pool_thread_destructor(void); ++ ++void + gf_mem_acct_enable_set(void *ctx); + + #endif /* _MEM_POOL_H */ +diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym +index 7a2edef..86215d2 100644 +--- a/libglusterfs/src/libglusterfs.sym ++++ b/libglusterfs/src/libglusterfs.sym +@@ -872,8 +872,7 @@ mem_get0 + mem_pool_destroy + mem_pool_new_fn + mem_pools_fini +-mem_pools_init_early +-mem_pools_init_late ++mem_pools_init + mem_put + mkdir_p + next_token +diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c +index 9b4ea52..ab78804 100644 +--- a/libglusterfs/src/mem-pool.c ++++ b/libglusterfs/src/mem-pool.c +@@ -353,7 +353,6 @@ free: + FREE(ptr); + } + +-static pthread_key_t pool_key; + static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER; + static struct list_head pool_threads; + static pthread_mutex_t pool_free_lock = PTHREAD_MUTEX_INITIALIZER; +@@ -361,6 +360,8 @@ static struct list_head pool_free_threads; + static struct mem_pool_shared pools[NPOOLS]; + static size_t pool_list_size; + ++static __thread per_thread_pool_list_t *thread_pool_list = NULL; ++ + #if !defined(GF_DISABLE_MEMPOOL) + #define N_COLD_LISTS 1024 + #define POOL_SWEEP_SECS 30 +@@ -373,7 +374,6 @@ typedef struct { + + enum init_state { + GF_MEMPOOL_INIT_NONE = 0, +- GF_MEMPOOL_INIT_PREINIT, + GF_MEMPOOL_INIT_EARLY, + GF_MEMPOOL_INIT_LATE, + GF_MEMPOOL_INIT_DESTROY +@@ -486,9 +486,9 @@ pool_sweeper(void *arg) + } + + void +-pool_destructor(void *arg) ++mem_pool_thread_destructor(void) + { +- per_thread_pool_list_t *pool_list = arg; ++ per_thread_pool_list_t *pool_list = thread_pool_list; + + /* The pool-sweeper thread will take it from here. + * +@@ -499,7 +499,10 @@ pool_destructor(void *arg) + * This change can modify what mem_put() does, but both possibilities are + * fine until the sweeper thread kicks in. The real synchronization must be + * between mem_put() and the sweeper thread. */ +- pool_list->poison = 1; ++ if (pool_list != NULL) { ++ pool_list->poison = 1; ++ thread_pool_list = NULL; ++ } + } + + static __attribute__((constructor)) void +@@ -522,46 +525,14 @@ mem_pools_preinit(void) + pool_list_size = sizeof(per_thread_pool_list_t) + + sizeof(per_thread_pool_t) * (NPOOLS - 1); + +- init_done = GF_MEMPOOL_INIT_PREINIT; ++ init_done = GF_MEMPOOL_INIT_EARLY; + } + +-/* Use mem_pools_init_early() function for basic initialization. There will be +- * no cleanup done by the pool_sweeper thread until mem_pools_init_late() has +- * been called. Calling mem_get() will be possible after this function has +- * setup the basic structures. */ ++/* Call mem_pools_init() once threading has been configured completely. This ++ * prevent the pool_sweeper thread from getting killed once the main() thread ++ * exits during deamonizing. */ + void +-mem_pools_init_early(void) +-{ +- pthread_mutex_lock(&init_mutex); +- /* Use a pthread_key destructor to clean up when a thread exits. +- * +- * We won't increase init_count here, that is only done when the +- * pool_sweeper thread is started too. +- */ +- if (init_done == GF_MEMPOOL_INIT_PREINIT || +- init_done == GF_MEMPOOL_INIT_DESTROY) { +- /* key has not been created yet */ +- if (pthread_key_create(&pool_key, pool_destructor) != 0) { +- gf_log("mem-pool", GF_LOG_CRITICAL, +- "failed to initialize mem-pool key"); +- } +- +- init_done = GF_MEMPOOL_INIT_EARLY; +- } else { +- gf_log("mem-pool", GF_LOG_CRITICAL, +- "incorrect order of mem-pool initialization " +- "(init_done=%d)", +- init_done); +- } +- +- pthread_mutex_unlock(&init_mutex); +-} +- +-/* Call mem_pools_init_late() once threading has been configured completely. +- * This prevent the pool_sweeper thread from getting killed once the main() +- * thread exits during deamonizing. */ +-void +-mem_pools_init_late(void) ++mem_pools_init(void) + { + pthread_mutex_lock(&init_mutex); + if ((init_count++) == 0) { +@@ -580,13 +551,12 @@ mem_pools_fini(void) + switch (init_count) { + case 0: + /* +- * If init_count is already zero (as e.g. if somebody called +- * this before mem_pools_init_late) then the sweeper was +- * probably never even started so we don't need to stop it. +- * Even if there's some crazy circumstance where there is a +- * sweeper but init_count is still zero, that just means we'll +- * leave it running. Not perfect, but far better than any +- * known alternative. ++ * If init_count is already zero (as e.g. if somebody called this ++ * before mem_pools_init) then the sweeper was probably never even ++ * started so we don't need to stop it. Even if there's some crazy ++ * circumstance where there is a sweeper but init_count is still ++ * zero, that just means we'll leave it running. Not perfect, but ++ * far better than any known alternative. + */ + break; + case 1: { +@@ -594,20 +564,17 @@ mem_pools_fini(void) + per_thread_pool_list_t *next_pl; + unsigned int i; + +- /* if only mem_pools_init_early() was called, sweeper_tid will +- * be invalid and the functions will error out. That is not +- * critical. In all other cases, the sweeper_tid will be valid +- * and the thread gets stopped. */ ++ /* if mem_pools_init() was not called, sweeper_tid will be invalid ++ * and the functions will error out. That is not critical. In all ++ * other cases, the sweeper_tid will be valid and the thread gets ++ * stopped. */ + (void)pthread_cancel(sweeper_tid); + (void)pthread_join(sweeper_tid, NULL); + +- /* Need to clean the pool_key to prevent further usage of the +- * per_thread_pool_list_t structure that is stored for each +- * thread. +- * This also prevents calling pool_destructor() when a thread +- * exits, so there is no chance on a use-after-free of the +- * per_thread_pool_list_t structure. */ +- (void)pthread_key_delete(pool_key); ++ /* At this point all threads should have already terminated, so ++ * it should be safe to destroy all pending per_thread_pool_list_t ++ * structures that are stored for each thread. */ ++ mem_pool_thread_destructor(); + + /* free all objects from all pools */ + list_for_each_entry_safe(pool_list, next_pl, &pool_threads, +@@ -642,11 +609,7 @@ mem_pools_fini(void) + + #else + void +-mem_pools_init_early(void) +-{ +-} +-void +-mem_pools_init_late(void) ++mem_pools_init(void) + { + } + void +@@ -734,7 +697,7 @@ mem_get_pool_list(void) + per_thread_pool_list_t *pool_list; + unsigned int i; + +- pool_list = pthread_getspecific(pool_key); ++ pool_list = thread_pool_list; + if (pool_list) { + return pool_list; + } +@@ -767,7 +730,8 @@ mem_get_pool_list(void) + list_add(&pool_list->thr_list, &pool_threads); + (void)pthread_mutex_unlock(&pool_lock); + +- (void)pthread_setspecific(pool_key, pool_list); ++ thread_pool_list = pool_list; ++ + return pool_list; + } + +diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c +index c05939a..2eb7b49 100644 +--- a/libglusterfs/src/syncop.c ++++ b/libglusterfs/src/syncop.c +@@ -26,28 +26,10 @@ syncopctx_setfsuid(void *uid) + + opctx = syncopctx_getctx(); + +- /* alloc for this thread the first time */ +- if (!opctx) { +- opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx); +- if (!opctx) { +- ret = -1; +- goto out; +- } +- +- ret = syncopctx_setctx(opctx); +- if (ret != 0) { +- GF_FREE(opctx); +- opctx = NULL; +- goto out; +- } +- } ++ opctx->uid = *(uid_t *)uid; ++ opctx->valid |= SYNCOPCTX_UID; + + out: +- if (opctx && uid) { +- opctx->uid = *(uid_t *)uid; +- opctx->valid |= SYNCOPCTX_UID; +- } +- + return ret; + } + +@@ -66,28 +48,10 @@ syncopctx_setfsgid(void *gid) + + opctx = syncopctx_getctx(); + +- /* alloc for this thread the first time */ +- if (!opctx) { +- opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx); +- if (!opctx) { +- ret = -1; +- goto out; +- } +- +- ret = syncopctx_setctx(opctx); +- if (ret != 0) { +- GF_FREE(opctx); +- opctx = NULL; +- goto out; +- } +- } ++ opctx->gid = *(gid_t *)gid; ++ opctx->valid |= SYNCOPCTX_GID; + + out: +- if (opctx && gid) { +- opctx->gid = *(gid_t *)gid; +- opctx->valid |= SYNCOPCTX_GID; +- } +- + return ret; + } + +@@ -107,43 +71,20 @@ syncopctx_setfsgroups(int count, const void *groups) + + opctx = syncopctx_getctx(); + +- /* alloc for this thread the first time */ +- if (!opctx) { +- opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx); +- if (!opctx) { +- ret = -1; +- goto out; +- } +- +- ret = syncopctx_setctx(opctx); +- if (ret != 0) { +- GF_FREE(opctx); +- opctx = NULL; +- goto out; +- } +- } +- + /* resize internal groups as required */ + if (count && opctx->grpsize < count) { + if (opctx->groups) { +- tmpgroups = GF_REALLOC(opctx->groups, (sizeof(gid_t) * count)); +- /* NOTE: Not really required to zero the reallocation, +- * as ngrps controls the validity of data, +- * making a note irrespective */ +- if (tmpgroups == NULL) { +- opctx->grpsize = 0; +- GF_FREE(opctx->groups); +- opctx->groups = NULL; +- ret = -1; +- goto out; +- } +- } else { +- tmpgroups = GF_CALLOC(count, sizeof(gid_t), gf_common_mt_syncopctx); +- if (tmpgroups == NULL) { +- opctx->grpsize = 0; +- ret = -1; +- goto out; +- } ++ /* Group list will be updated later, so no need to keep current ++ * data and waste time copying it. It's better to free the current ++ * allocation and then allocate a fresh new memory block. */ ++ GF_FREE(opctx->groups); ++ opctx->groups = NULL; ++ opctx->grpsize = 0; ++ } ++ tmpgroups = GF_MALLOC(count * sizeof(gid_t), gf_common_mt_syncopctx); ++ if (tmpgroups == NULL) { ++ ret = -1; ++ goto out; + } + + opctx->groups = tmpgroups; +@@ -177,28 +118,10 @@ syncopctx_setfspid(void *pid) + + opctx = syncopctx_getctx(); + +- /* alloc for this thread the first time */ +- if (!opctx) { +- opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx); +- if (!opctx) { +- ret = -1; +- goto out; +- } +- +- ret = syncopctx_setctx(opctx); +- if (ret != 0) { +- GF_FREE(opctx); +- opctx = NULL; +- goto out; +- } +- } ++ opctx->pid = *(pid_t *)pid; ++ opctx->valid |= SYNCOPCTX_PID; + + out: +- if (opctx && pid) { +- opctx->pid = *(pid_t *)pid; +- opctx->valid |= SYNCOPCTX_PID; +- } +- + return ret; + } + +@@ -217,28 +140,10 @@ syncopctx_setfslkowner(gf_lkowner_t *lk_owner) + + opctx = syncopctx_getctx(); + +- /* alloc for this thread the first time */ +- if (!opctx) { +- opctx = GF_CALLOC(1, sizeof(*opctx), gf_common_mt_syncopctx); +- if (!opctx) { +- ret = -1; +- goto out; +- } +- +- ret = syncopctx_setctx(opctx); +- if (ret != 0) { +- GF_FREE(opctx); +- opctx = NULL; +- goto out; +- } +- } ++ opctx->lk_owner = *lk_owner; ++ opctx->valid |= SYNCOPCTX_LKOWNER; + + out: +- if (opctx && lk_owner) { +- opctx->lk_owner = *lk_owner; +- opctx->valid |= SYNCOPCTX_LKOWNER; +- } +- + return ret; + } + +diff --git a/xlators/features/changelog/lib/src/gf-changelog-helpers.c b/xlators/features/changelog/lib/src/gf-changelog-helpers.c +index 03dac5e..e5a9db4 100644 +--- a/xlators/features/changelog/lib/src/gf-changelog-helpers.c ++++ b/xlators/features/changelog/lib/src/gf-changelog-helpers.c +@@ -64,20 +64,7 @@ gf_rfc3986_encode_space_newline(unsigned char *s, char *enc, char *estr) + * made a part of libglusterfs. + */ + +-static pthread_key_t rl_key; +-static pthread_once_t rl_once = PTHREAD_ONCE_INIT; +- +-static void +-readline_destructor(void *ptr) +-{ +- GF_FREE(ptr); +-} +- +-static void +-readline_once(void) +-{ +- pthread_key_create(&rl_key, readline_destructor); +-} ++static __thread read_line_t thread_tsd = {}; + + static ssize_t + my_read(read_line_t *tsd, int fd, char *ptr) +@@ -97,27 +84,6 @@ my_read(read_line_t *tsd, int fd, char *ptr) + return 1; + } + +-static int +-gf_readline_init_once(read_line_t **tsd) +-{ +- if (pthread_once(&rl_once, readline_once) != 0) +- return -1; +- +- *tsd = pthread_getspecific(rl_key); +- if (*tsd) +- goto out; +- +- *tsd = GF_CALLOC(1, sizeof(**tsd), gf_changelog_mt_libgfchangelog_rl_t); +- if (!*tsd) +- return -1; +- +- if (pthread_setspecific(rl_key, *tsd) != 0) +- return -1; +- +-out: +- return 0; +-} +- + ssize_t + gf_readline(int fd, void *vptr, size_t maxlen) + { +@@ -125,10 +91,7 @@ gf_readline(int fd, void *vptr, size_t maxlen) + size_t rc = 0; + char c = ' '; + char *ptr = NULL; +- read_line_t *tsd = NULL; +- +- if (gf_readline_init_once(&tsd)) +- return -1; ++ read_line_t *tsd = &thread_tsd; + + ptr = vptr; + for (n = 1; n < maxlen; n++) { +@@ -151,10 +114,7 @@ off_t + gf_lseek(int fd, off_t offset, int whence) + { + off_t off = 0; +- read_line_t *tsd = NULL; +- +- if (gf_readline_init_once(&tsd)) +- return -1; ++ read_line_t *tsd = &thread_tsd; + + off = sys_lseek(fd, offset, whence); + if (off == -1) +@@ -169,10 +129,7 @@ gf_lseek(int fd, off_t offset, int whence) + int + gf_ftruncate(int fd, off_t length) + { +- read_line_t *tsd = NULL; +- +- if (gf_readline_init_once(&tsd)) +- return -1; ++ read_line_t *tsd = &thread_tsd; + + if (sys_ftruncate(fd, 0)) + return -1; +diff --git a/xlators/features/changelog/lib/src/gf-changelog.c b/xlators/features/changelog/lib/src/gf-changelog.c +index 7ed9e55..d6acb37 100644 +--- a/xlators/features/changelog/lib/src/gf-changelog.c ++++ b/xlators/features/changelog/lib/src/gf-changelog.c +@@ -237,9 +237,8 @@ gf_changelog_init_master() + { + int ret = 0; + +- mem_pools_init_early(); + ret = gf_changelog_init_context(); +- mem_pools_init_late(); ++ mem_pools_init(); + + return ret; + } +diff --git a/xlators/nfs/server/src/mount3udp_svc.c b/xlators/nfs/server/src/mount3udp_svc.c +index d5e4169..0688779eb 100644 +--- a/xlators/nfs/server/src/mount3udp_svc.c ++++ b/xlators/nfs/server/src/mount3udp_svc.c +@@ -216,11 +216,7 @@ mount3udp_thread(void *argv) + + GF_ASSERT(nfsx); + +- if (glusterfs_this_set(nfsx)) { +- gf_msg(GF_MNT, GF_LOG_ERROR, ENOMEM, NFS_MSG_XLATOR_SET_FAIL, +- "Failed to set xlator, nfs.mount-udp will not work"); +- return NULL; +- } ++ glusterfs_this_set(nfsx); + + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL) { +-- +1.8.3.1 + diff --git a/0210-mem-pool.-c-h-minor-changes.patch b/0210-mem-pool.-c-h-minor-changes.patch new file mode 100644 index 0000000..c238579 --- /dev/null +++ b/0210-mem-pool.-c-h-minor-changes.patch @@ -0,0 +1,129 @@ +From 77a3cac0c8aed9e084296719926a534128c31dee Mon Sep 17 00:00:00 2001 +From: Yaniv Kaul +Date: Wed, 27 Feb 2019 15:48:42 +0200 +Subject: [PATCH 210/221] mem-pool.{c|h}: minor changes + +1. Removed some code that was not needed. It did not really do anything. +2. CALLOC -> MALLOC in one place. + +Compile-tested only! + +Upstream patch: +> BUG: 1193929 +> Upstream patch link: https://review.gluster.org/c/glusterfs/+/22274 +> Signed-off-by: Yaniv Kaul +> Change-Id: I4419161e1bb636158e32b5d33044b06f1eef2449 + +Change-Id: I4419161e1bb636158e32b5d33044b06f1eef2449 +Updates: bz#1722801 +Signed-off-by: Yaniv Kaul +Reviewed-on: https://code.engineering.redhat.com/gerrit/174712 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + libglusterfs/src/mem-pool.c | 37 ++++++++++++------------------------- + 1 file changed, 12 insertions(+), 25 deletions(-) + +diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c +index ab78804..ca25ffc 100644 +--- a/libglusterfs/src/mem-pool.c ++++ b/libglusterfs/src/mem-pool.c +@@ -643,7 +643,7 @@ mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, + } + pool = &pools[power - POOL_SMALLEST]; + +- new = GF_CALLOC(sizeof(struct mem_pool), 1, gf_common_mt_mem_pool); ++ new = GF_MALLOC(sizeof(struct mem_pool), gf_common_mt_mem_pool); + if (!new) + return NULL; + +@@ -671,15 +671,7 @@ mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, + void * + mem_get0(struct mem_pool *mem_pool) + { +- void *ptr = NULL; +- +- if (!mem_pool) { +- gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, +- "invalid argument"); +- return NULL; +- } +- +- ptr = mem_get(mem_pool); ++ void *ptr = mem_get(mem_pool); + if (ptr) { + #if defined(GF_DISABLE_MEMPOOL) + memset(ptr, 0, mem_pool->sizeof_type); +@@ -736,12 +728,14 @@ mem_get_pool_list(void) + } + + pooled_obj_hdr_t * +-mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool, +- gf_boolean_t *hit) ++mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool) + { + per_thread_pool_list_t *pool_list; + per_thread_pool_t *pt_pool; + pooled_obj_hdr_t *retval; ++#ifdef DEBUG ++ gf_boolean_t hit = _gf_true; ++#endif + + pool_list = mem_get_pool_list(); + if (!pool_list || pool_list->poison) { +@@ -755,10 +749,6 @@ mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool, + pt_pool = &pool_list->pools[pool->power_of_two - POOL_SMALLEST]; + } + +-#ifdef DEBUG +- *hit = _gf_true; +-#endif +- + (void)pthread_spin_lock(&pool_list->lock); + + retval = pt_pool->hot_list; +@@ -778,7 +768,7 @@ mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool, + retval = malloc((1 << pt_pool->parent->power_of_two) + + sizeof(pooled_obj_hdr_t)); + #ifdef DEBUG +- *hit = _gf_false; ++ hit = _gf_false; + #endif + } + } +@@ -788,7 +778,7 @@ mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool, + retval->pool = mem_pool; + retval->power_of_two = mem_pool->pool->power_of_two; + #ifdef DEBUG +- if (*hit == _gf_true) ++ if (hit == _gf_true) + GF_ATOMIC_INC(mem_pool->hit); + else + GF_ATOMIC_INC(mem_pool->miss); +@@ -807,19 +797,16 @@ mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool, + void * + mem_get(struct mem_pool *mem_pool) + { +-#if defined(GF_DISABLE_MEMPOOL) +- return GF_MALLOC(mem_pool->sizeof_type, gf_common_mt_mem_pool); +-#else +- pooled_obj_hdr_t *retval; +- gf_boolean_t hit; +- + if (!mem_pool) { + gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, + "invalid argument"); + return NULL; + } + +- retval = mem_get_from_pool(mem_pool, NULL, &hit); ++#if defined(GF_DISABLE_MEMPOOL) ++ return GF_MALLOC(mem_pool->sizeof_type, gf_common_mt_mem_pool); ++#else ++ pooled_obj_hdr_t *retval = mem_get_from_pool(mem_pool, NULL); + if (!retval) { + return NULL; + } +-- +1.8.3.1 + diff --git a/0211-libglusterfs-Fix-compilation-when-disable-mempool-is.patch b/0211-libglusterfs-Fix-compilation-when-disable-mempool-is.patch new file mode 100644 index 0000000..27326a9 --- /dev/null +++ b/0211-libglusterfs-Fix-compilation-when-disable-mempool-is.patch @@ -0,0 +1,41 @@ +From 4fa3c0be983c3f99c2785036ded5ef5ab390419b Mon Sep 17 00:00:00 2001 +From: Pranith Kumar K +Date: Mon, 6 May 2019 15:57:16 +0530 +Subject: [PATCH 211/221] libglusterfs: Fix compilation when --disable-mempool + is used + +Upstream patch: +> BUG: 1193929 +> Upstream patch link: https://review.gluster.org/c/glusterfs/+/22665 +> Change-Id: I245c065b209bcce5db939b6a0a934ba6fd393b47 +> Signed-off-by: Pranith Kumar K + +Updates: bz#1722801 +Change-Id: I245c065b209bcce5db939b6a0a934ba6fd393b47 +Signed-off-by: Pranith Kumar K +Reviewed-on: https://code.engineering.redhat.com/gerrit/174713 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + libglusterfs/src/mem-pool.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c +index ca25ffc..df167b6 100644 +--- a/libglusterfs/src/mem-pool.c ++++ b/libglusterfs/src/mem-pool.c +@@ -616,6 +616,11 @@ void + mem_pools_fini(void) + { + } ++void ++mem_pool_thread_destructor(void) ++{ ++} ++ + #endif + + struct mem_pool * +-- +1.8.3.1 + diff --git a/0212-core-fix-memory-allocation-issues.patch b/0212-core-fix-memory-allocation-issues.patch new file mode 100644 index 0000000..18da11d --- /dev/null +++ b/0212-core-fix-memory-allocation-issues.patch @@ -0,0 +1,169 @@ +From 0bf728030e0ad7a49e6e1737ea06ae74da9279d3 Mon Sep 17 00:00:00 2001 +From: Xavi Hernandez +Date: Fri, 21 Jun 2019 11:28:08 +0200 +Subject: [PATCH 212/221] core: fix memory allocation issues + +Two problems have been identified that caused that gluster's memory +usage were twice higher than required. + +1. An off by 1 error caused that all objects allocated from the memory + pools were taken from a pool bigger than required. Since each pool + corresponds to a size equal to a power of two, this was wasting half + of the available memory. + +2. The header information used for accounting on each memory object was + not taken into consideration when searching for a suitable memory + pool. It was added later when each individual block was allocated. + This made this space "invisible" to memory accounting. + +Credits: Thanks to Nithya Balachandran for identifying this problem and + testing this patch. + +Upstream patch: +> BUG: 1722802 +> Upstream patch link: https://review.gluster.org/c/glusterfs/+/22921 +> Change-Id: I90e27ad795fe51ca11c13080f62207451f6c138c +> Signed-off-by: Xavi Hernandez + +Fixes: bz#1722801 +Change-Id: I90e27ad795fe51ca11c13080f62207451f6c138c +Signed-off-by: Xavi Hernandez +Reviewed-on: https://code.engineering.redhat.com/gerrit/174714 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + libglusterfs/src/glusterfs/mem-pool.h | 5 ++- + libglusterfs/src/mem-pool.c | 57 +++++++++++++++++++---------------- + 2 files changed, 35 insertions(+), 27 deletions(-) + +diff --git a/libglusterfs/src/glusterfs/mem-pool.h b/libglusterfs/src/glusterfs/mem-pool.h +index c5a486b..be0a26d 100644 +--- a/libglusterfs/src/glusterfs/mem-pool.h ++++ b/libglusterfs/src/glusterfs/mem-pool.h +@@ -231,7 +231,10 @@ typedef struct pooled_obj_hdr { + struct mem_pool *pool; + } pooled_obj_hdr_t; + +-#define AVAILABLE_SIZE(p2) (1 << (p2)) ++/* Each memory block inside a pool has a fixed size that is a power of two. ++ * However each object will have a header that will reduce the available ++ * space. */ ++#define AVAILABLE_SIZE(p2) ((1UL << (p2)) - sizeof(pooled_obj_hdr_t)) + + typedef struct per_thread_pool { + /* the pool that was used to request this allocation */ +diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c +index df167b6..d88041d 100644 +--- a/libglusterfs/src/mem-pool.c ++++ b/libglusterfs/src/mem-pool.c +@@ -627,6 +627,7 @@ struct mem_pool * + mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, + unsigned long count, char *name) + { ++ unsigned long extra_size, size; + unsigned int power; + struct mem_pool *new = NULL; + struct mem_pool_shared *pool = NULL; +@@ -637,10 +638,25 @@ mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, + return NULL; + } + +- /* We ensure sizeof_type > 1 and the next power of two will be, at least, +- * 2^POOL_SMALLEST */ +- sizeof_type |= (1 << POOL_SMALLEST) - 1; +- power = sizeof(sizeof_type) * 8 - __builtin_clzl(sizeof_type - 1) + 1; ++ /* This is the overhead we'll have because of memory accounting for each ++ * memory block. */ ++ extra_size = sizeof(pooled_obj_hdr_t); ++ ++ /* We need to compute the total space needed to hold the data type and ++ * the header. Given that the smallest block size we have in the pools ++ * is 2^POOL_SMALLEST, we need to take the MAX(size, 2^POOL_SMALLEST). ++ * However, since this value is only needed to compute its rounded ++ * logarithm in base 2, and this only depends on the highest bit set, ++ * we can simply do a bitwise or with the minimum size. We need to ++ * subtract 1 for correct handling of sizes that are exactly a power ++ * of 2. */ ++ size = (sizeof_type + extra_size - 1UL) | ((1UL << POOL_SMALLEST) - 1UL); ++ ++ /* We compute the logarithm in base 2 rounded up of the resulting size. ++ * This value will identify which pool we need to use from the pools of ++ * powers of 2. This is equivalent to finding the position of the highest ++ * bit set. */ ++ power = sizeof(size) * 8 - __builtin_clzl(size); + if (power > POOL_LARGEST) { + gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, + "invalid argument"); +@@ -732,8 +748,8 @@ mem_get_pool_list(void) + return pool_list; + } + +-pooled_obj_hdr_t * +-mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool) ++static pooled_obj_hdr_t * ++mem_get_from_pool(struct mem_pool *mem_pool) + { + per_thread_pool_list_t *pool_list; + per_thread_pool_t *pt_pool; +@@ -747,12 +763,7 @@ mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool) + return NULL; + } + +- if (mem_pool) { +- pt_pool = &pool_list +- ->pools[mem_pool->pool->power_of_two - POOL_SMALLEST]; +- } else { +- pt_pool = &pool_list->pools[pool->power_of_two - POOL_SMALLEST]; +- } ++ pt_pool = &pool_list->pools[mem_pool->pool->power_of_two - POOL_SMALLEST]; + + (void)pthread_spin_lock(&pool_list->lock); + +@@ -770,8 +781,7 @@ mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool) + } else { + (void)pthread_spin_unlock(&pool_list->lock); + GF_ATOMIC_INC(pt_pool->parent->allocs_stdc); +- retval = malloc((1 << pt_pool->parent->power_of_two) + +- sizeof(pooled_obj_hdr_t)); ++ retval = malloc(1 << pt_pool->parent->power_of_two); + #ifdef DEBUG + hit = _gf_false; + #endif +@@ -779,19 +789,14 @@ mem_get_from_pool(struct mem_pool *mem_pool, struct mem_pool_shared *pool) + } + + if (retval != NULL) { +- if (mem_pool) { +- retval->pool = mem_pool; +- retval->power_of_two = mem_pool->pool->power_of_two; ++ retval->pool = mem_pool; ++ retval->power_of_two = mem_pool->pool->power_of_two; + #ifdef DEBUG +- if (hit == _gf_true) +- GF_ATOMIC_INC(mem_pool->hit); +- else +- GF_ATOMIC_INC(mem_pool->miss); ++ if (hit == _gf_true) ++ GF_ATOMIC_INC(mem_pool->hit); ++ else ++ GF_ATOMIC_INC(mem_pool->miss); + #endif +- } else { +- retval->power_of_two = pool->power_of_two; +- retval->pool = NULL; +- } + retval->magic = GF_MEM_HEADER_MAGIC; + retval->pool_list = pool_list; + } +@@ -811,7 +816,7 @@ mem_get(struct mem_pool *mem_pool) + #if defined(GF_DISABLE_MEMPOOL) + return GF_MALLOC(mem_pool->sizeof_type, gf_common_mt_mem_pool); + #else +- pooled_obj_hdr_t *retval = mem_get_from_pool(mem_pool, NULL); ++ pooled_obj_hdr_t *retval = mem_get_from_pool(mem_pool); + if (!retval) { + return NULL; + } +-- +1.8.3.1 + diff --git a/0213-cluster-dht-Strip-out-dht-xattrs.patch b/0213-cluster-dht-Strip-out-dht-xattrs.patch new file mode 100644 index 0000000..225379b --- /dev/null +++ b/0213-cluster-dht-Strip-out-dht-xattrs.patch @@ -0,0 +1,42 @@ +From ff5f06d6ba5ac87094ae5df435d1cfb38802e7ca Mon Sep 17 00:00:00 2001 +From: N Balachandran +Date: Tue, 18 Jun 2019 15:33:29 +0530 +Subject: [PATCH 213/221] cluster/dht: Strip out dht xattrs + +Some internal DHT xattrs were not being +removed when calling getxattr in pass-through mode. +This has been fixed. + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/22889/ + +>Change-Id: If7e3dbc7b495db88a566bd560888e3e9c167defa +>fixes: bz#1721435 +>Signed-off-by: N Balachandran + + +BUG: 1721357 +Change-Id: I29bce7ea78bb4fd3b493404282cb2c48ef0bf4ee +Signed-off-by: N Balachandran +Reviewed-on: https://code.engineering.redhat.com/gerrit/174699 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + xlators/cluster/dht/src/dht-common.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c +index e1edb38..9a6ea5b 100644 +--- a/xlators/cluster/dht/src/dht-common.c ++++ b/xlators/cluster/dht/src/dht-common.c +@@ -11216,6 +11216,8 @@ dht_pt_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + + conf = this->private; + dict_del(xattr, conf->xattr_name); ++ dict_del(xattr, conf->mds_xattr_key); ++ dict_del(xattr, conf->commithash_xattr_name); + + if (frame->root->pid >= 0) { + GF_REMOVE_INTERNAL_XATTR("trusted.glusterfs.quota*", xattr); +-- +1.8.3.1 + diff --git a/0214-geo-rep-Upgrading-config-file-to-new-version.patch b/0214-geo-rep-Upgrading-config-file-to-new-version.patch new file mode 100644 index 0000000..711aa3b --- /dev/null +++ b/0214-geo-rep-Upgrading-config-file-to-new-version.patch @@ -0,0 +1,114 @@ +From 76921775b0a6760276060409882c0556f19d8d01 Mon Sep 17 00:00:00 2001 +From: Shwetha K Acharya +Date: Wed, 29 May 2019 16:49:01 +0530 +Subject: [PATCH 214/221] geo-rep: Upgrading config file to new version + +- configuration handling is enhanced with patch +https://review.gluster.org/#/c/glusterfs/+/18257/ +- hence, the old configurations are not applied when +Geo-rep session is created in the old version and upgraded. + +This patch solves the issue. It, +- checks if the config file is old. +- parses required values from old config file and stores in new + config file, which ensures that configurations are applied on + upgrade. +- stores old config file as backup. +- handles changes in options introduced in + https://review.gluster.org/#/c/glusterfs/+/18257/ + +>fixes: bz#1707731 +>Change-Id: Iad8da6c1e1ae8ecf7c84dfdf8ea3ac6966d8a2a0 +>Signed-off-by: Shwetha K Acharya + +backport of https://review.gluster.org/#/c/glusterfs/+/22894/ + +Bug: 1708064 +Change-Id: Iad8da6c1e1ae8ecf7c84dfdf8ea3ac6966d8a2a0 +Signed-off-by: Shwetha K Acharya +Reviewed-on: https://code.engineering.redhat.com/gerrit/174743 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + geo-replication/syncdaemon/gsyncd.py | 5 ++++ + geo-replication/syncdaemon/gsyncdconfig.py | 41 ++++++++++++++++++++++++++++++ + 2 files changed, 46 insertions(+) + +diff --git a/geo-replication/syncdaemon/gsyncd.py b/geo-replication/syncdaemon/gsyncd.py +index effe0ce..a4c6f32 100644 +--- a/geo-replication/syncdaemon/gsyncd.py ++++ b/geo-replication/syncdaemon/gsyncd.py +@@ -253,6 +253,11 @@ def main(): + if args.subcmd == "slave": + override_from_args = True + ++ if args.subcmd == "monitor": ++ ret = gconf.is_config_file_old(config_file, args.master, extra_tmpl_args["slavevol"]) ++ if ret is not None: ++ gconf.config_upgrade(config_file, ret) ++ + # Load Config file + gconf.load(GLUSTERFS_CONFDIR + "/gsyncd.conf", + config_file, +diff --git a/geo-replication/syncdaemon/gsyncdconfig.py b/geo-replication/syncdaemon/gsyncdconfig.py +index 23a1c57..7edc582 100644 +--- a/geo-replication/syncdaemon/gsyncdconfig.py ++++ b/geo-replication/syncdaemon/gsyncdconfig.py +@@ -14,6 +14,7 @@ try: + except ImportError: + from configparser import ConfigParser, NoSectionError + import os ++import shutil + from string import Template + from datetime import datetime + +@@ -325,6 +326,46 @@ class Gconf(object): + + return False + ++def is_config_file_old(config_file, mastervol, slavevol): ++ cnf = ConfigParser() ++ cnf.read(config_file) ++ session_section = "peers %s %s" % (mastervol, slavevol) ++ try: ++ return dict(cnf.items(session_section)) ++ except NoSectionError: ++ return None ++ ++def config_upgrade(config_file, ret): ++ config_file_backup = os.path.join(os.path.dirname(config_file), "gsyncd.conf.bkp") ++ ++ #copy old config file in a backup file ++ shutil.copyfile(config_file, config_file_backup) ++ ++ #write a new config file ++ config = ConfigParser() ++ config.add_section('vars') ++ ++ for key, value in ret.items(): ++ #handle option name changes ++ if key == "use_tarssh": ++ new_key = "sync-method" ++ if value == "true": ++ new_value = "tarssh" ++ else: ++ new_value = "rsync" ++ config.set('vars', new_key, new_value) ++ ++ if key == "timeout": ++ new_key = "slave-timeout" ++ config.set('vars', new_key, value) ++ ++ #for changes like: ignore_deletes to ignore-deletes ++ new_key = key.replace("_", "-") ++ config.set('vars', new_key, value) ++ ++ with open(config_file, 'w') as configfile: ++ config.write(configfile) ++ + + def validate_unixtime(value): + try: +-- +1.8.3.1 + diff --git a/0215-posix-modify-storage.reserve-option-to-take-size-and.patch b/0215-posix-modify-storage.reserve-option-to-take-size-and.patch new file mode 100644 index 0000000..3e4217b --- /dev/null +++ b/0215-posix-modify-storage.reserve-option-to-take-size-and.patch @@ -0,0 +1,319 @@ +From 0c485548b4126ed907dec9941209b1b1312d0b5d Mon Sep 17 00:00:00 2001 +From: Sheetal Pamecha +Date: Wed, 19 Jun 2019 15:08:58 +0530 +Subject: [PATCH 215/221] posix: modify storage.reserve option to take size and + percent + +* reverting changes made in +https://review.gluster.org/#/c/glusterfs/+/21686/ + +* Now storage.reserve can take value in percent or bytes + +> fixes: bz#1651445 +> Change-Id: Id4826210ec27991c55b17d1fecd90356bff3e036 +> Signed-off-by: Sheetal Pamecha +> Cherry pick from commit 5cbc87d8b8f1287e81c38b793b8d13b057208c62 +> Reviewed on upstream link https://review.gluster.org/#/c/glusterfs/+/22900/ + +BUG: 1573077 +Change-Id: Id4826210ec27991c55b17d1fecd90356bff3e036 +Signed-off-by: Sheetal Pamecha +Reviewed-on: https://code.engineering.redhat.com/gerrit/174744 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + tests/bugs/posix/bug-1651445.t | 29 +++++++++------------- + xlators/mgmt/glusterd/src/glusterd-volume-set.c | 33 ------------------------- + xlators/storage/posix/src/posix-common.c | 33 +++++++++++-------------- + xlators/storage/posix/src/posix-helpers.c | 26 +++++++++---------- + xlators/storage/posix/src/posix-inode-fd-ops.c | 15 ++++++----- + xlators/storage/posix/src/posix.h | 4 +-- + 6 files changed, 51 insertions(+), 89 deletions(-) + +diff --git a/tests/bugs/posix/bug-1651445.t b/tests/bugs/posix/bug-1651445.t +index f6f1833..5248d47 100644 +--- a/tests/bugs/posix/bug-1651445.t ++++ b/tests/bugs/posix/bug-1651445.t +@@ -17,39 +17,34 @@ TEST $CLI volume start $V0 + + TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 + +-TEST $CLI volume set $V0 storage.reserve-size 10MB ++#Setting the size in bytes ++TEST $CLI volume set $V0 storage.reserve 40MB + +-#No effect as priority to reserve-size +-TEST $CLI volume set $V0 storage.reserve 20 ++#wait 5s to reset disk_space_full flag ++sleep 5 + + TEST dd if=/dev/zero of=$M0/a bs=100M count=1 +-sleep 5 ++TEST dd if=/dev/zero of=$M0/b bs=10M count=1 + +-#Below dd confirms posix is giving priority to reserve-size +-TEST dd if=/dev/zero of=$M0/b bs=40M count=1 ++# Wait 5s to update disk_space_full flag because thread check disk space ++# after every 5s + + sleep 5 ++# setup_lvm create lvm partition of 150M and 40M are reserve so after ++# consuming more than 110M next dd should fail + TEST ! dd if=/dev/zero of=$M0/c bs=5M count=1 + + rm -rf $M0/* +-#Size will reserve from the previously set reserve option = 20% +-TEST $CLI volume set $V0 storage.reserve-size 0 + +-#Overwrite reserve option +-TEST $CLI volume set $V0 storage.reserve-size 40MB ++#Setting the size in percent and repeating the above steps ++TEST $CLI volume set $V0 storage.reserve 40 + +-#wait 5s to reset disk_space_full flag + sleep 5 + +-TEST dd if=/dev/zero of=$M0/a bs=100M count=1 ++TEST dd if=/dev/zero of=$M0/a bs=80M count=1 + TEST dd if=/dev/zero of=$M0/b bs=10M count=1 + +-# Wait 5s to update disk_space_full flag because thread check disk space +-# after every 5s +- + sleep 5 +-# setup_lvm create lvm partition of 150M and 40M are reserve so after +-# consuming more than 110M next dd should fail + TEST ! dd if=/dev/zero of=$M0/c bs=5M count=1 + + TEST $CLI volume stop $V0 +diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c +index 3a7ab83..7a83124 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c ++++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c +@@ -1231,30 +1231,6 @@ out: + + return ret; + } +-static int +-validate_size(glusterd_volinfo_t *volinfo, dict_t *dict, char *key, char *value, +- char **op_errstr) +-{ +- xlator_t *this = NULL; +- uint64_t size = 0; +- int ret = -1; +- +- this = THIS; +- GF_VALIDATE_OR_GOTO("glusterd", this, out); +- ret = gf_string2bytesize_uint64(value, &size); +- if (ret < 0) { +- gf_asprintf(op_errstr, +- "%s is not a valid size. %s " +- "expects a valid value in bytes", +- value, key); +- gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_INVALID_ENTRY, "%s", +- *op_errstr); +- } +-out: +- gf_msg_debug("glusterd", 0, "Returning %d", ret); +- +- return ret; +-} + + /* dispatch table for VOLUME SET + * ----------------------------- +@@ -2854,15 +2830,6 @@ struct volopt_map_entry glusterd_volopt_map[] = { + .op_version = GD_OP_VERSION_3_13_0, + }, + { +- .key = "storage.reserve-size", +- .voltype = "storage/posix", +- .value = "0", +- .validate_fn = validate_size, +- .description = "If set, priority will be given to " +- "storage.reserve-size over storage.reserve", +- .op_version = GD_OP_VERSION_7_0, +- }, +- { + .option = "health-check-timeout", + .key = "storage.health-check-timeout", + .type = NO_DOC, +diff --git a/xlators/storage/posix/src/posix-common.c b/xlators/storage/posix/src/posix-common.c +index 0f70af5..bfe2cb0 100644 +--- a/xlators/storage/posix/src/posix-common.c ++++ b/xlators/storage/posix/src/posix-common.c +@@ -345,12 +345,14 @@ posix_reconfigure(xlator_t *this, dict_t *options) + " fallback to :"); + } + +- GF_OPTION_RECONF("reserve-size", priv->disk_reserve_size, options, size, ++ GF_OPTION_RECONF("reserve", priv->disk_reserve, options, percent_or_size, + out); ++ /* option can be any one of percent or bytes */ ++ priv->disk_unit = 0; ++ if (priv->disk_reserve < 100.0) ++ priv->disk_unit = 'p'; + +- GF_OPTION_RECONF("reserve", priv->disk_reserve_percent, options, uint32, +- out); +- if (priv->disk_reserve_size || priv->disk_reserve_percent) { ++ if (priv->disk_reserve) { + ret = posix_spawn_disk_space_check_thread(this); + if (ret) { + gf_msg(this->name, GF_LOG_INFO, 0, P_MSG_DISK_SPACE_CHECK_FAILED, +@@ -975,11 +977,15 @@ posix_init(xlator_t *this) + + _private->disk_space_check_active = _gf_false; + _private->disk_space_full = 0; +- GF_OPTION_INIT("reserve-size", _private->disk_reserve_size, size, out); + +- GF_OPTION_INIT("reserve", _private->disk_reserve_percent, uint32, out); ++ GF_OPTION_INIT("reserve", _private->disk_reserve, percent_or_size, out); ++ ++ /* option can be any one of percent or bytes */ ++ _private->disk_unit = 0; ++ if (_private->disk_reserve < 100.0) ++ _private->disk_unit = 'p'; + +- if (_private->disk_reserve_size || _private->disk_reserve_percent) { ++ if (_private->disk_reserve) { + ret = posix_spawn_disk_space_check_thread(this); + if (ret) { + gf_msg(this->name, GF_LOG_INFO, 0, P_MSG_DISK_SPACE_CHECK_FAILED, +@@ -1221,23 +1227,14 @@ struct volume_options posix_options[] = { + .op_version = {GD_OP_VERSION_4_0_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, + {.key = {"reserve"}, +- .type = GF_OPTION_TYPE_INT, ++ .type = GF_OPTION_TYPE_PERCENT_OR_SIZET, + .min = 0, + .default_value = "1", + .validate = GF_OPT_VALIDATE_MIN, +- .description = "Percentage of disk space to be reserved." ++ .description = "Percentage/Size of disk space to be reserved." + " Set to 0 to disable", + .op_version = {GD_OP_VERSION_3_13_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, +- {.key = {"reserve-size"}, +- .type = GF_OPTION_TYPE_SIZET, +- .min = 0, +- .default_value = "0", +- .validate = GF_OPT_VALIDATE_MIN, +- .description = "size in megabytes to be reserved for disk space." +- " Set to 0 to disable", +- .op_version = {GD_OP_VERSION_7_0}, +- .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC}, + {.key = {"batch-fsync-mode"}, + .type = GF_OPTION_TYPE_STR, + .default_value = "reverse-fsync", +diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c +index 849db3d..07169b5 100644 +--- a/xlators/storage/posix/src/posix-helpers.c ++++ b/xlators/storage/posix/src/posix-helpers.c +@@ -2246,11 +2246,11 @@ posix_disk_space_check(xlator_t *this) + struct posix_private *priv = NULL; + char *subvol_path = NULL; + int op_ret = 0; +- uint64_t size = 0; +- int percent = 0; ++ double size = 0; ++ double percent = 0; + struct statvfs buf = {0}; +- uint64_t totsz = 0; +- uint64_t freesz = 0; ++ double totsz = 0; ++ double freesz = 0; + + GF_VALIDATE_OR_GOTO(this->name, this, out); + priv = this->private; +@@ -2258,14 +2258,6 @@ posix_disk_space_check(xlator_t *this) + + subvol_path = priv->base_path; + +- if (priv->disk_reserve_size) { +- size = priv->disk_reserve_size; +- } else { +- percent = priv->disk_reserve_percent; +- totsz = (buf.f_blocks * buf.f_bsize); +- size = ((totsz * percent) / 100); +- } +- + op_ret = sys_statvfs(subvol_path, &buf); + + if (op_ret == -1) { +@@ -2273,8 +2265,16 @@ posix_disk_space_check(xlator_t *this) + "statvfs failed on %s", subvol_path); + goto out; + } +- freesz = (buf.f_bfree * buf.f_bsize); + ++ if (priv->disk_unit == 'p') { ++ percent = priv->disk_reserve; ++ totsz = (buf.f_blocks * buf.f_bsize); ++ size = ((totsz * percent) / 100); ++ } else { ++ size = priv->disk_reserve; ++ } ++ ++ freesz = (buf.f_bfree * buf.f_bsize); + if (freesz <= size) { + priv->disk_space_full = 1; + } else { +diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c +index b92c411..fc847d6 100644 +--- a/xlators/storage/posix/src/posix-inode-fd-ops.c ++++ b/xlators/storage/posix/src/posix-inode-fd-ops.c +@@ -720,7 +720,7 @@ posix_do_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + thread after every 5 sec sleep to working correctly storage.reserve + option behaviour + */ +- if (priv->disk_reserve_size || priv->disk_reserve_percent) ++ if (priv->disk_reserve) + posix_disk_space_check(this); + + DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, ret, ret, out); +@@ -2306,7 +2306,7 @@ posix_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) + }; + struct posix_private *priv = NULL; + int shared_by = 1; +- int percent = 0; ++ double percent = 0; + uint64_t reserved_blocks = 0; + + VALIDATE_OR_GOTO(frame, out); +@@ -2332,11 +2332,14 @@ posix_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) + goto out; + } + +- if (priv->disk_reserve_size) { +- reserved_blocks = priv->disk_reserve_size / buf.f_bsize; ++ if (priv->disk_unit == 'p') { ++ percent = priv->disk_reserve; ++ reserved_blocks = (((buf.f_blocks * percent) / 100) + 0.5); + } else { +- percent = priv->disk_reserve_percent; +- reserved_blocks = (buf.f_blocks * percent) / 100; ++ if (buf.f_bsize) { ++ reserved_blocks = (priv->disk_reserve + buf.f_bsize - 1) / ++ buf.f_bsize; ++ } + } + + if (buf.f_bfree > reserved_blocks) { +diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h +index 4364b96..b0935a7 100644 +--- a/xlators/storage/posix/src/posix.h ++++ b/xlators/storage/posix/src/posix.h +@@ -225,8 +225,8 @@ struct posix_private { + pthread_t health_check; + gf_boolean_t health_check_active; + +- uint32_t disk_reserve_percent; +- uint64_t disk_reserve_size; ++ double disk_reserve; ++ char disk_unit; + uint32_t disk_space_full; + pthread_t disk_space_check; + gf_boolean_t disk_space_check_active; +-- +1.8.3.1 + diff --git a/0216-Test-case-fixe-for-downstream-3.5.0.patch b/0216-Test-case-fixe-for-downstream-3.5.0.patch new file mode 100644 index 0000000..bc4ce60 --- /dev/null +++ b/0216-Test-case-fixe-for-downstream-3.5.0.patch @@ -0,0 +1,29 @@ +From b2204969bb0dba5de32685e1021fa44d0c406813 Mon Sep 17 00:00:00 2001 +From: Sunil Kumar Acharya +Date: Tue, 25 Jun 2019 12:17:10 +0530 +Subject: [PATCH 216/221] Test case fixe for downstream 3.5.0 + +Mark bug-1319374-THIS-crash.t as bad. + +BUG: 1704562 +Change-Id: I6afeb9a74ab88af7b741454367005250cd4c0e0f +Signed-off-by: Sunil Kumar Acharya +Reviewed-on: https://code.engineering.redhat.com/gerrit/174652 +Tested-by: RHGS Build Bot +--- + tests/bugs/gfapi/bug-1319374-THIS-crash.t | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tests/bugs/gfapi/bug-1319374-THIS-crash.t b/tests/bugs/gfapi/bug-1319374-THIS-crash.t +index 8d3db42..429d71e 100755 +--- a/tests/bugs/gfapi/bug-1319374-THIS-crash.t ++++ b/tests/bugs/gfapi/bug-1319374-THIS-crash.t +@@ -25,3 +25,5 @@ TEST $(dirname $0)/bug-1319374 $H0 $V0 $logdir/bug-1319374.log + cleanup_tester $(dirname $0)/bug-1319374 + + cleanup; ++#G_TESTDEF_TEST_STATUS_CENTOS6=BAD_TEST,BUG=1723673 ++#G_TESTDEF_TEST_STATUS_NETBSD7=BAD_TEST,BUG=1723673 +-- +1.8.3.1 + diff --git a/0217-uss-Fix-tar-issue-with-ctime-and-uss-enabled.patch b/0217-uss-Fix-tar-issue-with-ctime-and-uss-enabled.patch new file mode 100644 index 0000000..055b9f2 --- /dev/null +++ b/0217-uss-Fix-tar-issue-with-ctime-and-uss-enabled.patch @@ -0,0 +1,75 @@ +From 71ff9b7c6356e521d98ee025554b63dd23db9836 Mon Sep 17 00:00:00 2001 +From: Kotresh HR +Date: Thu, 13 Jun 2019 22:43:47 +0530 +Subject: [PATCH 217/221] uss: Fix tar issue with ctime and uss enabled + +Problem: +If ctime and uss enabled, tar still complains with 'file +changed as we read it' + +Cause: +To clear nfs cache (gluster-nfs), the ctime was incremented +in snap-view client on stat cbk. + +Fix: +The ctime should not be incremented manually. Since gluster-nfs +is planning to be deprecated, this code is being removed to +fix the issue. + +Backport of: + > Patch: https://review.gluster.org/22861 + > Change-Id: Iae7f100c20fce880a50b008ba716077350281404 + > fixes: bz#1720290 + > Signed-off-by: Kotresh HR + +Change-Id: Iae7f100c20fce880a50b008ba716077350281404 +BUG: 1709301 +Signed-off-by: Kotresh HR +Reviewed-on: https://code.engineering.redhat.com/gerrit/173922 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + .../features/snapview-client/src/snapview-client.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +diff --git a/xlators/features/snapview-client/src/snapview-client.c b/xlators/features/snapview-client/src/snapview-client.c +index 5d7986c..9c789ae 100644 +--- a/xlators/features/snapview-client/src/snapview-client.c ++++ b/xlators/features/snapview-client/src/snapview-client.c +@@ -577,20 +577,24 @@ gf_svc_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) + { +- /* Consider a testcase: ++ /* TODO: FIX ME ++ * Consider a testcase: + * #mount -t nfs host1:/vol1 /mnt + * #ls /mnt + * #ls /mnt/.snaps (As expected this fails) + * #gluster volume set vol1 features.uss enable +- * Now `ls /mnt/.snaps` should work, +- * but fails with No such file or directory. +- * This is because NFS client caches the list of files in +- * a directory. This cache is updated if there are any changes +- * in the directory attributes. To solve this problem change +- * a attribute 'ctime' when USS is enabled ++ * Now `ls /mnt/.snaps` should work, but fails with No such file or ++ * directory. This is because NFS client (gNFS) caches the list of files ++ * in a directory. This cache is updated if there are any changes in the ++ * directory attributes. So, one way to solve this problem is to change ++ * 'ctime' attribute when USS is enabled as below. ++ * ++ * if (op_ret == 0 && IA_ISDIR(buf->ia_type)) ++ * buf->ia_ctime_nsec++; ++ * ++ * But this is not the ideal solution as applications see the unexpected ++ * ctime change causing failures. + */ +- if (op_ret == 0 && IA_ISDIR(buf->ia_type)) +- buf->ia_ctime_nsec++; + + SVC_STACK_UNWIND(stat, frame, op_ret, op_errno, buf, xdata); + return 0; +-- +1.8.3.1 + diff --git a/0218-graph-shd-Use-glusterfs_graph_deactivate-to-free-the.patch b/0218-graph-shd-Use-glusterfs_graph_deactivate-to-free-the.patch new file mode 100644 index 0000000..b7db655 --- /dev/null +++ b/0218-graph-shd-Use-glusterfs_graph_deactivate-to-free-the.patch @@ -0,0 +1,88 @@ +From 8cc6d8af00303c445b94715c92fe9e3e01edb867 Mon Sep 17 00:00:00 2001 +From: Mohammed Rafi KC +Date: Mon, 24 Jun 2019 15:49:04 +0530 +Subject: [PATCH 218/221] graph/shd: Use glusterfs_graph_deactivate to free the + xl rec + +We were using glusterfs_graph_fini to free the xl rec from +glusterfs_process_volfp as well as glusterfs_graph_cleanup. + +Instead we can use glusterfs_graph_deactivate, which does +fini as well as other common rec free. + +Backport of:https://review.gluster.org/#/c/glusterfs/+/22904/ + +>Change-Id: Ie4a5f2771e5254aa5ed9f00c3672a6d2cc8e4bc1 +>Updates: bz#1716695 +>Signed-off-by: Mohammed Rafi KC + +Change-Id: I09d7124366bc690ceca9e8d0adee8a0dc8081091 +BUG: 1711939 +Signed-off-by: Mohammed Rafi KC +Reviewed-on: https://code.engineering.redhat.com/gerrit/174814 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + libglusterfs/src/graph.c | 2 +- + libglusterfs/src/xlator.c | 9 ++++++++- + xlators/features/shard/src/shard.c | 3 +++ + 3 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c +index 27d9335..5b95fd6 100644 +--- a/libglusterfs/src/graph.c ++++ b/libglusterfs/src/graph.c +@@ -1394,7 +1394,7 @@ glusterfs_graph_cleanup(void *arg) + + pthread_mutex_lock(&ctx->cleanup_lock); + { +- glusterfs_graph_fini(graph); ++ glusterfs_graph_deactivate(graph); + glusterfs_graph_destroy(graph); + } + pthread_mutex_unlock(&ctx->cleanup_lock); +diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c +index 71e1ed4..d9d3441 100644 +--- a/libglusterfs/src/xlator.c ++++ b/libglusterfs/src/xlator.c +@@ -659,6 +659,7 @@ xlator_fini_rec(xlator_t *xl) + trav = trav->next; + } + ++ xl->cleanup_starting = 1; + if (xl->init_succeeded) { + if (xl->fini) { + old_THIS = THIS; +@@ -666,8 +667,14 @@ xlator_fini_rec(xlator_t *xl) + + xl->fini(xl); + +- if (xl->local_pool) ++ if (xl->local_pool) { + mem_pool_destroy(xl->local_pool); ++ xl->local_pool = NULL; ++ } ++ if (xl->itable) { ++ inode_table_destroy(xl->itable); ++ xl->itable = NULL; ++ } + + THIS = old_THIS; + } else { +diff --git a/xlators/features/shard/src/shard.c b/xlators/features/shard/src/shard.c +index b248767..31c7eec 100644 +--- a/xlators/features/shard/src/shard.c ++++ b/xlators/features/shard/src/shard.c +@@ -6785,6 +6785,9 @@ fini(xlator_t *this) + + GF_VALIDATE_OR_GOTO("shard", this, out); + ++ /*Itable was not created by shard, hence setting to NULL.*/ ++ this->itable = NULL; ++ + mem_pool_destroy(this->local_pool); + this->local_pool = NULL; + +-- +1.8.3.1 + diff --git a/0219-posix-add-posix_set_ctime-in-posix_ftruncate.patch b/0219-posix-add-posix_set_ctime-in-posix_ftruncate.patch new file mode 100644 index 0000000..eefb890 --- /dev/null +++ b/0219-posix-add-posix_set_ctime-in-posix_ftruncate.patch @@ -0,0 +1,35 @@ +From d9781ed4964d9e752fc880c8cd8afcbd2c561ebe Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Wed, 26 Jun 2019 15:58:33 +0530 +Subject: [PATCH 219/221] posix : add posix_set_ctime() in posix_ftruncate() + +Upstream references : +> release 6: https://review.gluster.org/#/c/glusterfs/+/22965/ +> mainline: https://review.gluster.org/#/c/glusterfs/+/22948/ + +Change-Id: I0cb5320fea71306e0283509ae47024f23874b53b +fixes: bz#1720163 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://code.engineering.redhat.com/gerrit/174837 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + xlators/storage/posix/src/posix-inode-fd-ops.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c +index fc847d6..c949f68 100644 +--- a/xlators/storage/posix/src/posix-inode-fd-ops.c ++++ b/xlators/storage/posix/src/posix-inode-fd-ops.c +@@ -5059,6 +5059,8 @@ posix_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + goto out; + } + ++ posix_set_ctime(frame, this, NULL, pfd->fd, fd->inode, &postop); ++ + op_ret = 0; + + out: +-- +1.8.3.1 + diff --git a/0220-graph-shd-Use-top-down-approach-while-cleaning-xlato.patch b/0220-graph-shd-Use-top-down-approach-while-cleaning-xlato.patch new file mode 100644 index 0000000..07f702b --- /dev/null +++ b/0220-graph-shd-Use-top-down-approach-while-cleaning-xlato.patch @@ -0,0 +1,190 @@ +From b963fa8bb71963127147d33bf609f439dd5bd107 Mon Sep 17 00:00:00 2001 +From: Mohammed Rafi KC +Date: Thu, 27 Jun 2019 19:17:29 +0530 +Subject: [PATCH 220/221] graph/shd: Use top down approach while cleaning + xlator + +We were cleaning xlator from botton to top, which might +lead to problems when upper xlators trying to access +the xlator object loaded below. + +One such scenario is when fd_unref happens as part of the +fini call which might lead to calling the releasedir to +lower xlator. This will lead to invalid mem access + +Backport of:https://review.gluster.org/#/c/glusterfs/+/22968/ + +>Change-Id: I8a6cb619256fab0b0c01a2d564fc88287c4415a0 +>Updates: bz#1716695 +>Signed-off-by: Mohammed Rafi KC + +Change-Id: I22bbf99e9451183b3e0fe61b57b2440ab4163fe5 +BUG: 1711939 +Signed-off-by: Mohammed Rafi KC +Reviewed-on: https://code.engineering.redhat.com/gerrit/174882 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + libglusterfs/src/graph.c | 10 +++++++++- + xlators/features/bit-rot/src/stub/bit-rot-stub.c | 1 + + xlators/features/changelog/src/changelog.c | 1 + + xlators/features/cloudsync/src/cloudsync.c | 4 +++- + xlators/features/index/src/index.c | 1 + + xlators/features/quiesce/src/quiesce.c | 1 + + xlators/features/read-only/src/worm.c | 1 + + xlators/features/sdfs/src/sdfs.c | 1 + + xlators/features/selinux/src/selinux.c | 2 ++ + xlators/features/trash/src/trash.c | 1 + + 10 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c +index 5b95fd6..172dc61 100644 +--- a/libglusterfs/src/graph.c ++++ b/libglusterfs/src/graph.c +@@ -1193,6 +1193,14 @@ glusterfs_graph_fini(glusterfs_graph_t *graph) + if (trav->init_succeeded) { + trav->cleanup_starting = 1; + trav->fini(trav); ++ if (trav->local_pool) { ++ mem_pool_destroy(trav->local_pool); ++ trav->local_pool = NULL; ++ } ++ if (trav->itable) { ++ inode_table_destroy(trav->itable); ++ trav->itable = NULL; ++ } + trav->init_succeeded = 0; + } + trav = trav->next; +@@ -1394,7 +1402,7 @@ glusterfs_graph_cleanup(void *arg) + + pthread_mutex_lock(&ctx->cleanup_lock); + { +- glusterfs_graph_deactivate(graph); ++ glusterfs_graph_fini(graph); + glusterfs_graph_destroy(graph); + } + pthread_mutex_unlock(&ctx->cleanup_lock); +diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.c b/xlators/features/bit-rot/src/stub/bit-rot-stub.c +index 3f48a4b..03446be 100644 +--- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c ++++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c +@@ -185,6 +185,7 @@ cleanup_lock: + pthread_mutex_destroy(&priv->lock); + free_mempool: + mem_pool_destroy(priv->local_pool); ++ priv->local_pool = NULL; + free_priv: + GF_FREE(priv); + this->private = NULL; +diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c +index d9025f3..2862d1e 100644 +--- a/xlators/features/changelog/src/changelog.c ++++ b/xlators/features/changelog/src/changelog.c +@@ -2790,6 +2790,7 @@ cleanup_options: + changelog_freeup_options(this, priv); + cleanup_mempool: + mem_pool_destroy(this->local_pool); ++ this->local_pool = NULL; + cleanup_priv: + GF_FREE(priv); + error_return: +diff --git a/xlators/features/cloudsync/src/cloudsync.c b/xlators/features/cloudsync/src/cloudsync.c +index 26e512c..0ad987e 100644 +--- a/xlators/features/cloudsync/src/cloudsync.c ++++ b/xlators/features/cloudsync/src/cloudsync.c +@@ -200,8 +200,10 @@ cs_init(xlator_t *this) + + out: + if (ret == -1) { +- if (this->local_pool) ++ if (this->local_pool) { + mem_pool_destroy(this->local_pool); ++ this->local_pool = NULL; ++ } + + cs_cleanup_private(priv); + +diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c +index 2f2a6d0..4ece7ff 100644 +--- a/xlators/features/index/src/index.c ++++ b/xlators/features/index/src/index.c +@@ -2478,6 +2478,7 @@ out: + GF_FREE(priv); + this->private = NULL; + mem_pool_destroy(this->local_pool); ++ this->local_pool = NULL; + } + + if (attr_inited) +diff --git a/xlators/features/quiesce/src/quiesce.c b/xlators/features/quiesce/src/quiesce.c +index bfd1116..06f58c9 100644 +--- a/xlators/features/quiesce/src/quiesce.c ++++ b/xlators/features/quiesce/src/quiesce.c +@@ -2536,6 +2536,7 @@ fini(xlator_t *this) + this->private = NULL; + + mem_pool_destroy(priv->local_pool); ++ priv->local_pool = NULL; + LOCK_DESTROY(&priv->lock); + GF_FREE(priv); + out: +diff --git a/xlators/features/read-only/src/worm.c b/xlators/features/read-only/src/worm.c +index 24196f8..7d13180 100644 +--- a/xlators/features/read-only/src/worm.c ++++ b/xlators/features/read-only/src/worm.c +@@ -569,6 +569,7 @@ fini(xlator_t *this) + mem_put(priv); + this->private = NULL; + mem_pool_destroy(this->local_pool); ++ this->local_pool = NULL; + out: + return; + } +diff --git a/xlators/features/sdfs/src/sdfs.c b/xlators/features/sdfs/src/sdfs.c +index f0247fd..164c632 100644 +--- a/xlators/features/sdfs/src/sdfs.c ++++ b/xlators/features/sdfs/src/sdfs.c +@@ -1429,6 +1429,7 @@ void + fini(xlator_t *this) + { + mem_pool_destroy(this->local_pool); ++ this->local_pool = NULL; + return; + } + +diff --git a/xlators/features/selinux/src/selinux.c b/xlators/features/selinux/src/selinux.c +index 58b4c5d..ce5fc90 100644 +--- a/xlators/features/selinux/src/selinux.c ++++ b/xlators/features/selinux/src/selinux.c +@@ -256,6 +256,7 @@ out: + GF_FREE(priv); + } + mem_pool_destroy(this->local_pool); ++ this->local_pool = NULL; + } + return ret; + } +@@ -284,6 +285,7 @@ fini(xlator_t *this) + GF_FREE(priv); + + mem_pool_destroy(this->local_pool); ++ this->local_pool = NULL; + + return; + } +diff --git a/xlators/features/trash/src/trash.c b/xlators/features/trash/src/trash.c +index d668436..eb5007b 100644 +--- a/xlators/features/trash/src/trash.c ++++ b/xlators/features/trash/src/trash.c +@@ -2523,6 +2523,7 @@ out: + GF_FREE(priv); + } + mem_pool_destroy(this->local_pool); ++ this->local_pool = NULL; + } + return ret; + } +-- +1.8.3.1 + diff --git a/0221-protocol-client-propagte-GF_EVENT_CHILD_PING-only-fo.patch b/0221-protocol-client-propagte-GF_EVENT_CHILD_PING-only-fo.patch new file mode 100644 index 0000000..74e3796 --- /dev/null +++ b/0221-protocol-client-propagte-GF_EVENT_CHILD_PING-only-fo.patch @@ -0,0 +1,75 @@ +From ac216eae4775f7d95877b247937e2a4a4828b1b2 Mon Sep 17 00:00:00 2001 +From: Raghavendra G +Date: Tue, 4 Jun 2019 19:22:45 +0530 +Subject: [PATCH 221/221] protocol/client: propagte GF_EVENT_CHILD_PING only + for connections to brick + +Two reasons: +* ping responses from glusterd may not be relevant for Halo + replication. Instead, it might be interested in only knowing whether + the brick itself is responsive. +* When a brick is killed, propagating GF_EVENT_CHILD_PING of ping + response from glusterd results in GF_EVENT_DISCONNECT spuriously + propagated to parent xlators. These DISCONNECT events are from the + connections client establishes with glusterd as part of its + reconnect logic. Without GF_EVENT_CHILD_PING, the last event + propagated to parent xlators would be the first DISCONNECT event + from brick and hence subsequent DISCONNECTS to glusterd are not + propagated as protocol/client prevents same event being propagated + to parent xlators consecutively. propagating GF_EVENT_CHILD_PING for + ping responses from glusterd would change the last_sent_event to + GF_EVENT_CHILD_PING and hence protocol/client cannot prevent + subsequent DISCONNECT events + +>Signed-off-by: Raghavendra G +>Fixes: bz#1716979 +>Change-Id: I50276680c52f05ca9e12149a3094923622d6eaef + +Upstream Patch: https://review.gluster.org/#/c/glusterfs/+/22821/ + +BUG: 1703423 +Change-Id: I50276680c52f05ca9e12149a3094923622d6eaef +Signed-off-by: Sunil Kumar Acharya +Reviewed-on: https://code.engineering.redhat.com/gerrit/174883 +Tested-by: RHGS Build Bot +--- + xlators/protocol/client/src/client.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c +index a372807..95e4be5 100644 +--- a/xlators/protocol/client/src/client.c ++++ b/xlators/protocol/client/src/client.c +@@ -2276,6 +2276,12 @@ client_mark_fd_bad(xlator_t *this) + return 0; + } + ++static int ++is_connection_to_brick(struct rpc_clnt *rpc) ++{ ++ return (rpc->conn.config.remote_port != 0); ++} ++ + int + client_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, + void *data) +@@ -2297,10 +2303,12 @@ client_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, + + switch (event) { + case RPC_CLNT_PING: { +- ret = default_notify(this, GF_EVENT_CHILD_PING, data); +- if (ret) +- gf_log(this->name, GF_LOG_INFO, "CHILD_PING notify failed"); +- conf->last_sent_event = GF_EVENT_CHILD_PING; ++ if (is_connection_to_brick(rpc)) { ++ ret = default_notify(this, GF_EVENT_CHILD_PING, data); ++ if (ret) ++ gf_log(this->name, GF_LOG_INFO, "CHILD_PING notify failed"); ++ conf->last_sent_event = GF_EVENT_CHILD_PING; ++ } + break; + } + case RPC_CLNT_CONNECT: { +-- +1.8.3.1 + diff --git a/glusterfs.spec b/glusterfs.spec index 1a6a5ca..bd8a608 100644 --- a/glusterfs.spec +++ b/glusterfs.spec @@ -231,7 +231,7 @@ Release: 0.1%{?prereltag:.%{prereltag}}%{?dist} %else Name: glusterfs Version: 6.0 -Release: 6%{?dist} +Release: 7%{?dist} ExcludeArch: i686 %endif License: GPLv2 or LGPLv3+ @@ -303,6 +303,9 @@ Obsoletes: %{name}-ufo %if ( 0%{!?_with_gnfs:1} ) Obsoletes: %{name}-gnfs %endif +%if ( 0%{?rhel} < 7 ) +Obsoletes: %{name}-ganesha +%endif Provides: %{name}-common = %{version}-%{release} Provides: %{name}-core = %{version}-%{release} @@ -498,6 +501,35 @@ Patch0189: 0189-features-shard-Fix-block-count-accounting-upon-trunc.patch Patch0190: 0190-Build-removing-the-hardcoded-usage-of-python3.patch Patch0191: 0191-Build-Update-python-shebangs-based-on-version.patch Patch0192: 0192-build-Ensure-gluster-cli-package-is-built-as-part-of.patch +Patch0193: 0193-spec-fixed-python-dependency-for-rhel6.patch +Patch0194: 0194-stack-Make-sure-to-have-unique-call-stacks-in-all-ca.patch +Patch0195: 0195-build-package-glusterfs-ganesha-for-rhel7-and-above.patch +Patch0196: 0196-posix-ctime-Fix-ctime-upgrade-issue.patch +Patch0197: 0197-posix-fix-crash-in-posix_cs_set_state.patch +Patch0198: 0198-cluster-ec-Prevent-double-pre-op-xattrops.patch +Patch0199: 0199-upcall-Avoid-sending-notifications-for-invalid-inode.patch +Patch0200: 0200-gfapi-fix-incorrect-initialization-of-upcall-syncop-.patch +Patch0201: 0201-geo-rep-Fix-permissions-for-GEOREP_DIR-in-non-root-s.patch +Patch0202: 0202-shd-mux-Fix-race-between-mux_proc-unlink-and-stop.patch +Patch0203: 0203-glusterd-shd-Change-shd-logfile-to-a-unique-name.patch +Patch0204: 0204-glusterd-conditionally-clear-txn_opinfo-in-stage-op.patch +Patch0205: 0205-glusterd-Can-t-run-rebalance-due-to-long-unix-socket.patch +Patch0206: 0206-glusterd-ignore-user.-options-from-compatibility-che.patch +Patch0207: 0207-glusterd-fix-use-after-free-of-a-dict_t.patch +Patch0208: 0208-mem-pool-remove-dead-code.patch +Patch0209: 0209-core-avoid-dynamic-TLS-allocation-when-possible.patch +Patch0210: 0210-mem-pool.-c-h-minor-changes.patch +Patch0211: 0211-libglusterfs-Fix-compilation-when-disable-mempool-is.patch +Patch0212: 0212-core-fix-memory-allocation-issues.patch +Patch0213: 0213-cluster-dht-Strip-out-dht-xattrs.patch +Patch0214: 0214-geo-rep-Upgrading-config-file-to-new-version.patch +Patch0215: 0215-posix-modify-storage.reserve-option-to-take-size-and.patch +Patch0216: 0216-Test-case-fixe-for-downstream-3.5.0.patch +Patch0217: 0217-uss-Fix-tar-issue-with-ctime-and-uss-enabled.patch +Patch0218: 0218-graph-shd-Use-glusterfs_graph_deactivate-to-free-the.patch +Patch0219: 0219-posix-add-posix_set_ctime-in-posix_ftruncate.patch +Patch0220: 0220-graph-shd-Use-top-down-approach-while-cleaning-xlato.patch +Patch0221: 0221-protocol-client-propagte-GF_EVENT_CHILD_PING-only-fo.patch %description GlusterFS is a distributed file-system capable of scaling to several @@ -646,7 +678,7 @@ is in user space and easily manageable. This package provides support to FUSE based clients and inlcudes the glusterfs(d) binary. -%if ( 0%{!?_without_server:1} ) +%if ( 0%{!?_without_server:1} && 0%{?rhel} > 6 ) %package ganesha Summary: NFS-Ganesha configuration Group: Applications/File @@ -694,7 +726,11 @@ Summary: GlusterFS Geo-replication Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}-server%{?_isa} = %{version}-%{release} Requires: python%{_pythonver} +%if ( 0%{?rhel} && 0%{?rhel} < 7 ) +Requires: python-prettytable +%else Requires: python%{_pythonver}-prettytable +%endif Requires: python%{_pythonver}-gluster = %{version}-%{release} Requires: rsync @@ -1118,7 +1154,7 @@ install -D -p -m 0644 extras/glusterfs-logrotate \ %{buildroot}%{_sysconfdir}/logrotate.d/glusterfs # ganesha ghosts -%if ( 0%{!?_without_server:1} ) +%if ( 0%{!?_without_server:1} && 0%{?rhel} > 6 ) mkdir -p %{buildroot}%{_sysconfdir}/ganesha touch %{buildroot}%{_sysconfdir}/ganesha/ganesha-ha.conf mkdir -p %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ @@ -1428,11 +1464,14 @@ exit 0 %endif %endif -%if ( 0%{?_without_server:1} ) -#exclude ganesha related files +%if ( 0%{?_without_server:1} || 0%{?rhel} < 7 ) +#exclude ganesha related files for rhel 6 and client builds %exclude %{_sysconfdir}/ganesha/ganesha-ha.conf.sample %exclude %{_libexecdir}/ganesha/* %exclude %{_prefix}/lib/ocf/resource.d/heartbeat/* +%if ( 0%{!?_without_server:1} ) +%{_sharedstatedir}/glusterd/hooks/1/start/post/S31ganesha-start.sh +%endif %endif %exclude %{_datadir}/glusterfs/scripts/setup-thin-arbiter.sh @@ -1587,7 +1626,7 @@ exit 0 %exclude %{_datadir}/glusterfs/tests/vagrant %endif -%if ( 0%{!?_without_server:1} ) +%if ( 0%{!?_without_server:1} && 0%{?rhel} > 6 ) %files ganesha %dir %{_libexecdir}/ganesha %{_sysconfdir}/ganesha/ganesha-ha.conf.sample @@ -2199,6 +2238,12 @@ fi %endif %changelog +* Fri Jun 28 2019 Sunil Kumar Acharya - 6.0-7 +- fixes bugs bz#1573077 bz#1600918 bz#1703423 bz#1704207 bz#1708064 + bz#1709301 bz#1713664 bz#1716760 bz#1717784 bz#1720163 bz#1720192 + bz#1720551 bz#1721351 bz#1721357 bz#1721477 bz#1722131 bz#1722331 + bz#1722509 bz#1722801 bz#1720248 + * Fri Jun 14 2019 Sunil Kumar Acharya - 6.0-6 - fixes bugs bz#1668001 bz#1708043 bz#1708183 bz#1710701 bz#1719640 bz#1720079 bz#1720248 bz#1720318 bz#1720461