From 1f2f23ddef47251a8a8b9b3adcc0877186391fea Mon Sep 17 00:00:00 2001 From: Milind Changire Date: Tue, 18 Dec 2018 11:23:13 -0500 Subject: [PATCH] autobuild v3.12.2-33 Resolves: bz#1350745 bz#1362129 bz#1541568 bz#1597252 bz#1599220 Resolves: bz#1633177 bz#1637564 bz#1639476 bz#1639568 bz#1643370 Resolves: bz#1645480 bz#1648296 bz#1648893 bz#1651040 bz#1651460 Resolves: bz#1652466 bz#1652537 bz#1653224 bz#1653613 bz#1654103 Resolves: bz#1654161 bz#1655385 bz#1655578 bz#1656357 bz#1659439 Signed-off-by: Milind Changire --- 0456-Update-rfc.sh-to-rhgs-3.4.3.patch | 27 + ...t-sync-brick-root-perms-on-add-brick.patch | 122 ++ 0458-glusterd-fix-crash.patch | 42 + 0459-glfsheal-add-a-nolog-flag.patch | 223 ++ ...g-confirmation-message-in-peer-detac.patch | 74 + ...upport-for-multi-threaded-fuse-reade.patch | 835 ++++++++ ...Do-not-log-ENXIO-errors-for-seek-fop.patch | 62 + ...spec-.in-firewalld-file-doesn-t-use-.patch | 58 + 0464-build-exclude-packaging-crypt.so.patch | 37 + ...issing-explicit-package-dependencies.patch | 84 + ...-distributed-virt-for-single-brick-o.patch | 86 + ...d-to-regenerate-volfiles-when-GD_OP_.patch | 304 +++ ...invalid-port-logs-to-DEBUG-log-level.patch | 40 + ...every-inode-looked-up-nfs3_fh_resolv.patch | 48 + ...after-free-in-dht_rmdir_readdirp_cbk.patch | 87 + ...ng-profile-commands-to-mgmt_v3-frame.patch | 507 +++++ ...duce-a-new-op-version-for-rhgs-3.4.3.patch | 72 + 0473-rpc-bump-up-server.event-threads.patch | 64 + ...te_cbk-should-read-fd-from-local-con.patch | 45 + ...form-store-operation-in-cleanup-lock.patch | 175 ++ ...-afr-add-checks-for-allowing-lookups.patch | 610 ++++++ ...-rcu_read_lock-unlock-under-cleanup_.patch | 1808 +++++++++++++++++ ...-memory-corruption-caused-by-per-thr.patch | 289 +++ ...ure-pacemaker-is-enabled-after-setup.patch | 51 + ...ke-slave-volume-read-only-by-default.patch | 101 + ...not-blindly-remove-volume-share-from.patch | 102 + ...eral-improvements-to-S30samba-start..patch | 91 + ...add-volume-share-section-to-smb.conf.patch | 86 + ...-volume-set-command-for-Samba-integr.patch | 84 + ...nt-volume-create-without-redundant-b.patch | 60 + ...ormance-rda-Fixed-dict_t-memory-leak.patch | 51 + ...cking-of-mem_pool-that-requested-the.patch | 270 +++ ...w-lookup-on-root-if-it-is-from-ADD_R.patch | 459 +++++ ...ot-update-read_subvol-in-inode_ctx-a.patch | 91 + ...ng-rebalance-commands-to-mgmt_v3-fra.patch | 921 +++++++++ ...alance-mgmt_v3-command-to-op-version.patch | 56 + ...k-glusterfs_ctx_t-in-struct-mem_pool.patch | 282 +++ ...count-allocations-done-per-user-pool.patch | 96 + glusterfs.spec | 62 +- 39 files changed, 8558 insertions(+), 4 deletions(-) create mode 100644 0456-Update-rfc.sh-to-rhgs-3.4.3.patch create mode 100644 0457-cluster-dht-sync-brick-root-perms-on-add-brick.patch create mode 100644 0458-glusterd-fix-crash.patch create mode 100644 0459-glfsheal-add-a-nolog-flag.patch create mode 100644 0460-cli-add-a-warning-confirmation-message-in-peer-detac.patch create mode 100644 0461-mount-fuse-Add-support-for-multi-threaded-fuse-reade.patch create mode 100644 0462-posix-Do-not-log-ENXIO-errors-for-seek-fop.patch create mode 100644 0463-build-glusterfs.spec-.in-firewalld-file-doesn-t-use-.patch create mode 100644 0464-build-exclude-packaging-crypt.so.patch create mode 100644 0465-build-add-missing-explicit-package-dependencies.patch create mode 100644 0466-extras-Add-group-distributed-virt-for-single-brick-o.patch create mode 100644 0467-glusterd-glusterd-to-regenerate-volfiles-when-GD_OP_.patch create mode 100644 0468-core-move-invalid-port-logs-to-DEBUG-log-level.patch create mode 100644 0469-nfs-set-ctx-for-every-inode-looked-up-nfs3_fh_resolv.patch create mode 100644 0470-dht-fix-use-after-free-in-dht_rmdir_readdirp_cbk.patch create mode 100644 0471-glusterd-migrating-profile-commands-to-mgmt_v3-frame.patch create mode 100644 0472-glusterd-introduce-a-new-op-version-for-rhgs-3.4.3.patch create mode 100644 0473-rpc-bump-up-server.event-threads.patch create mode 100644 0474-afr-open_ftruncate_cbk-should-read-fd-from-local-con.patch create mode 100644 0475-glusterd-perform-store-operation-in-cleanup-lock.patch create mode 100644 0476-afr-add-checks-for-allowing-lookups.patch create mode 100644 0477-glusterd-perform-rcu_read_lock-unlock-under-cleanup_.patch create mode 100644 0478-libglusterfs-fix-memory-corruption-caused-by-per-thr.patch create mode 100644 0479-ganesha-ha-ensure-pacemaker-is-enabled-after-setup.patch create mode 100644 0480-geo-rep-Make-slave-volume-read-only-by-default.patch create mode 100644 0481-extras-hooks-Do-not-blindly-remove-volume-share-from.patch create mode 100644 0482-extras-hooks-General-improvements-to-S30samba-start..patch create mode 100644 0483-Do-not-blindly-add-volume-share-section-to-smb.conf.patch create mode 100644 0484-extras-New-group-volume-set-command-for-Samba-integr.patch create mode 100644 0485-cluster-ec-Prevent-volume-create-without-redundant-b.patch create mode 100644 0486-performance-rda-Fixed-dict_t-memory-leak.patch create mode 100644 0487-mem-pool-add-tracking-of-mem_pool-that-requested-the.patch create mode 100644 0488-cluster-afr-Allow-lookup-on-root-if-it-is-from-ADD_R.patch create mode 100644 0489-cluster-afr-Do-not-update-read_subvol-in-inode_ctx-a.patch create mode 100644 0490-glusterd-migrating-rebalance-commands-to-mgmt_v3-fra.patch create mode 100644 0491-glusterd-tag-rebalance-mgmt_v3-command-to-op-version.patch create mode 100644 0492-mem-pool-track-glusterfs_ctx_t-in-struct-mem_pool.patch create mode 100644 0493-mem-pool-count-allocations-done-per-user-pool.patch diff --git a/0456-Update-rfc.sh-to-rhgs-3.4.3.patch b/0456-Update-rfc.sh-to-rhgs-3.4.3.patch new file mode 100644 index 0000000..bf8fb6d --- /dev/null +++ b/0456-Update-rfc.sh-to-rhgs-3.4.3.patch @@ -0,0 +1,27 @@ +From cd5b8a65ea1df291d936bda1f2514cc5805d4209 Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Tue, 11 Dec 2018 12:57:44 +0530 +Subject: [PATCH 456/493] Update rfc.sh to rhgs-3.4.3 + +Change-Id: Ida4e354010cf83aa121baa02a2d071ccb8867fc7 +Signed-off-by: Milind Changire +--- + rfc.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rfc.sh b/rfc.sh +index 5b09aad..bd52851 100755 +--- a/rfc.sh ++++ b/rfc.sh +@@ -17,7 +17,7 @@ done + shift $((OPTIND-1)) + + +-branch="rhgs-3.4.2"; ++branch="rhgs-3.4.3"; + + set_hooks_commit_msg() + { +-- +1.8.3.1 + diff --git a/0457-cluster-dht-sync-brick-root-perms-on-add-brick.patch b/0457-cluster-dht-sync-brick-root-perms-on-add-brick.patch new file mode 100644 index 0000000..cf819fa --- /dev/null +++ b/0457-cluster-dht-sync-brick-root-perms-on-add-brick.patch @@ -0,0 +1,122 @@ +From aad0d32376e6ca56770e5c2d4dc5a1462b1e7167 Mon Sep 17 00:00:00 2001 +From: N Balachandran +Date: Thu, 13 Dec 2018 12:06:10 +0530 +Subject: [PATCH 457/493] cluster/dht: sync brick root perms on add brick + +If a single brick is added to the volume and the +newly added brick is the first to respond to a +dht_revalidate call, its stbuf will not be merged +into local->stbuf as the brick does not yet have +a layout. The is_permission_different check therefore +fails to detect that an attr heal is required as it +only considers the stbuf values from existing bricks. +To fix this, merge all stbuf values into local->stbuf +and use local->prebuf to store the correct directory +attributes. + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/21611/ + +> Change-Id: Ic9e8b04a1ab9ed1248b6b056e3450bbafe32e1bc +> fixes: bz#1648298 +> Signed-off-by: N Balachandran + +Change-Id: I329ce48555d15f741d7247290e749f0800d12df8 +BUG: 1648296 +Signed-off-by: N Balachandran +Reviewed-on: https://code.engineering.redhat.com/gerrit/158493 +Tested-by: RHGS Build Bot +Reviewed-by: Susant Palai +Reviewed-by: Raghavendra Gowdappa +--- + tests/bugs/distribute/bug-1368012.t | 11 +++++------ + xlators/cluster/dht/src/dht-common.c | 26 ++++++++------------------ + 2 files changed, 13 insertions(+), 24 deletions(-) + +diff --git a/tests/bugs/distribute/bug-1368012.t b/tests/bugs/distribute/bug-1368012.t +index b861554..0b62635 100644 +--- a/tests/bugs/distribute/bug-1368012.t ++++ b/tests/bugs/distribute/bug-1368012.t +@@ -15,7 +15,7 @@ TEST pidof glusterd; + TEST $CLI volume info; + + ## Lets create volume +-TEST $CLI volume create $V0 $H0:/${V0}{1,2}; ++TEST $CLI volume create $V0 $H0:$B0/${V0}{1,2}; + + ## Verify volume is created + EXPECT "$V0" volinfo_field $V0 'Volume Name'; +@@ -36,17 +36,16 @@ TEST chmod 444 $M0 + TEST permission_root=`stat -c "%A" $M0` + TEST echo $permission_root + #Add-brick +-TEST $CLI volume add-brick $V0 $H0:/${V0}3 ++TEST $CLI volume add-brick $V0 $H0:$B0/${V0}3 + EXPECT_WITHIN $PROCESS_UP_TIMEOUT "3" online_brick_count + + #Allow one lookup to happen +-TEST pushd $M0 +-TEST ls ++TEST ls $M0 + #Generate another lookup + echo 3 > /proc/sys/vm/drop_caches +-TEST ls ++TEST ls $M0 + #check root permission + EXPECT_WITHIN "5" $permission_root get_permission $M0 + #check permission on the new-brick +-EXPECT $permission_root get_permission /${V0}3 ++EXPECT $permission_root get_permission $B0/${V0}3 + cleanup +diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c +index d3a0c8b..2e19036 100644 +--- a/xlators/cluster/dht/src/dht-common.c ++++ b/xlators/cluster/dht/src/dht-common.c +@@ -1717,14 +1717,17 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + if (is_dir) { + ret = dht_dir_has_layout (xattr, conf->xattr_name); + if (ret >= 0) { +- if (is_greater_time(local->stbuf.ia_ctime, +- local->stbuf.ia_ctime_nsec, ++ if (is_greater_time(local->prebuf.ia_ctime, ++ local->prebuf.ia_ctime_nsec, + stbuf->ia_ctime, + stbuf->ia_ctime_nsec)) { + /* Choose source */ + local->prebuf.ia_gid = stbuf->ia_gid; + local->prebuf.ia_uid = stbuf->ia_uid; + ++ local->prebuf.ia_ctime = stbuf->ia_ctime; ++ local->prebuf.ia_ctime_nsec = stbuf->ia_ctime_nsec; ++ + if (__is_root_gfid (stbuf->ia_gfid)) + local->prebuf.ia_prot = stbuf->ia_prot; + } +@@ -1792,22 +1795,9 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + } + } + +- +- /* Update stbuf from the servers where layout is present. This +- * is an indication that the server is not a newly added brick. +- * Merging stbuf from newly added brick may result in the added +- * brick being the source of heal for uid/gid */ +- if (!is_dir || (is_dir && +- dht_dir_has_layout (xattr, conf->xattr_name) >= 0) +- || conf->subvolume_cnt == 1) { +- +- dht_iatt_merge (this, &local->stbuf, stbuf, prev); +- dht_iatt_merge (this, &local->postparent, postparent, +- prev); +- } else { +- /* copy the gfid anyway */ +- gf_uuid_copy (local->stbuf.ia_gfid, stbuf->ia_gfid); +- } ++ gf_uuid_copy (local->stbuf.ia_gfid, stbuf->ia_gfid); ++ dht_iatt_merge (this, &local->stbuf, stbuf, prev); ++ dht_iatt_merge (this, &local->postparent, postparent, prev); + + local->op_ret = 0; + +-- +1.8.3.1 + diff --git a/0458-glusterd-fix-crash.patch b/0458-glusterd-fix-crash.patch new file mode 100644 index 0000000..3ffd65e --- /dev/null +++ b/0458-glusterd-fix-crash.patch @@ -0,0 +1,42 @@ +From 3a1484c401d4293531c80532fa96c2f7cfc8aa2d Mon Sep 17 00:00:00 2001 +From: Sanju Rakonde +Date: Wed, 19 Sep 2018 19:49:51 +0530 +Subject: [PATCH 458/493] glusterd: fix crash + +When huge number of volumes are created, glusterd crash is seen. +With the core dump, got to know that mgmt_lock_timer became NULL. +Adding a null check for the same, need to explore about the root +cause. + +>updates: bz#1630922 +>Change-Id: I0770063fcbbbf4b24bef29e94b857b20bdfb5b85 +>Signed-off-by: Sanju Rakonde + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/21228/ + +Change-Id: I0770063fcbbbf4b24bef29e94b857b20bdfb5b85 +BUG: 1599220 +Signed-off-by: Sanju Rakonde +Reviewed-on: https://code.engineering.redhat.com/gerrit/158542 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + xlators/mgmt/glusterd/src/glusterd-locks.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-locks.c b/xlators/mgmt/glusterd/src/glusterd-locks.c +index d75452d..d62d9dd 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-locks.c ++++ b/xlators/mgmt/glusterd/src/glusterd-locks.c +@@ -890,7 +890,7 @@ glusterd_mgmt_v3_unlock (const char *name, uuid_t uuid, char *type) + type, name); + + /* Release owner reference which was held during lock */ +- if (mgmt_lock_timer->timer) { ++ if (mgmt_lock_timer && mgmt_lock_timer->timer) { + ret = -1; + mgmt_lock_timer_xl = mgmt_lock_timer->xl; + GF_VALIDATE_OR_GOTO (this->name, mgmt_lock_timer_xl, out); +-- +1.8.3.1 + diff --git a/0459-glfsheal-add-a-nolog-flag.patch b/0459-glfsheal-add-a-nolog-flag.patch new file mode 100644 index 0000000..8e2837f --- /dev/null +++ b/0459-glfsheal-add-a-nolog-flag.patch @@ -0,0 +1,223 @@ +From 1637d5018aeea96efc2916afe162c4905ef2c2d9 Mon Sep 17 00:00:00 2001 +From: Ravishankar N +Date: Fri, 14 Dec 2018 12:48:05 +0530 +Subject: [PATCH 459/493] glfsheal: add a '--nolog' flag + +(Upstream master patch: https://review.gluster.org/#/c/glusterfs/+/21501/) + +....and if set, change the log level to GF_LOG_NONE. This is useful for +monitoring applications which invoke the heal info set of commands once +every minute, leading to un-necessary glfsheal* logs in +/var/log/glusterfs/. For example, we can now run + +`gluster volume heal info --nolog` +`gluster volume heal info split-brain --nolog` etc. + +The default log level is still retained at GF_LOG_INFO. + +The patch also changes glfsheal internally to accept '--xml' instead of 'xml'. +Note: The --nolog flag is *not* displayed in the help anywhere, for the +sake of consistency in how the other flags are not displayed anywhere in +the help. + +Change-Id: I932d0f79070880b0f9ca87e164d3c2a3b831c8c4 +BUG: 1579293 +Signed-off-by: Ravishankar N +Reviewed-on: https://code.engineering.redhat.com/gerrit/158640 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + cli/src/cli-cmd-volume.c | 8 ++++--- + cli/src/cli.c | 5 ++++ + cli/src/cli.h | 1 + + heal/src/glfs-heal.c | 59 ++++++++++++++++++++++++++++++++++++------------ + 4 files changed, 56 insertions(+), 17 deletions(-) + +diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c +index 32efa73..8fca7eb 100644 +--- a/cli/src/cli-cmd-volume.c ++++ b/cli/src/cli-cmd-volume.c +@@ -2830,7 +2830,7 @@ cli_launch_glfs_heal (int heal_op, dict_t *options) + switch (heal_op) { + case GF_SHD_OP_INDEX_SUMMARY: + if (global_state->mode & GLUSTER_MODE_XML) { +- runner_add_args (&runner, "xml", NULL); ++ runner_add_args (&runner, "--xml", NULL); + } + break; + case GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE: +@@ -2854,7 +2854,7 @@ cli_launch_glfs_heal (int heal_op, dict_t *options) + case GF_SHD_OP_SPLIT_BRAIN_FILES: + runner_add_args (&runner, "split-brain-info", NULL); + if (global_state->mode & GLUSTER_MODE_XML) { +- runner_add_args (&runner, "xml", NULL); ++ runner_add_args (&runner, "--xml", NULL); + } + break; + case GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE: +@@ -2864,12 +2864,14 @@ cli_launch_glfs_heal (int heal_op, dict_t *options) + case GF_SHD_OP_HEAL_SUMMARY: + runner_add_args (&runner, "info-summary", NULL); + if (global_state->mode & GLUSTER_MODE_XML) { +- runner_add_args (&runner, "xml", NULL); ++ runner_add_args (&runner, "--xml", NULL); + } + break; + default: + ret = -1; + } ++ if (global_state->mode & GLUSTER_MODE_GLFSHEAL_NOLOG) ++ runner_add_args(&runner, "--nolog", NULL); + ret = runner_start (&runner); + if (ret == -1) + goto out; +diff --git a/cli/src/cli.c b/cli/src/cli.c +index b64d4ef..3fd7bc5 100644 +--- a/cli/src/cli.c ++++ b/cli/src/cli.c +@@ -340,6 +340,11 @@ cli_opt_parse (char *opt, struct cli_state *state) + return 0; + } + ++ if (strcmp(opt, "nolog") == 0) { ++ state->mode |= GLUSTER_MODE_GLFSHEAL_NOLOG; ++ return 0; ++ } ++ + if (strcmp (opt, "wignore-partition") == 0) { + state->mode |= GLUSTER_MODE_WIGNORE_PARTITION; + return 0; +diff --git a/cli/src/cli.h b/cli/src/cli.h +index 109dcd4..104d601 100644 +--- a/cli/src/cli.h ++++ b/cli/src/cli.h +@@ -61,6 +61,7 @@ typedef enum { + #define GLUSTER_MODE_XML (1 << 2) + #define GLUSTER_MODE_WIGNORE (1 << 3) + #define GLUSTER_MODE_WIGNORE_PARTITION (1 << 4) ++#define GLUSTER_MODE_GLFSHEAL_NOLOG (1 << 5) + + + #define GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH(abspath, volname, path) do { \ +diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c +index 153cd29..12746dc 100644 +--- a/heal/src/glfs-heal.c ++++ b/heal/src/glfs-heal.c +@@ -40,6 +40,9 @@ xmlDocPtr glfsh_doc = NULL; + ret = 0; \ + } while (0) \ + ++#define MODE_XML (1 << 0) ++#define MODE_NO_LOG (1 << 1) ++ + typedef struct num_entries { + uint64_t num_entries; + uint64_t pending_entries; +@@ -1434,6 +1437,28 @@ out: + return ret; + } + ++static void ++parse_flags(int *argc, char **argv, int *flags) ++{ ++ int i = 0; ++ char *opt = NULL; ++ int count = 0; ++ ++ for (i = 0; i < *argc; i++) { ++ opt = strtail(argv[i], "--"); ++ if (!opt) ++ continue; ++ if (strcmp(opt, "nolog") == 0) { ++ *flags |= MODE_NO_LOG; ++ count++; ++ } else if (strcmp(opt, "xml") == 0) { ++ *flags |= MODE_XML; ++ count++; ++ } ++ } ++ *argc = *argc - count; ++} ++ + int + glfsh_heal_from_bigger_file_or_mtime (glfs_t *fs, xlator_t *top_subvol, + loc_t *rootloc, char *file, +@@ -1518,6 +1543,8 @@ main (int argc, char **argv) + char *file = NULL; + char *op_errstr = NULL; + gf_xl_afr_op_t heal_op = -1; ++ gf_loglevel_t log_level = GF_LOG_INFO; ++ int flags = 0; + + if (argc < 2) { + printf (USAGE_STR, argv[0]); +@@ -1526,6 +1553,13 @@ main (int argc, char **argv) + } + + volname = argv[1]; ++ ++ parse_flags(&argc, argv, &flags); ++ if (flags & MODE_NO_LOG) ++ log_level = GF_LOG_NONE; ++ if (flags & MODE_XML) ++ is_xml = 1; ++ + switch (argc) { + case 2: + heal_op = GF_SHD_OP_INDEX_SUMMARY; +@@ -1533,9 +1567,6 @@ main (int argc, char **argv) + case 3: + if (!strcmp (argv[2], "split-brain-info")) { + heal_op = GF_SHD_OP_SPLIT_BRAIN_FILES; +- } else if (!strcmp (argv[2], "xml")) { +- heal_op = GF_SHD_OP_INDEX_SUMMARY; +- is_xml = 1; + } else if (!strcmp (argv[2], "granular-entry-heal-op")) { + heal_op = GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE; + } else if (!strcmp (argv[2], "info-summary")) { +@@ -1547,15 +1578,7 @@ main (int argc, char **argv) + } + break; + case 4: +- if ((!strcmp (argv[2], "split-brain-info")) +- && (!strcmp (argv[3], "xml"))) { +- heal_op = GF_SHD_OP_SPLIT_BRAIN_FILES; +- is_xml = 1; +- } else if ((!strcmp (argv[2], "info-summary")) +- && (!strcmp (argv[3], "xml"))) { +- heal_op = GF_SHD_OP_HEAL_SUMMARY; +- is_xml = 1; +- } else if (!strcmp (argv[2], "bigger-file")) { ++ if (!strcmp (argv[2], "bigger-file")) { + heal_op = GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE; + file = argv[3]; + } else if (!strcmp (argv[2], "latest-mtime")) { +@@ -1592,7 +1615,15 @@ main (int argc, char **argv) + glfsh_output = &glfsh_human_readable; + if (is_xml) { + #if (HAVE_LIB_XML) +- glfsh_output = &glfsh_xml_output; ++ if ((heal_op == GF_SHD_OP_INDEX_SUMMARY) || ++ (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) || ++ (heal_op == GF_SHD_OP_HEAL_SUMMARY)) { ++ glfsh_output = &glfsh_xml_output; ++ } else { ++ printf(USAGE_STR, argv[0]); ++ ret = -1; ++ goto out; ++ } + #else + /*No point doing anything, just fail the command*/ + exit (EXIT_FAILURE); +@@ -1636,7 +1667,7 @@ main (int argc, char **argv) + } + snprintf (logfilepath, sizeof (logfilepath), + DEFAULT_HEAL_LOG_FILE_DIRECTORY"/glfsheal-%s.log", volname); +- ret = glfs_set_logging(fs, logfilepath, GF_LOG_INFO); ++ ret = glfs_set_logging(fs, logfilepath, log_level); + if (ret < 0) { + ret = -errno; + gf_asprintf (&op_errstr, "Failed to set the log file path, " +-- +1.8.3.1 + diff --git a/0460-cli-add-a-warning-confirmation-message-in-peer-detac.patch b/0460-cli-add-a-warning-confirmation-message-in-peer-detac.patch new file mode 100644 index 0000000..8125367 --- /dev/null +++ b/0460-cli-add-a-warning-confirmation-message-in-peer-detac.patch @@ -0,0 +1,74 @@ +From 81b19743a97ebecc188d87fbe04dce59260824f8 Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Tue, 6 Nov 2018 21:35:36 +0530 +Subject: [PATCH 460/493] cli: add a warning/confirmation message in peer + detach code path + +On a multi node cluster if one of the node is detached which had active +clients mounted through the same server address, this can cause all the +clients to loose any volfile changes. This is due to the lack of infra +in glusterd to let client know the list of IPs and attempt to connect to +other active nodes as failback. Such framework does exist in GD2 but not +in GD1. + +This patch ensures to take a preventive measure to have a warning +message thrown to user to ensure all such connected clients are +remounted through a different IP. + +> Change-Id: I740b01868abbd75bf0a609cfaf00114d4d78aa96 +> Fixes: bz#1647074 +> Signed-off-by: Atin Mukherjee + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/21572/ + +Change-Id: I740b01868abbd75bf0a609cfaf00114d4d78aa96 +BUG: 1639568 +Signed-off-by: Sanju Rakonde +Reviewed-on: https://code.engineering.redhat.com/gerrit/158630 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + cli/src/cli-cmd-peer.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/cli/src/cli-cmd-peer.c b/cli/src/cli-cmd-peer.c +index 7df60bc..6f3b744 100644 +--- a/cli/src/cli-cmd-peer.c ++++ b/cli/src/cli-cmd-peer.c +@@ -111,13 +111,20 @@ cli_cmd_peer_deprobe_cbk (struct cli_state *state, struct cli_cmd_word *word, + int sent = 0; + int parse_error = 0; + cli_local_t *local = NULL; ++ gf_answer_t answer = GF_ANSWER_NO; ++ const char *question = NULL; + + if ((wordcount < 3) || (wordcount > 4)) { + cli_usage_out (word->pattern); + parse_error = 1; + goto out; + } +- ++ question = ++ "All clients mounted through the peer which is getting detached" ++ " need to be remounted using one of the other active peers in " ++ "the trusted storage pool to ensure client gets notification on" ++ " any changes done on the gluster configuration and if the " ++ "same has been done do you want to proceed?"; + proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DEPROBE]; + + frame = create_frame (THIS, THIS->ctx->pool); +@@ -149,6 +156,11 @@ cli_cmd_peer_deprobe_cbk (struct cli_state *state, struct cli_cmd_word *word, + ret = dict_set_int32 (dict, "flags", flags); + if (ret) + goto out; ++ answer = cli_cmd_get_confirmation(state, question); ++ if (GF_ANSWER_NO == answer) { ++ ret = 0; ++ goto out; ++ } + + CLI_LOCAL_INIT (local, words, frame, dict); + +-- +1.8.3.1 + diff --git a/0461-mount-fuse-Add-support-for-multi-threaded-fuse-reade.patch b/0461-mount-fuse-Add-support-for-multi-threaded-fuse-reade.patch new file mode 100644 index 0000000..aba7f00 --- /dev/null +++ b/0461-mount-fuse-Add-support-for-multi-threaded-fuse-reade.patch @@ -0,0 +1,835 @@ +From 668b55b7dd86b23e635cfb2264bc5e50f4cd888d Mon Sep 17 00:00:00 2001 +From: Krutika Dhananjay +Date: Tue, 9 Jan 2018 15:11:00 +0530 +Subject: [PATCH 461/493] mount/fuse: Add support for multi-threaded fuse + readers + + > Upstream: https://review.gluster.org/19226 + > Github issue #412 + > Change-Id: I94aa1505e5ae6a133683d473e0e4e0edd139b76b + +Usage: Use 'reader-thread-count=' as command line option to +set the thread count at the time of mounting the volume. + +Next task is to make these threads auto-scale based on the load, +instead of having the user remount the volume everytime to change +the thread count. + +Change-Id: I94aa1505e5ae6a133683d473e0e4e0edd139b76b +BUG: 1651040 +Signed-off-by: Krutika Dhananjay +Reviewed-on: https://code.engineering.redhat.com/gerrit/158514 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + glusterfsd/src/glusterfsd.c | 26 ++++ + glusterfsd/src/glusterfsd.h | 1 + + libglusterfs/src/glusterfs.h | 1 + + xlators/mount/fuse/src/fuse-bridge.c | 231 ++++++++++++++++++---------- + xlators/mount/fuse/src/fuse-bridge.h | 9 +- + xlators/mount/fuse/src/fuse-helpers.c | 3 + + xlators/mount/fuse/src/fuse-mem-types.h | 1 + + xlators/mount/fuse/utils/mount.glusterfs.in | 7 + + 8 files changed, 196 insertions(+), 83 deletions(-) + +diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c +index 78f3719..03bca24 100644 +--- a/glusterfsd/src/glusterfsd.c ++++ b/glusterfsd/src/glusterfsd.c +@@ -238,6 +238,8 @@ static struct argp_option gf_options[] = { + "Enable localtime logging"}, + {"event-history", ARGP_FUSE_EVENT_HISTORY_KEY, "BOOL", + OPTION_ARG_OPTIONAL, "disable/enable fuse event-history"}, ++ {"reader-thread-count", ARGP_READER_THREAD_COUNT_KEY, "INTEGER", ++ OPTION_ARG_OPTIONAL, "set fuse reader thread count"}, + {0, 0, 0, 0, "Miscellaneous Options:"}, + {0, } + }; +@@ -557,6 +559,17 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options) + goto err; + } + } ++ if (cmd_args->reader_thread_count) { ++ ret = dict_set_uint32 (options, "reader-thread-count", ++ cmd_args->reader_thread_count); ++ if (ret < 0) { ++ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4, ++ "failed to set dict value for key " ++ "reader-thread-count"); ++ goto err; ++ } ++ } ++ + ret = 0; + err: + return ret; +@@ -1307,6 +1320,19 @@ no_oom_api: + argp_failure (state, -1, 0, + "unknown event-history setting \"%s\"", arg); + break; ++ case ARGP_READER_THREAD_COUNT_KEY: ++ if (gf_string2uint32 (arg, &cmd_args->reader_thread_count)) { ++ argp_failure (state, -1, 0, ++ "unknown reader thread count option %s", ++ arg); ++ } else if ((cmd_args->reader_thread_count < 1) || ++ (cmd_args->reader_thread_count > 64)) { ++ argp_failure (state, -1, 0, ++ "Invalid reader thread count %s. " ++ "Valid range: [\"1, 64\"]", arg); ++ } ++ ++ break; + } + + return 0; +diff --git a/glusterfsd/src/glusterfsd.h b/glusterfsd/src/glusterfsd.h +index f66947b..75cb1d8 100644 +--- a/glusterfsd/src/glusterfsd.h ++++ b/glusterfsd/src/glusterfsd.h +@@ -99,6 +99,7 @@ enum argp_option_keys { + ARGP_LOCALTIME_LOGGING_KEY = 177, + ARGP_SUBDIR_MOUNT_KEY = 178, + ARGP_FUSE_EVENT_HISTORY_KEY = 179, ++ ARGP_READER_THREAD_COUNT_KEY = 180, + }; + + struct _gfd_vol_top_priv { +diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h +index 5e641fd..3e2f426 100644 +--- a/libglusterfs/src/glusterfs.h ++++ b/libglusterfs/src/glusterfs.h +@@ -446,6 +446,7 @@ struct _cmd_args { + char *subdir_mount; + + char *event_history; ++ uint32_t reader_thread_count; + }; + typedef struct _cmd_args cmd_args_t; + +diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c +index fbb4c53..8d1e3a0 100644 +--- a/xlators/mount/fuse/src/fuse-bridge.c ++++ b/xlators/mount/fuse/src/fuse-bridge.c +@@ -665,7 +665,8 @@ fuse_lookup_resume (fuse_state_t *state) + } + + static void +-fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + char *name = msg; + fuse_state_t *state = NULL; +@@ -693,7 +694,8 @@ do_forget(xlator_t *this, uint64_t unique, uint64_t nodeid, uint64_t nlookup) + } + + static void +-fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + + { + struct fuse_forget_in *ffi = msg; +@@ -714,7 +716,8 @@ fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg) + + #if FUSE_KERNEL_MINOR_VERSION >= 16 + static void +-fuse_batch_forget(xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_batch_forget(xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_batch_forget_in *fbfi = msg; + struct fuse_forget_one *ffo = (struct fuse_forget_one *) (fbfi + 1); +@@ -932,7 +935,8 @@ fuse_getattr_resume (fuse_state_t *state) + } + + static void +-fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + #if FUSE_KERNEL_MINOR_VERSION >= 9 + struct fuse_getattr_in *fgi = msg; +@@ -1265,7 +1269,8 @@ fuse_setattr_resume (fuse_state_t *state) + } + + static void +-fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_setattr_in *fsi = msg; + +@@ -1492,7 +1497,8 @@ fuse_access_resume (fuse_state_t *state) + } + + static void +-fuse_access (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_access (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_access_in *fai = msg; + fuse_state_t *state = NULL; +@@ -1566,7 +1572,8 @@ fuse_readlink_resume (fuse_state_t *state) + } + + static void +-fuse_readlink (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_readlink (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + fuse_state_t *state = NULL; + +@@ -1616,7 +1623,8 @@ fuse_mknod_resume (fuse_state_t *state) + } + + static void +-fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_mknod_in *fmi = msg; + char *name = (char *)(fmi + 1); +@@ -1686,7 +1694,8 @@ fuse_mkdir_resume (fuse_state_t *state) + } + + static void +-fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_mkdir_in *fmi = msg; + char *name = (char *)(fmi + 1); +@@ -1738,7 +1747,8 @@ fuse_unlink_resume (fuse_state_t *state) + } + + static void +-fuse_unlink (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_unlink (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + char *name = msg; + fuse_state_t *state = NULL; +@@ -1775,7 +1785,8 @@ fuse_rmdir_resume (fuse_state_t *state) + } + + static void +-fuse_rmdir (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_rmdir (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + char *name = msg; + fuse_state_t *state = NULL; +@@ -1825,7 +1836,8 @@ fuse_symlink_resume (fuse_state_t *state) + } + + static void +-fuse_symlink (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_symlink (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + char *name = msg; + char *linkname = name + strlen (name) + 1; +@@ -1947,7 +1959,8 @@ fuse_rename_resume (fuse_state_t *state) + } + + static void +-fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_rename_in *fri = msg; + char *oldname = (char *)(fri + 1); +@@ -1997,7 +2010,8 @@ fuse_link_resume (fuse_state_t *state) + } + + static void +-fuse_link (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_link (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_link_in *fli = msg; + char *name = (char *)(fli + 1); +@@ -2186,7 +2200,8 @@ fuse_create_resume (fuse_state_t *state) + } + + static void +-fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + #if FUSE_KERNEL_MINOR_VERSION >= 12 + struct fuse_create_in *fci = msg; +@@ -2280,7 +2295,8 @@ fuse_open_resume (fuse_state_t *state) + } + + static void +-fuse_open (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_open (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_open_in *foi = msg; + fuse_state_t *state = NULL; +@@ -2357,7 +2373,8 @@ fuse_readv_resume (fuse_state_t *state) + } + + static void +-fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_read_in *fri = msg; + +@@ -2433,8 +2450,6 @@ void + fuse_write_resume (fuse_state_t *state) + { + struct iobref *iobref = NULL; +- struct iobuf *iobuf = NULL; +- + + iobref = iobref_new (); + if (!iobref) { +@@ -2447,8 +2462,7 @@ fuse_write_resume (fuse_state_t *state) + return; + } + +- iobuf = ((fuse_private_t *) (state->this->private))->iobuf; +- iobref_add (iobref, iobuf); ++ iobref_add (iobref, state->iobuf); + + gf_log ("glusterfs-fuse", GF_LOG_TRACE, + "%"PRIu64": WRITE (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")", +@@ -2462,7 +2476,8 @@ fuse_write_resume (fuse_state_t *state) + } + + static void +-fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + /* WRITE is special, metadata is attached to in_header, + * and msg is the payload as-is. +@@ -2505,6 +2520,7 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg) + + state->vector.iov_base = msg; + state->vector.iov_len = fwi->size; ++ state->iobuf = iobuf; + + fuse_resolve_and_resume (state, fuse_write_resume); + +@@ -2543,7 +2559,8 @@ fuse_lseek_resume (fuse_state_t *state) + } + + static void +-fuse_lseek (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_lseek (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_lseek_in *ffi = msg; + fuse_state_t *state = NULL; +@@ -2579,7 +2596,8 @@ fuse_flush_resume (fuse_state_t *state) + } + + static void +-fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_flush_in *ffi = msg; + +@@ -2615,7 +2633,8 @@ fuse_internal_release (xlator_t *this, fd_t *fd) + } + + static void +-fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_release_in *fri = msg; + fd_t *fd = NULL; +@@ -2660,7 +2679,8 @@ fuse_fsync_resume (fuse_state_t *state) + } + + static void +-fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_fsync_in *fsi = msg; + +@@ -2735,7 +2755,8 @@ fuse_opendir_resume (fuse_state_t *state) + } + + static void +-fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + /* + struct fuse_open_in *foi = msg; +@@ -2877,7 +2898,8 @@ fuse_readdir_resume (fuse_state_t *state) + } + + static void +-fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_read_in *fri = msg; + +@@ -3028,7 +3050,8 @@ fuse_readdirp_resume (fuse_state_t *state) + + + static void +-fuse_readdirp (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_readdirp (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_read_in *fri = msg; + +@@ -3075,7 +3098,8 @@ fuse_fallocate_resume(fuse_state_t *state) + } + + static void +-fuse_fallocate(xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_fallocate(xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_fallocate_in *ffi = msg; + fuse_state_t *state = NULL; +@@ -3093,7 +3117,8 @@ fuse_fallocate(xlator_t *this, fuse_in_header_t *finh, void *msg) + #endif /* FUSE minor version >= 19 */ + + static void +-fuse_releasedir (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_releasedir (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_release_in *fri = msg; + fuse_state_t *state = NULL; +@@ -3134,7 +3159,8 @@ fuse_fsyncdir_resume (fuse_state_t *state) + } + + static void +-fuse_fsyncdir (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_fsyncdir (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_fsync_in *fsi = msg; + +@@ -3221,7 +3247,8 @@ fuse_statfs_resume (fuse_state_t *state) + + + static void +-fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + fuse_state_t *state = NULL; + +@@ -3273,7 +3300,8 @@ fuse_setxattr_resume (fuse_state_t *state) + + + static void +-fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_setxattr_in *fsi = msg; + char *name = (char *)(fsi + 1); +@@ -3604,7 +3632,8 @@ fuse_getxattr_resume (fuse_state_t *state) + + + static void +-fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_getxattr_in *fgxi = msg; + char *name = (char *)(fgxi + 1); +@@ -3710,7 +3739,8 @@ fuse_listxattr_resume (fuse_state_t *state) + + + static void +-fuse_listxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_listxattr (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_getxattr_in *fgxi = msg; + fuse_state_t *state = NULL; +@@ -3766,7 +3796,8 @@ fuse_removexattr_resume (fuse_state_t *state) + + + static void +-fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + char *name = msg; + +@@ -3865,7 +3896,8 @@ fuse_getlk_resume (fuse_state_t *state) + + + static void +-fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_lk_in *fli = msg; + +@@ -3957,7 +3989,8 @@ fuse_setlk_resume (fuse_state_t *state) + + + static void +-fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_lk_in *fli = msg; + +@@ -4056,7 +4089,8 @@ notify_kernel_loop (void *data) + #endif + + static void +-fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + struct fuse_init_in *fini = msg; + struct fuse_init_out fino = {0,}; +@@ -4227,7 +4261,8 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg) + + + static void +-fuse_enosys (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_enosys (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + send_fuse_err (this, finh, ENOSYS); + +@@ -4236,7 +4271,8 @@ fuse_enosys (xlator_t *this, fuse_in_header_t *finh, void *msg) + + + static void +-fuse_destroy (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_destroy (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + send_fuse_err (this, finh, 0); + +@@ -4826,6 +4862,7 @@ fuse_graph_sync (xlator_t *this) + new_graph_id = priv->next_graph->id; + priv->next_graph = NULL; + need_first_lookup = 1; ++ priv->handle_graph_switch = _gf_true; + + while (!priv->event_recvd) { + ret = pthread_cond_wait (&priv->sync_cond, +@@ -4854,6 +4891,8 @@ unlock: + { + old_subvol->switched = 1; + winds_on_old_subvol = old_subvol->winds; ++ priv->handle_graph_switch = _gf_false; ++ pthread_cond_broadcast (&priv->migrate_cond); + } + pthread_mutex_unlock (&priv->sync_mutex); + +@@ -4861,6 +4900,13 @@ unlock: + xlator_notify (old_subvol, GF_EVENT_PARENT_DOWN, + old_subvol, NULL); + } ++ } else { ++ pthread_mutex_lock (&priv->sync_mutex); ++ { ++ priv->handle_graph_switch = _gf_false; ++ pthread_cond_broadcast (&priv->migrate_cond); ++ } ++ pthread_mutex_unlock (&priv->sync_mutex); + } + + return 0; +@@ -4897,7 +4943,6 @@ fuse_thread_proc (void *data) + const size_t msg0_size = sizeof (*finh) + 128; + fuse_handler_t **fuse_ops = NULL; + struct pollfd pfd[2] = {{0,}}; +- gf_boolean_t mount_finished = _gf_false; + + this = data; + priv = this->private; +@@ -4914,32 +4959,40 @@ fuse_thread_proc (void *data) + /* THIS has to be reset here */ + THIS = this; + +- if (!mount_finished) { +- memset(pfd,0,sizeof(pfd)); +- pfd[0].fd = priv->status_pipe[0]; +- pfd[0].events = POLLIN | POLLHUP | POLLERR; +- pfd[1].fd = priv->fd; +- pfd[1].events = POLLIN | POLLHUP | POLLERR; +- if (poll(pfd,2,-1) < 0) { +- gf_log (this->name, GF_LOG_ERROR, +- "poll error %s", strerror(errno)); +- break; +- } +- if (pfd[0].revents & POLLIN) { +- if (fuse_get_mount_status(this) != 0) { ++ pthread_mutex_lock (&priv->sync_mutex); ++ { ++ if (!priv->mount_finished) { ++ memset(pfd, 0, sizeof(pfd)); ++ pfd[0].fd = priv->status_pipe[0]; ++ pfd[0].events = POLLIN | POLLHUP | POLLERR; ++ pfd[1].fd = priv->fd; ++ pfd[1].events = POLLIN | POLLHUP | POLLERR; ++ if (poll(pfd, 2, -1) < 0) { ++ gf_log (this->name, GF_LOG_ERROR, ++ "poll error %s", ++ strerror(errno)); ++ pthread_mutex_unlock (&priv->sync_mutex); + break; + } +- mount_finished = _gf_true; +- } +- else if (pfd[0].revents) { +- gf_log (this->name, GF_LOG_ERROR, +- "mount pipe closed without status"); +- break; +- } +- if (!pfd[1].revents) { +- continue; ++ if (pfd[0].revents & POLLIN) { ++ if (fuse_get_mount_status(this) != 0) { ++ pthread_mutex_unlock (&priv->sync_mutex); ++ break; ++ } ++ priv->mount_finished = _gf_true; ++ } else if (pfd[0].revents) { ++ gf_log (this->name, GF_LOG_ERROR, ++ "mount pipe closed without status"); ++ pthread_mutex_unlock (&priv->sync_mutex); ++ break; ++ } ++ if (!pfd[1].revents) { ++ pthread_mutex_unlock (&priv->sync_mutex); ++ continue; ++ } + } + } ++ pthread_mutex_unlock (&priv->sync_mutex); + + /* + * We don't want to block on readv while we're still waiting +@@ -5034,8 +5087,6 @@ fuse_thread_proc (void *data) + break; + } + +- priv->iobuf = iobuf; +- + /* + * This can be moved around a bit, but it's important to do it + * *after* the readv. Otherwise, a graph switch could occur +@@ -5078,9 +5129,9 @@ fuse_thread_proc (void *data) + + if (finh->opcode >= FUSE_OP_HIGH) + /* turn down MacFUSE specific messages */ +- fuse_enosys (this, finh, msg); ++ fuse_enosys (this, finh, msg, NULL); + else +- fuse_ops[finh->opcode] (this, finh, msg); ++ fuse_ops[finh->opcode] (this, finh, msg, iobuf); + + iobuf_unref (iobuf); + continue; +@@ -5152,8 +5203,6 @@ fuse_priv_dump (xlator_t *this) + private->volfile_size); + gf_proc_dump_write("mount_point", "%s", + private->mount_point); +- gf_proc_dump_write("iobuf", "%p", +- private->iobuf); + gf_proc_dump_write("fuse_thread_started", "%d", + (int)private->fuse_thread_started); + gf_proc_dump_write("direct_io_mode", "%d", +@@ -5279,6 +5328,7 @@ unlock: + int + notify (xlator_t *this, int32_t event, void *data, ...) + { ++ int i = 0; + int32_t ret = 0; + fuse_private_t *private = NULL; + gf_boolean_t start_thread = _gf_false; +@@ -5327,14 +5377,21 @@ notify (xlator_t *this, int32_t event, void *data, ...) + pthread_mutex_unlock (&private->sync_mutex); + + if (start_thread) { +- ret = gf_thread_create (&private->fuse_thread, NULL, +- fuse_thread_proc, this, +- "fuseproc"); +- if (ret != 0) { +- gf_log (this->name, GF_LOG_DEBUG, +- "pthread_create() failed (%s)", +- strerror (errno)); +- break; ++ private->fuse_thread = GF_CALLOC (private->reader_thread_count, ++ sizeof (pthread_t), ++ gf_fuse_mt_pthread_t); ++ for (i = 0; i < private->reader_thread_count; i++) { ++ ++ ret = gf_thread_create (&private->fuse_thread[i], ++ NULL, ++ fuse_thread_proc, this, ++ "fuseproc"); ++ if (ret != 0) { ++ gf_log (this->name, GF_LOG_DEBUG, ++ "pthread_create() failed (%s)", ++ strerror (errno)); ++ break; ++ } + } + } + +@@ -5441,7 +5498,8 @@ static fuse_handler_t *fuse_dump_ops[FUSE_OP_HIGH]; + + + static void +-fuse_dumper (xlator_t *this, fuse_in_header_t *finh, void *msg) ++fuse_dumper (xlator_t *this, fuse_in_header_t *finh, void *msg, ++ struct iobuf *iobuf) + { + fuse_private_t *priv = NULL; + struct iovec diov[6] = {{0,},}; +@@ -5473,7 +5531,7 @@ fuse_dumper (xlator_t *this, fuse_in_header_t *finh, void *msg) + "failed to dump fuse message (R): %s", + strerror (errno)); + +- priv->fuse_ops0[finh->opcode] (this, finh, msg); ++ priv->fuse_ops0[finh->opcode] (this, finh, msg, NULL); + } + + +@@ -5578,6 +5636,9 @@ init (xlator_t *this_xl) + GF_OPTION_INIT (ZR_ATTR_TIMEOUT_OPT, priv->attribute_timeout, double, + cleanup_exit); + ++ GF_OPTION_INIT ("reader-thread-count", priv->reader_thread_count, uint32, ++ cleanup_exit); ++ + GF_OPTION_INIT (ZR_ENTRY_TIMEOUT_OPT, priv->entry_timeout, double, + cleanup_exit); + +@@ -5793,6 +5854,7 @@ init (xlator_t *this_xl) + + pthread_mutex_init (&priv->fuse_dump_mutex, NULL); + pthread_cond_init (&priv->sync_cond, NULL); ++ pthread_cond_init (&priv->migrate_cond, NULL); + pthread_mutex_init (&priv->sync_mutex, NULL); + priv->event_recvd = 0; + +@@ -5992,5 +6054,12 @@ struct volume_options options[] = { + .description = "This option can be used to enable or disable fuse " + "event history.", + }, ++ { .key = {"reader-thread-count"}, ++ .type = GF_OPTION_TYPE_INT, ++ .default_value = "1", ++ .min = 1, ++ .max = 64, ++ .description = "Sets fuse reader thread count.", ++ }, + { .key = {NULL} }, + }; +diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h +index 2dfef64..4ca76e9 100644 +--- a/xlators/mount/fuse/src/fuse-bridge.h ++++ b/xlators/mount/fuse/src/fuse-bridge.h +@@ -52,7 +52,7 @@ + + typedef struct fuse_in_header fuse_in_header_t; + typedef void (fuse_handler_t) (xlator_t *this, fuse_in_header_t *finh, +- void *msg); ++ void *msg, struct iobuf *iobuf); + + struct fuse_private { + int fd; +@@ -62,7 +62,8 @@ struct fuse_private { + char *mount_point; + struct iobuf *iobuf; + +- pthread_t fuse_thread; ++ pthread_t *fuse_thread; ++ uint32_t reader_thread_count; + char fuse_thread_started; + + uint32_t direct_io_mode; +@@ -140,6 +141,9 @@ struct fuse_private { + + /* whether to run the unmount daemon */ + gf_boolean_t auto_unmount; ++ gf_boolean_t mount_finished; ++ gf_boolean_t handle_graph_switch; ++ pthread_cond_t migrate_cond; + }; + typedef struct fuse_private fuse_private_t; + +@@ -391,6 +395,7 @@ typedef struct { + int32_t fd_no; + + gf_seek_what_t whence; ++ struct iobuf *iobuf; + } fuse_state_t; + + typedef struct { +diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c +index c59ff77..c2d4d0c 100644 +--- a/xlators/mount/fuse/src/fuse-helpers.c ++++ b/xlators/mount/fuse/src/fuse-helpers.c +@@ -123,6 +123,9 @@ get_fuse_state (xlator_t *this, fuse_in_header_t *finh) + + pthread_mutex_lock (&priv->sync_mutex); + { ++ while (priv->handle_graph_switch) ++ pthread_cond_wait (&priv->migrate_cond, ++ &priv->sync_mutex); + active_subvol = fuse_active_subvol (state->this); + active_subvol->winds++; + } +diff --git a/xlators/mount/fuse/src/fuse-mem-types.h b/xlators/mount/fuse/src/fuse-mem-types.h +index 2b4b473..721b9a3 100644 +--- a/xlators/mount/fuse/src/fuse-mem-types.h ++++ b/xlators/mount/fuse/src/fuse-mem-types.h +@@ -23,6 +23,7 @@ enum gf_fuse_mem_types_ { + gf_fuse_mt_graph_switch_args_t, + gf_fuse_mt_gids_t, + gf_fuse_mt_invalidate_node_t, ++ gf_fuse_mt_pthread_t, + gf_fuse_mt_end + }; + #endif +diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in +index b39bb98..817619e 100755 +--- a/xlators/mount/fuse/utils/mount.glusterfs.in ++++ b/xlators/mount/fuse/utils/mount.glusterfs.in +@@ -221,6 +221,10 @@ start_glusterfs () + cmd_line=$(echo "$cmd_line --event-history=$event_history"); + fi + ++ if [ -n "$reader_thread_count" ]; then ++ cmd_line=$(echo "$cmd_line --reader-thread-count=$reader_thread_count"); ++ fi ++ + if [ -n "$volume_name" ]; then + cmd_line=$(echo "$cmd_line --volume-name=$volume_name"); + fi +@@ -496,6 +500,9 @@ with_options() + "event-history") + event_history=$value + ;; ++ "reader-thread-count") ++ reader_thread_count=$value ++ ;; + "no-root-squash") + if [ $value = "yes" ] || + [ $value = "on" ] || +-- +1.8.3.1 + diff --git a/0462-posix-Do-not-log-ENXIO-errors-for-seek-fop.patch b/0462-posix-Do-not-log-ENXIO-errors-for-seek-fop.patch new file mode 100644 index 0000000..c18bd8e --- /dev/null +++ b/0462-posix-Do-not-log-ENXIO-errors-for-seek-fop.patch @@ -0,0 +1,62 @@ +From a064614b60924c4b0b1dbc4dd18278ce18b46db0 Mon Sep 17 00:00:00 2001 +From: Xavi Hernandez +Date: Fri, 6 Jul 2018 23:26:41 +0200 +Subject: [PATCH 462/493] posix: Do not log ENXIO errors for seek fop + +When lseek is used with SEEK_DATA and SEEK_HOLE, it's expected that the +last operation fails with ENXIO when offset is beyond the end of file. +In this case it doesn't make sense to report this as an error log message. + +This patch reports ENXIO failure messages for seek fops in debug level +instead of error level. + +> Change-Id: I62a4f61f99b0e4d7ea6a2cdcd40afe15072794ac +> fixes: bz#1598926 +> Signed-off-by: Xavi Hernandez + +Upstream patch: https://review.gluster.org/c/glusterfs/+/20475 +Change-Id: I62a4f61f99b0e4d7ea6a2cdcd40afe15072794ac +BUG: 1598883 +Signed-off-by: Xavi Hernandez +Reviewed-on: https://code.engineering.redhat.com/gerrit/158531 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + libglusterfs/src/common-utils.c | 6 ++++++ + xlators/storage/posix/src/posix.c | 3 ++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c +index dd6cdb3..25600a9 100644 +--- a/libglusterfs/src/common-utils.c ++++ b/libglusterfs/src/common-utils.c +@@ -4369,6 +4369,12 @@ fop_log_level (glusterfs_fop_t fop, int op_errno) + if (op_errno == EEXIST) + return GF_LOG_DEBUG; + ++ if (fop == GF_FOP_SEEK) { ++ if (op_errno == ENXIO) { ++ return GF_LOG_DEBUG; ++ } ++ } ++ + return GF_LOG_ERROR; + } + +diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c +index e46fe99..13b4aa6 100644 +--- a/xlators/storage/posix/src/posix.c ++++ b/xlators/storage/posix/src/posix.c +@@ -1225,7 +1225,8 @@ posix_seek (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + ret = sys_lseek (pfd->fd, offset, whence); + if (ret == -1) { + err = errno; +- gf_msg (this->name, GF_LOG_ERROR, err, P_MSG_SEEK_FAILED, ++ gf_msg (this->name, fop_log_level(GF_FOP_SEEK, err), err, ++ P_MSG_SEEK_FAILED, + "seek failed on fd %d length %" PRId64 , pfd->fd, + offset); + goto out; +-- +1.8.3.1 + diff --git a/0463-build-glusterfs.spec-.in-firewalld-file-doesn-t-use-.patch b/0463-build-glusterfs.spec-.in-firewalld-file-doesn-t-use-.patch new file mode 100644 index 0000000..f6641d5 --- /dev/null +++ b/0463-build-glusterfs.spec-.in-firewalld-file-doesn-t-use-.patch @@ -0,0 +1,58 @@ +From f1d10db3bf315bfc9640a532aa39b9248d55e9c6 Mon Sep 17 00:00:00 2001 +From: Kaleb S KEITHLEY +Date: Thu, 13 Dec 2018 11:24:05 +0530 +Subject: [PATCH 463/493] build: glusterfs.spec(.in) firewalld file doesn't use + %{_prefix} + +.../firewalld/services/glusterfs.xml in %server files section +does not use %{_prefix} + +Other firewalld files, e.g., in the firewalld.src.rpm file use +%{_prefix} + +N.B. the other 'hardcoded' path, "/sbin/mount.glusterfs" in the +%files fuse section must remain as is, there is no macro for +mount utilities to use as there is for, e.g., the %{_sbindir} +macro for /usr/sbin. This doesn't matter for either RHEL6, where +/sbin and /usr/sbin are distinct directories, or for Fedora and +RHEL7, where /sbin is a symlink to /usr/sbin. E.g. see the nfs- +utils.src.rpm where /sbin/mount.nfs is also 'hardcoded'. + +mainline: +> Change-Id: I902f47e3c589526c774d0aceb6fc2815abf86b01 +> BUG: 1350793 +> Signed-off-by: Kaleb S KEITHLEY +> Reviewed-on: http://review.gluster.org/14823 +> Smoke: Gluster Build System +> CentOS-regression: Gluster Build System +> NetBSD-regression: NetBSD Build System +> Reviewed-by: Milind Changire +> Reviewed-by: Niels de Vos + +Change-Id: I902f47e3c589526c774d0aceb6fc2815abf86b01 +BUG: 1350745 +Signed-off-by: Kaleb S KEITHLEY +Reviewed-on: https://code.engineering.redhat.com/gerrit/158502 +Tested-by: RHGS Build Bot +Tested-by: Milind Changire +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + glusterfs.spec.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index b6b7630..2745b50 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1168,7 +1168,7 @@ exit 0 + %exclude %{_tmpfilesdir}/gluster.conf + %endif + %if ( 0%{?_with_firewalld:1} ) +-%exclude /usr/lib/firewalld/services/glusterfs.xml ++%exclude %{_prefix}/lib/firewalld/services/glusterfs.xml + %endif + %endif + %doc ChangeLog COPYING-GPLV2 COPYING-LGPLV3 INSTALL README.md THANKS +-- +1.8.3.1 + diff --git a/0464-build-exclude-packaging-crypt.so.patch b/0464-build-exclude-packaging-crypt.so.patch new file mode 100644 index 0000000..f32c9da --- /dev/null +++ b/0464-build-exclude-packaging-crypt.so.patch @@ -0,0 +1,37 @@ +From 93f35b10446fe14a0fd3e5d318056fe399479386 Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Thu, 13 Dec 2018 11:31:20 +0530 +Subject: [PATCH 464/493] build: exclude packaging crypt.so + +exclude packaging crypt.so for FIPS compliance + +Label: DOWNSTREAM ONLY + +BUG: 1653224 +Change-Id: Icbf0d3efc90813c5856237213e6cf25af84e4915 +Signed-off-by: Milind Changire +Reviewed-on: https://code.engineering.redhat.com/gerrit/158500 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + glusterfs.spec.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 2745b50..baee2fa 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1198,8 +1198,8 @@ exit 0 + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug/trace.so + %if ( ! ( 0%{?rhel} && 0%{?rhel} < 6 ) ) + # RHEL-5 based distributions have a too old openssl +-%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption +- %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption/crypt.so ++%exclude %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption ++%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption/crypt.so + %endif + %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features + %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/access-control.so +-- +1.8.3.1 + diff --git a/0465-build-add-missing-explicit-package-dependencies.patch b/0465-build-add-missing-explicit-package-dependencies.patch new file mode 100644 index 0000000..850ce76 --- /dev/null +++ b/0465-build-add-missing-explicit-package-dependencies.patch @@ -0,0 +1,84 @@ +From ef7af50ae35ac5776057d6355b84ae111d33151e Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Thu, 13 Dec 2018 12:46:56 +0530 +Subject: [PATCH 465/493] build: add missing explicit package dependencies + +Add dependencies for glusterfs-libs, and other packages. +This is an Errata Tool whine. + +Label: DOWNSTREAM ONLY + +BUG: 1656357 +Change-Id: Ieaadb6e4ffa84d1811aa740f7891855568ecbcbb +Signed-off-by: Milind Changire +Reviewed-on: https://code.engineering.redhat.com/gerrit/158501 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + glusterfs.spec.in | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index baee2fa..f6a4ab0 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -282,6 +282,7 @@ Summary: GlusterFS api library + Group: System Environment/Daemons + Requires: %{name}%{?_isa} = %{version}-%{release} + Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release} ++Requires: %{name}-libs%{?_isa} = %{version}-%{release} + + %description api + GlusterFS is a distributed file-system capable of scaling to several +@@ -300,6 +301,7 @@ Group: Development/Libraries + Requires: %{name}%{?_isa} = %{version}-%{release} + Requires: %{name}-devel%{?_isa} = %{version}-%{release} + Requires: libacl-devel ++Requires: %{name}-api%{?_isa} = %{version}-%{release} + + %description api-devel + GlusterFS is a distributed file-system capable of scaling to several +@@ -336,6 +338,8 @@ Requires: %{name}%{?_isa} = %{version}-%{release} + %if ( 0%{!?_without_extra_xlators:1} ) + Requires: %{name}-extra-xlators = %{version}-%{release} + %endif ++Requires: %{name}-libs%{?_isa} = %{version}-%{release} ++Requires: %{name}-server%{?_isa} = %{version}-%{release} + + %description devel + GlusterFS is a distributed file-system capable of scaling to several +@@ -385,6 +389,7 @@ Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release} + + Obsoletes: %{name}-client < %{version}-%{release} + Provides: %{name}-client = %{version}-%{release} ++Requires: %{name}-libs%{?_isa} = %{version}-%{release} + + %description fuse + GlusterFS is a distributed file-system capable of scaling to several +@@ -454,6 +459,7 @@ BuildRequires: python-ctypes + Requires: python2-gluster = %{version}-%{release} + Requires: rsync + Requires: util-linux ++Requires: %{name}-libs%{?_isa} = %{version}-%{release} + + %description geo-replication + GlusterFS is a distributed file-system capable of scaling to several +@@ -526,6 +532,7 @@ BuildRequires: libibverbs-devel + BuildRequires: librdmacm-devel >= 1.0.15 + %endif + Requires: %{name}%{?_isa} = %{version}-%{release} ++Requires: %{name}-libs%{?_isa} = %{version}-%{release} + + %description rdma + GlusterFS is a distributed file-system capable of scaling to several +@@ -656,6 +663,7 @@ This package provides the glusterfs server daemon. + %package client-xlators + Summary: GlusterFS client-side translators + Group: Applications/File ++Requires: %{name}-libs%{?_isa} = %{version}-%{release} + + %description client-xlators + GlusterFS is a distributed file-system capable of scaling to several +-- +1.8.3.1 + diff --git a/0466-extras-Add-group-distributed-virt-for-single-brick-o.patch b/0466-extras-Add-group-distributed-virt-for-single-brick-o.patch new file mode 100644 index 0000000..6d443fc --- /dev/null +++ b/0466-extras-Add-group-distributed-virt-for-single-brick-o.patch @@ -0,0 +1,86 @@ +From 2ef41e27b452f215e56bfc08c8117f8f18c33619 Mon Sep 17 00:00:00 2001 +From: Krutika Dhananjay +Date: Wed, 28 Nov 2018 12:39:31 +0530 +Subject: [PATCH 466/493] extras: Add group-distributed-virt for single-brick + ovirt-gluster use-case + + > Upstream: https://review.gluster.org/21735 + > BUG: 1654138 + > Change-Id: I930011327332b7ba30cc76f614efaf5932eb4f3d + +Change-Id: I930011327332b7ba30cc76f614efaf5932eb4f3d +BUG: 1653613 +Signed-off-by: Krutika Dhananjay +Reviewed-on: https://code.engineering.redhat.com/gerrit/158487 +Tested-by: RHGS Build Bot +Reviewed-by: Milind Changire +Reviewed-by: Atin Mukherjee +--- + extras/Makefile.am | 6 +++++- + extras/group-distributed-virt | 10 ++++++++++ + glusterfs.spec.in | 4 ++++ + 3 files changed, 19 insertions(+), 1 deletion(-) + create mode 100644 extras/group-distributed-virt + +diff --git a/extras/Makefile.am b/extras/Makefile.am +index 7b791af..e0e05b5 100644 +--- a/extras/Makefile.am ++++ b/extras/Makefile.am +@@ -12,7 +12,9 @@ SUBDIRS = init.d systemd benchmarking hook-scripts $(OCF_SUBDIR) LinuxRPM \ + + confdir = $(sysconfdir)/glusterfs + conf_DATA = glusterfs-logrotate gluster-rsyslog-7.2.conf gluster-rsyslog-5.8.conf \ +- logger.conf.example glusterfs-georep-logrotate group-virt.example group-metadata-cache group-gluster-block group-nl-cache group-db-workload ++ logger.conf.example glusterfs-georep-logrotate group-virt.example \ ++ group-metadata-cache group-gluster-block group-nl-cache group-db-workload \ ++ group-distributed-virt + + voldir = $(sysconfdir)/glusterfs + vol_DATA = glusterd.vol +@@ -49,3 +51,5 @@ install-data-local: + $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/nl-cache + $(INSTALL_DATA) $(top_srcdir)/extras/group-db-workload \ + $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/db-workload ++ $(INSTALL_DATA) $(top_srcdir)/extras/group-distributed-virt \ ++ $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/distributed-virt +diff --git a/extras/group-distributed-virt b/extras/group-distributed-virt +new file mode 100644 +index 0000000..a960b76 +--- /dev/null ++++ b/extras/group-distributed-virt +@@ -0,0 +1,10 @@ ++performance.quick-read=off ++performance.read-ahead=off ++performance.io-cache=off ++performance.low-prio-threads=32 ++network.remote-dio=enable ++features.shard=on ++user.cifs=off ++client.event-threads=4 ++server.event-threads=4 ++performance.client-io-threads=on +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index f6a4ab0..a4accd9 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1522,6 +1522,7 @@ exit 0 + %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/metadata-cache + %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/gluster-block + %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/db-workload ++ %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/distributed-virt + %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/nl-cache + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glusterfind + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glusterfind/.keys +@@ -2169,6 +2170,9 @@ fi + %endif + + %changelog ++* Thu Dec 13 2018 Krutika Dhananjay ++- Install /var/lib/glusterd/groups/distributed-virt by default (#1653613) ++ + * Fri Jul 6 2018 Atin Mukherjee + - Added db group profile (#1597506) + +-- +1.8.3.1 + diff --git a/0467-glusterd-glusterd-to-regenerate-volfiles-when-GD_OP_.patch b/0467-glusterd-glusterd-to-regenerate-volfiles-when-GD_OP_.patch new file mode 100644 index 0000000..b5aa151 --- /dev/null +++ b/0467-glusterd-glusterd-to-regenerate-volfiles-when-GD_OP_.patch @@ -0,0 +1,304 @@ +From 647b4d4e8edefd256de2a9f3916763b8cfa8429b Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Tue, 20 Nov 2018 12:32:32 +0530 +Subject: [PATCH 467/493] glusterd: glusterd to regenerate volfiles when + GD_OP_VERSION_MAX changes + +While glusterd has an infra to allow post install of spec to bring it up +in the interim upgrade mode to allow all the volfiles to be regenerated +with the latest executable, in container world the same methodology is +not followed as container image always point to the specific gluster rpm +and gluster rpm doesn't go through an upgrade process. + +This fix does the following: +1. If glusterd.upgrade file doesn't exist, regenerate the volfiles +2. If maximum-operating-version read from glusterd.upgrade doesn't match +with GD_OP_VERSION_MAX, glusterd detects it to be a version where new +options are introduced and regenerate the volfiles. + +Tests done: + +1. Bring up glusterd, check if glusterd.upgrade file has been created +with GD_OP_VERSION_MAX value. +2. Post 1, restart glusterd and check glusterd hasn't regenerated the +volfiles as there's is no change in the GD_OP_VERSION_MAX vs the +op_version read from the file. +3. Bump up the GD_OP_VERSION_MAX in the code by 1 and post compilation +restart glusterd where the volfiles should be again regenerated. + +Note: The old way of having volfiles regenerated during an rpm upgrade +is kept as it is for now but eventually this can be sunset later. + +> Change-Id: I75b49a1601c71e99f6a6bc360dd12dd03a96414b +> Fixes: bz#1651463 +> Signed-off-by: Atin Mukherjee + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/21687/ + +Change-Id: I75b49a1601c71e99f6a6bc360dd12dd03a96414b +BUG: 1651460 +Signed-off-by: Sanju Rakonde +Reviewed-on: https://code.engineering.redhat.com/gerrit/158645 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + xlators/mgmt/glusterd/src/glusterd-store.c | 126 +++++++++++++++++++++++++++-- + xlators/mgmt/glusterd/src/glusterd-store.h | 6 ++ + xlators/mgmt/glusterd/src/glusterd.c | 27 +++++-- + xlators/mgmt/glusterd/src/glusterd.h | 7 ++ + 4 files changed, 154 insertions(+), 12 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c +index 37542e7..f276fef 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-store.c ++++ b/xlators/mgmt/glusterd/src/glusterd-store.c +@@ -2063,7 +2063,7 @@ glusterd_store_global_info (xlator_t *this) + } + + handle->fd = gf_store_mkstemp (handle); +- if (handle->fd <= 0) { ++ if (handle->fd < 0) { + ret = -1; + goto out; + } +@@ -2081,7 +2081,7 @@ glusterd_store_global_info (xlator_t *this) + goto out; + } + +- snprintf (op_version_str, 15, "%d", conf->op_version); ++ snprintf (op_version_str, sizeof(op_version_str), "%d", conf->op_version); + ret = gf_store_save_value (handle->fd, GD_OP_VERSION_KEY, + op_version_str); + if (ret) { +@@ -2094,12 +2094,8 @@ glusterd_store_global_info (xlator_t *this) + ret = gf_store_rename_tmppath (handle); + out: + if (handle) { +- if (ret && (handle->fd > 0)) ++ if (ret && (handle->fd >= 0)) + gf_store_unlink_tmppath (handle); +- +- if (handle->fd > 0) { +- handle->fd = 0; +- } + } + + if (uuid_str) +@@ -2114,6 +2110,122 @@ out: + } + + int ++glusterd_store_max_op_version(xlator_t *this) ++{ ++ int ret = -1; ++ glusterd_conf_t *conf = NULL; ++ char op_version_str[15] = {0,}; ++ char path[PATH_MAX] = {0,}; ++ gf_store_handle_t *handle = NULL; ++ int32_t len = 0; ++ ++ conf = this->private; ++ ++ len = snprintf(path, PATH_MAX, "%s/%s", conf->workdir, ++ GLUSTERD_UPGRADE_FILE); ++ if ((len < 0) || (len >= PATH_MAX)) { ++ goto out; ++ } ++ ret = gf_store_handle_new(path, &handle); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_ERROR, 0, ++ GD_MSG_STORE_HANDLE_GET_FAIL, "Unable to get store " ++ "handle"); ++ goto out; ++ } ++ ++ /* These options need to be available for all users */ ++ ret = sys_chmod(handle->path, 0644); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_FILE_OP_FAILED, ++ "chmod error for %s", GLUSTERD_UPGRADE_FILE); ++ goto out; ++ } ++ ++ handle->fd = gf_store_mkstemp(handle); ++ if (handle->fd < 0) { ++ ret = -1; ++ goto out; ++ } ++ ++ snprintf(op_version_str, sizeof(op_version_str), "%d", ++ GD_OP_VERSION_MAX); ++ ret = gf_store_save_value(handle->fd, GD_MAX_OP_VERSION_KEY, ++ op_version_str); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_OP_VERS_STORE_FAIL, ++ "Storing op-version failed ret = %d", ret); ++ goto out; ++ } ++ ++ ret = gf_store_rename_tmppath(handle); ++out: ++ if (handle) { ++ if (ret && (handle->fd >= 0)) ++ gf_store_unlink_tmppath(handle); ++ } ++ ++ if (ret) ++ gf_msg(this->name, GF_LOG_ERROR, 0, ++ GD_MSG_GLUSTERD_GLOBAL_INFO_STORE_FAIL, ++ "Failed to store max op-version"); ++ if (handle) ++ gf_store_handle_destroy(handle); ++ return ret; ++} ++ ++int ++glusterd_retrieve_max_op_version(xlator_t *this, int *op_version) ++{ ++ char *op_version_str = NULL; ++ glusterd_conf_t *priv = NULL; ++ int ret = -1; ++ int tmp_version = 0; ++ char *tmp = NULL; ++ char path[PATH_MAX] = {0,}; ++ gf_store_handle_t *handle = NULL; ++ int32_t len = 0; ++ ++ priv = this->private; ++ ++ len = snprintf(path, PATH_MAX, "%s/%s", priv->workdir, ++ GLUSTERD_UPGRADE_FILE); ++ if ((len < 0) || (len >= PATH_MAX)) { ++ goto out; ++ } ++ ret = gf_store_handle_retrieve(path, &handle); ++ ++ if (ret) { ++ gf_msg_debug(this->name, 0, "Unable to get store handle!"); ++ goto out; ++ } ++ ++ ret = gf_store_retrieve_value(handle, GD_MAX_OP_VERSION_KEY, ++ &op_version_str); ++ if (ret) { ++ gf_msg_debug(this->name, 0, "No previous op_version present"); ++ goto out; ++ } ++ ++ tmp_version = strtol(op_version_str, &tmp, 10); ++ if ((tmp_version <= 0) || (tmp && strlen(tmp) > 1)) { ++ gf_msg(this->name, GF_LOG_WARNING, EINVAL, ++ GD_MSG_UNSUPPORTED_VERSION, "invalid version number"); ++ goto out; ++ } ++ ++ *op_version = tmp_version; ++ ++ ret = 0; ++out: ++ if (op_version_str) ++ GF_FREE(op_version_str); ++ if (handle) ++ gf_store_handle_destroy(handle); ++ return ret; ++} ++ ++int + glusterd_retrieve_op_version (xlator_t *this, int *op_version) + { + char *op_version_str = NULL; +diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h +index 383a475..76c5500 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-store.h ++++ b/xlators/mgmt/glusterd/src/glusterd-store.h +@@ -161,6 +161,12 @@ glusterd_retrieve_op_version (xlator_t *this, int *op_version); + int + glusterd_store_global_info (xlator_t *this); + ++int ++glusterd_retrieve_max_op_version(xlator_t *this, int *op_version); ++ ++int ++glusterd_store_max_op_version(xlator_t *this); ++ + int32_t + glusterd_store_retrieve_options (xlator_t *this); + +diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c +index ca17526..29d5de1 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.c ++++ b/xlators/mgmt/glusterd/src/glusterd.c +@@ -1428,6 +1428,7 @@ init (xlator_t *this) + gf_boolean_t upgrade = _gf_false; + gf_boolean_t downgrade = _gf_false; + char *localtime_logging = NULL; ++ int op_version = 0; + + #ifndef GF_DARWIN_HOST_OS + { +@@ -1976,6 +1977,27 @@ init (xlator_t *this) + } + + GF_ATOMIC_INIT(conf->blockers, 0); ++ ret = glusterd_handle_upgrade_downgrade(this->options, conf, upgrade, ++ downgrade); ++ if (ret) ++ goto out; ++ ++ ret = glusterd_retrieve_max_op_version(this, &op_version); ++ /* first condition indicates file isn't present which means this code ++ * change is hitting for the first time or someone has deleted it from ++ * the backend.second condition is when max op_version differs, in both ++ * cases volfiles should be regenerated ++ */ ++ if (op_version == 0 || op_version != GD_OP_VERSION_MAX) { ++ gf_log(this->name, GF_LOG_INFO, ++ "Regenerating volfiles due to a max op-version mismatch " ++ "or glusterd.upgrade file not being present, op_version " ++ "retrieved: %d, max op_version: %d", op_version, ++ GD_OP_VERSION_MAX); ++ glusterd_recreate_volfiles(conf); ++ ret = glusterd_store_max_op_version(this); ++ } ++ + /* If the peer count is less than 2 then this would be the best time to + * spawn process/bricks that may need (re)starting since last time + * (this) glusterd was up. */ +@@ -1983,11 +2005,6 @@ init (xlator_t *this) + glusterd_launch_synctask (glusterd_spawn_daemons, NULL); + + +- ret = glusterd_handle_upgrade_downgrade (this->options, conf, upgrade, +- downgrade); +- if (ret) +- goto out; +- + ret = glusterd_hooks_spawn_worker (this); + if (ret) + goto out; +diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h +index bfa8310..cbdca52 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.h ++++ b/xlators/mgmt/glusterd/src/glusterd.h +@@ -582,6 +582,9 @@ typedef enum { + + #define GLUSTERD_DEFAULT_PORT GF_DEFAULT_BASE_PORT + #define GLUSTERD_INFO_FILE "glusterd.info" ++#define GLUSTERD_UPGRADE_FILE \ ++ "glusterd.upgrade" /* zero byte file to detect a need for regenerating \ ++ volfiles in container mode */ + #define GLUSTERD_VOLUME_QUOTA_CONFIG "quota.conf" + #define GLUSTERD_VOLUME_DIR_PREFIX "vols" + #define GLUSTERD_PEER_DIR_PREFIX "peers" +@@ -1333,4 +1336,8 @@ glusterd_tier_prevalidate (dict_t *dict, char **op_errstr, + + int + glusterd_options_init (xlator_t *this); ++ ++int32_t ++glusterd_recreate_volfiles(glusterd_conf_t *conf); ++ + #endif +-- +1.8.3.1 + diff --git a/0468-core-move-invalid-port-logs-to-DEBUG-log-level.patch b/0468-core-move-invalid-port-logs-to-DEBUG-log-level.patch new file mode 100644 index 0000000..6f69339 --- /dev/null +++ b/0468-core-move-invalid-port-logs-to-DEBUG-log-level.patch @@ -0,0 +1,40 @@ +From 8eb95b2ebdedd61e7784cf2f18b9564d2d4ed0b9 Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Thu, 13 Dec 2018 10:11:58 +0530 +Subject: [PATCH 468/493] core: move invalid port logs to DEBUG log level + +Stop spamming "invalid port" logs in case sysadmin has reserved a large +number of ports. + +manline: +> Change-Id: I244ef7693560cc404b36cadc6b05d92ec0e908d3 +> fixes: bz#1656517 +> Signed-off-by: Milind Changire +> Reviewed-on: https://review.gluster.org/c/glusterfs/+/21809 + +Change-Id: I244ef7693560cc404b36cadc6b05d92ec0e908d3 +BUG: 1656217 +Signed-off-by: Milind Changire +Reviewed-on: https://code.engineering.redhat.com/gerrit/158483 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + libglusterfs/src/common-utils.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c +index 25600a9..1243754 100644 +--- a/libglusterfs/src/common-utils.c ++++ b/libglusterfs/src/common-utils.c +@@ -3373,7 +3373,7 @@ gf_ports_reserved (char *blocked_port, unsigned char *ports, uint32_t ceiling) + if (blocked_port[strlen(blocked_port) -1] == '\n') + blocked_port[strlen(blocked_port) -1] = '\0'; + if (gf_string2int32 (blocked_port, &tmp_port1) == 0) { +- if (tmp_port1 > ceiling ++ if (tmp_port1 > GF_PORT_MAX + || tmp_port1 < 0) { + gf_msg ("glusterfs-socket", GF_LOG_WARNING, 0, + LG_MSG_INVALID_PORT, "invalid port %d", +-- +1.8.3.1 + diff --git a/0469-nfs-set-ctx-for-every-inode-looked-up-nfs3_fh_resolv.patch b/0469-nfs-set-ctx-for-every-inode-looked-up-nfs3_fh_resolv.patch new file mode 100644 index 0000000..a265365 --- /dev/null +++ b/0469-nfs-set-ctx-for-every-inode-looked-up-nfs3_fh_resolv.patch @@ -0,0 +1,48 @@ +From 4a3e8888d7e866137287fced284b71ba152a17ad Mon Sep 17 00:00:00 2001 +From: Jiffin Tony Thottan +Date: Thu, 29 Nov 2018 19:22:40 +0530 +Subject: [PATCH 469/493] nfs : set ctx for every inode looked up + nfs3_fh_resolve_inode_lookup_cbk() + +The inode ctx for nfs xlator is set with help nfs_fix_generation. +But currently gnfs is crashing because inode_ctx is becoming null +nfs3_resolve_inode_hard() is used to perform a lookup on entire +path and looks like function is missing to set the ctx for inode. +This patch will set ctx for the inode which it looked on. + +Upstream reference : +>url: https://review.gluster.org/#/c/glusterfs/+/21749/ +>Change-Id: I464fa7f78df1bae990ebe97de8ccf6d5fb74fc9f +>fixes: bz#1651439 +>Signed-off-by: Jiffin Tony Thottan + +Change-Id: I464fa7f78df1bae990ebe97de8ccf6d5fb74fc9f +BUG: 1633177 +Signed-off-by: Jiffin Tony Thottan +Reviewed-on: https://code.engineering.redhat.com/gerrit/158676 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + xlators/nfs/server/src/nfs3-helpers.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c +index 0b97709..9bc8aff 100644 +--- a/xlators/nfs/server/src/nfs3-helpers.c ++++ b/xlators/nfs/server/src/nfs3-helpers.c +@@ -3660,6 +3660,12 @@ nfs3_fh_resolve_entry_lookup_cbk (call_frame_t *frame, void *cookie, + inode_lookup (linked_inode); + inode_unref (cs->resolvedloc.inode); + cs->resolvedloc.inode = linked_inode; ++ } else { ++ /* nfs3_fh_resolve_entry_hard() use to resolve entire path if needed. ++ * So the ctx for inode obtained from here need to set properly, ++ * otherwise it may result in a crash. ++ */ ++ nfs_fix_generation(this, inode); + } + err: + nfs3_call_resume (cs); +-- +1.8.3.1 + diff --git a/0470-dht-fix-use-after-free-in-dht_rmdir_readdirp_cbk.patch b/0470-dht-fix-use-after-free-in-dht_rmdir_readdirp_cbk.patch new file mode 100644 index 0000000..46e91de --- /dev/null +++ b/0470-dht-fix-use-after-free-in-dht_rmdir_readdirp_cbk.patch @@ -0,0 +1,87 @@ +From 870513f9bade449fa760a81e242102860a0fdc91 Mon Sep 17 00:00:00 2001 +From: N Balachandran +Date: Thu, 13 Dec 2018 10:54:15 +0530 +Subject: [PATCH 470/493] dht: fix use after free in dht_rmdir_readdirp_cbk + +The frame is freed when linkfile exist in dht_rmdir_is_subvol_empty(), +the following message use the freed local. + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/21446/ + +> Change-Id: I41191e8bd477f031a2444d5f15e578dc4f086e6b +> Updates: bz#1640489 +> Signed-off-by: Kinglong Mee + +Change-Id: Ia257e1da57cc486ab336e43f8e88187e984c70e2 +BUG: 1654103 +Author: Kinglong Mee +Signed-off-by: N Balachandran +Reviewed-on: https://code.engineering.redhat.com/gerrit/158486 +Tested-by: RHGS Build Bot +Reviewed-by: Raghavendra Gowdappa +--- + xlators/cluster/dht/src/dht-common.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c +index 2e19036..ff0099c 100644 +--- a/xlators/cluster/dht/src/dht-common.c ++++ b/xlators/cluster/dht/src/dht-common.c +@@ -10175,6 +10175,7 @@ dht_rmdir_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + xlator_t *prev = NULL; + xlator_t *src = NULL; + int ret = 0; ++ char *path = NULL; + + + local = frame->local; +@@ -10182,6 +10183,11 @@ dht_rmdir_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + src = prev; + + if (op_ret > 2) { ++ /* dht_rmdir_is_subvol_empty() may free the frame, ++ * copy path for logging. ++ */ ++ path = gf_strdup(local->loc.path); ++ + ret = dht_rmdir_is_subvol_empty (frame, this, entries, src); + + switch (ret) { +@@ -10192,27 +10198,24 @@ dht_rmdir_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + local->loc.path, op_ret); + local->op_ret = -1; + local->op_errno = ENOTEMPTY; +- goto done; ++ break; + default: + /* @ret number of linkfiles are getting unlinked */ + gf_msg_trace (this->name, 0, + "readdir on %s for %s found %d " +- "linkfiles", prev->name, +- local->loc.path, ret); ++ "linkfiles", ++ prev->name, path, ret); + break; + } + + } + +- +- if (ret) { +- return 0; +- } +- +-done: + /* readdirp failed or no linkto files were found on this subvol */ ++ if (!ret) { ++ dht_rmdir_readdirp_done(frame, this); ++ } ++ GF_FREE(path); + +- dht_rmdir_readdirp_done (frame, this); + return 0; + } + +-- +1.8.3.1 + diff --git a/0471-glusterd-migrating-profile-commands-to-mgmt_v3-frame.patch b/0471-glusterd-migrating-profile-commands-to-mgmt_v3-frame.patch new file mode 100644 index 0000000..74a29d6 --- /dev/null +++ b/0471-glusterd-migrating-profile-commands-to-mgmt_v3-frame.patch @@ -0,0 +1,507 @@ +From e68845ff7018e5d81d7979684b18e6eda449b088 Mon Sep 17 00:00:00 2001 +From: Sanju Rakonde +Date: Thu, 8 Nov 2018 18:50:18 +0530 +Subject: [PATCH 471/493] glusterd: migrating profile commands to mgmt_v3 + framework + +Current profile commands use the op_state machine framework. +Porting it to use the mgmt_v3 framework. + +The following tests were performed on the patch: +case 1: +1. On a 3 node cluster, created and started 3 volumes +2. Mounted all the three volumes and wrote some data +3. Started profile operation for all the volumes +4. Ran "gluster v status" from N1, + "gluster v profile info" form N2, + "gluster v profile info" from N3 simultaneously in a + loop for around 10000 times +5. Didn't find any cores generated. + +case 2: +1. Repeat the steps 1,2 and 3 from case 1. +2. Ran "gluster v status" from N1, + "gluster v profile info" form N2(terminal 1), + "gluster v profile info" from N2(terminal 2) + simultaneously in a loop. +3. No cores were generated. + +> fixes: bz#1654181 +> Change-Id: I83044cf5aee3970ef94066c89fcc41783ed468a6 +> Signed-off-by: Sanju Rakonde + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/21736/ + +Change-Id: I83044cf5aee3970ef94066c89fcc41783ed468a6 +BUG: 1639476 +Signed-off-by: Sanju Rakonde +Reviewed-on: https://code.engineering.redhat.com/gerrit/158631 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + libglusterfs/src/globals.h | 2 + + xlators/mgmt/glusterd/src/glusterd-handler.c | 18 +- + xlators/mgmt/glusterd/src/glusterd-mgmt.c | 240 +++++++++++++++++++++++++-- + xlators/mgmt/glusterd/src/glusterd-mgmt.h | 6 +- + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 4 +- + xlators/mgmt/glusterd/src/glusterd-op-sm.h | 6 + + 6 files changed, 252 insertions(+), 24 deletions(-) + +diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h +index 1bede2e..d2b0964 100644 +--- a/libglusterfs/src/globals.h ++++ b/libglusterfs/src/globals.h +@@ -111,6 +111,8 @@ + + #define GD_OP_VERSION_3_13_3 31303 /* Op-version for GlusterFS 3.13.3 */ + ++#define GD_OP_VERSION_6_0 60000 /* Op-version for GlusterFS 6.0 */ ++ + /* Downstream only change */ + #define GD_OP_VERSION_3_11_2 31102 /* Op-version for RHGS 3.3.1-async */ + #define GD_OP_VERSION_3_13_3 31303 /* Op-version for RHGS-3.4-Batch Update-1*/ +diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c +index 7486f51..90eaa95 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-handler.c ++++ b/xlators/mgmt/glusterd/src/glusterd-handler.c +@@ -28,6 +28,7 @@ + #include "glusterd-sm.h" + #include "glusterd-op-sm.h" + #include "glusterd-utils.h" ++#include "glusterd-mgmt.h" + #include "glusterd-server-quorum.h" + #include "glusterd-store.h" + #include "glusterd-locks.h" +@@ -3065,10 +3066,13 @@ __glusterd_handle_cli_profile_volume (rpcsvc_request_t *req) + int32_t op = 0; + char err_str[2048] = {0,}; + xlator_t *this = NULL; ++ glusterd_conf_t *conf = NULL; + + GF_ASSERT (req); + this = THIS; + GF_ASSERT (this); ++ conf = this->private; ++ GF_VALIDATE_OR_GOTO(this->name, conf, out); + + ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); + if (ret < 0) { +@@ -3109,12 +3113,18 @@ __glusterd_handle_cli_profile_volume (rpcsvc_request_t *req) + goto out; + } + +- ret = glusterd_op_begin (req, cli_op, dict, err_str, sizeof (err_str)); ++ if (conf->op_version < GD_OP_VERSION_6_0) { ++ gf_msg_debug(this->name, 0, "The cluster is operating at " ++ "version less than %d. Falling back to op-sm " ++ "framework.", GD_OP_VERSION_6_0); ++ ret = glusterd_op_begin(req, cli_op, dict, err_str, sizeof(err_str)); ++ glusterd_friend_sm(); ++ glusterd_op_sm(); ++ } else { ++ ret = glusterd_mgmt_v3_initiate_profile_phases(req, cli_op, dict); ++ } + + out: +- glusterd_friend_sm (); +- glusterd_op_sm (); +- + free (cli_req.dict.dict_val); + + if (ret) { +diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c +index d7da3c1..751d6e4 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c ++++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c +@@ -19,6 +19,7 @@ + #include "glusterd-locks.h" + #include "glusterd-mgmt.h" + #include "glusterd-op-sm.h" ++#include "glusterd-server-quorum.h" + #include "glusterd-volgen.h" + #include "glusterd-store.h" + #include "glusterd-snapshot-utils.h" +@@ -213,6 +214,16 @@ gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict, + } + break; + ++ case GD_OP_PROFILE_VOLUME: ++ ret = glusterd_op_stage_stats_volume(dict, op_errstr); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_WARNING, 0, ++ GD_MSG_PRE_VALIDATION_FAIL, ++ "prevalidation failed for profile operation."); ++ goto out; ++ } ++ break; ++ + case GD_OP_MAX_OPVERSION: + ret = 0; + break; +@@ -252,6 +263,16 @@ gd_mgmt_v3_brick_op_fn (glusterd_op_t op, dict_t *dict, + } + break; + } ++ case GD_OP_PROFILE_VOLUME: ++ { ++ ret = gd_brick_op_phase(op, rsp_dict, dict, op_errstr); ++ if (ret) { ++ gf_log(this->name, GF_LOG_WARNING, "%s brickop failed", ++ gd_op_list[op]); ++ goto out; ++ } ++ break; ++ } + default: + break; + } +@@ -406,6 +427,17 @@ gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict, + break; + + } ++ case GD_OP_PROFILE_VOLUME: ++ { ++ ret = glusterd_op_stats_volume(dict, op_errstr, rsp_dict); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_ERROR, 0, ++ GD_MSG_COMMIT_OP_FAIL, "commit failed " ++ "volume profile operation."); ++ goto out; ++ } ++ break; ++ } + + default: + break; +@@ -847,6 +879,7 @@ glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op, + case GD_OP_DETACH_TIER_STATUS: + case GD_OP_TIER_START_STOP: + case GD_OP_REMOVE_TIER_BRICK: ++ case GD_OP_PROFILE_VOLUME: + break; + case GD_OP_MAX_OPVERSION: + break; +@@ -1039,6 +1072,16 @@ glusterd_mgmt_v3_pre_validate (glusterd_op_t op, dict_t *req_dict, + goto out; + } + ++ if (op == GD_OP_PROFILE_VOLUME) { ++ ret = glusterd_validate_quorum(this, op, req_dict, op_errstr); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_SERVER_QUORUM_NOT_MET, "Server quorum " ++ "not met. Rejecting operation."); ++ goto out; ++ } ++ } ++ + /* Pre Validation on local node */ + ret = gd_mgmt_v3_pre_validate_fn (op, req_dict, op_errstr, + rsp_dict, op_errno); +@@ -1157,6 +1200,7 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict, + case GD_OP_REPLACE_BRICK: + case GD_OP_RESET_BRICK: + case GD_OP_ADD_TIER_BRICK: ++ case GD_OP_PROFILE_VOLUME: + { + ret = dict_get_str (dict, "volname", &volname); + if (ret) { +@@ -1309,12 +1353,11 @@ out: + } + + int +-glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *req_dict, char **op_errstr, +- uint32_t txn_generation) ++glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *rsp_dict, dict_t *req_dict, ++ char **op_errstr, uint32_t txn_generation) + { + int32_t ret = -1; + int32_t peer_cnt = 0; +- dict_t *rsp_dict = NULL; + glusterd_peerinfo_t *peerinfo = NULL; + struct syncargs args = {0}; + uuid_t peer_uuid = {0}; +@@ -1329,14 +1372,6 @@ glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *req_dict, char **op_errstr, + GF_ASSERT (req_dict); + GF_ASSERT (op_errstr); + +- rsp_dict = dict_new (); +- if (!rsp_dict) { +- gf_msg (this->name, GF_LOG_ERROR, 0, +- GD_MSG_DICT_CREATE_FAIL, +- "Failed to create response dictionary"); +- goto out; +- } +- + /* Perform brick op on local node */ + ret = gd_mgmt_v3_brick_op_fn (op, req_dict, op_errstr, + rsp_dict); +@@ -1361,11 +1396,8 @@ glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *req_dict, char **op_errstr, + goto out; + } + +- dict_unref (rsp_dict); +- rsp_dict = NULL; +- + /* Sending brick op req to other nodes in the cluster */ +- gd_syncargs_init (&args, NULL); ++ gd_syncargs_init (&args, rsp_dict); + synctask_barrier_init((&args)); + peer_cnt = 0; + +@@ -2108,6 +2140,180 @@ out: + } + + int32_t ++glusterd_mgmt_v3_initiate_profile_phases (rpcsvc_request_t *req, ++ glusterd_op_t op, dict_t *dict) ++{ ++ int32_t ret = -1; ++ int32_t op_ret = -1; ++ dict_t *req_dict = NULL; ++ dict_t *tmp_dict = NULL; ++ glusterd_conf_t *conf = NULL; ++ char *op_errstr = NULL; ++ xlator_t *this = NULL; ++ gf_boolean_t is_acquired = _gf_false; ++ uuid_t *originator_uuid = NULL; ++ uint32_t txn_generation = 0; ++ uint32_t op_errno = 0; ++ ++ this = THIS; ++ GF_ASSERT (this); ++ GF_ASSERT (req); ++ GF_ASSERT (dict); ++ conf = this->private; ++ GF_ASSERT (conf); ++ ++ /* Save the peer list generation */ ++ txn_generation = conf->generation; ++ cmm_smp_rmb (); ++ /* This read memory barrier makes sure that this assignment happens here ++ * only and is not reordered and optimized by either the compiler or the ++ * processor. ++ */ ++ ++ /* Save the MY_UUID as the originator_uuid. This originator_uuid ++ * will be used by is_origin_glusterd() to determine if a node ++ * is the originator node for a command. */ ++ originator_uuid = GF_CALLOC (1, sizeof(uuid_t), ++ gf_common_mt_uuid_t); ++ if (!originator_uuid) { ++ ret = -1; ++ goto out; ++ } ++ ++ gf_uuid_copy (*originator_uuid, MY_UUID); ++ ret = dict_set_bin (dict, "originator_uuid", ++ originator_uuid, sizeof (uuid_t)); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_DICT_SET_FAILED, ++ "Failed to set originator_uuid."); ++ GF_FREE (originator_uuid); ++ goto out; ++ } ++ ++ /* Marking the operation as complete synctasked */ ++ ret = dict_set_int32 (dict, "is_synctasked", _gf_true); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_DICT_SET_FAILED, ++ "Failed to set synctasked flag."); ++ goto out; ++ } ++ ++ /* Use a copy at local unlock as cli response will be sent before ++ * the unlock and the volname in the dict might be removed */ ++ tmp_dict = dict_new(); ++ if (!tmp_dict) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_DICT_CREATE_FAIL, "Unable to create dict"); ++ goto out; ++ } ++ dict_copy (dict, tmp_dict); ++ ++ /* LOCKDOWN PHASE - Acquire mgmt_v3 locks */ ++ ret = glusterd_mgmt_v3_initiate_lockdown (op, dict, &op_errstr, ++ &op_errno, &is_acquired, ++ txn_generation); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_MGMTV3_LOCKDOWN_FAIL, ++ "mgmt_v3 lockdown failed."); ++ goto out; ++ } ++ ++ /* BUILD PAYLOAD */ ++ ret = glusterd_mgmt_v3_build_payload (&req_dict, &op_errstr, dict, op); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_MGMTV3_PAYLOAD_BUILD_FAIL, LOGSTR_BUILD_PAYLOAD, ++ gd_op_list[op]); ++ if (op_errstr == NULL) ++ gf_asprintf (&op_errstr, OPERRSTR_BUILD_PAYLOAD); ++ goto out; ++ } ++ ++ /* PRE-COMMIT VALIDATE PHASE */ ++ ret = glusterd_mgmt_v3_pre_validate (op, req_dict, &op_errstr, ++ &op_errno, txn_generation); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_PRE_VALIDATION_FAIL, "Pre Validation Failed"); ++ goto out; ++ } ++ ++ /* BRICK-OPS */ ++ ret = glusterd_mgmt_v3_brick_op(op, dict, req_dict, &op_errstr, ++ txn_generation); ++ if (ret) { ++ gf_log(this->name, GF_LOG_ERROR, "Brick Op Failed"); ++ goto out; ++ } ++ ++ /* COMMIT OP PHASE */ ++ ret = glusterd_mgmt_v3_commit (op, dict, req_dict, &op_errstr, ++ &op_errno, txn_generation); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_COMMIT_OP_FAIL, "Commit Op Failed"); ++ goto out; ++ } ++ ++ /* POST-COMMIT VALIDATE PHASE */ ++ /* As of now, post_validate is not trying to cleanup any failed ++ commands. So as of now, I am sending 0 (op_ret as 0). ++ */ ++ ret = glusterd_mgmt_v3_post_validate (op, 0, dict, req_dict, &op_errstr, ++ txn_generation); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_POST_VALIDATION_FAIL, "Post Validation Failed"); ++ goto out; ++ } ++ ++ ret = 0; ++out: ++ op_ret = ret; ++ /* UNLOCK PHASE FOR PEERS*/ ++ (void) glusterd_mgmt_v3_release_peer_locks (op, dict, op_ret, ++ &op_errstr, is_acquired, ++ txn_generation); ++ ++ /* LOCAL VOLUME(S) UNLOCK */ ++ if (is_acquired) { ++ /* Trying to release multiple mgmt_v3 locks */ ++ ret = glusterd_multiple_mgmt_v3_unlock (tmp_dict, MY_UUID); ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_MGMTV3_UNLOCK_FAIL, ++ "Failed to release mgmt_v3 locks on localhost"); ++ op_ret = ret; ++ } ++ } ++ ++ if (op_ret && (op_errno == 0)) ++ op_errno = EG_INTRNL; ++ ++ if (op != GD_OP_MAX_OPVERSION) { ++ /* SEND CLI RESPONSE */ ++ glusterd_op_send_cli_response (op, op_ret, op_errno, req, ++ dict, op_errstr); ++ } ++ ++ if (req_dict) ++ dict_unref (req_dict); ++ ++ if (tmp_dict) ++ dict_unref (tmp_dict); ++ ++ if (op_errstr) { ++ GF_FREE (op_errstr); ++ op_errstr = NULL; ++ } ++ ++ return 0; ++} ++ ++int32_t + glusterd_mgmt_v3_initiate_all_phases (rpcsvc_request_t *req, glusterd_op_t op, + dict_t *dict) + { +@@ -2465,7 +2671,7 @@ glusterd_mgmt_v3_initiate_snap_phases (rpcsvc_request_t *req, glusterd_op_t op, + goto out; + } + +- ret = glusterd_mgmt_v3_brick_op (op, req_dict, &op_errstr, ++ ret = glusterd_mgmt_v3_brick_op (op, dict, req_dict, &op_errstr, + txn_generation); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, +@@ -2526,7 +2732,7 @@ unbarrier: + goto out; + } + +- ret = glusterd_mgmt_v3_brick_op (op, req_dict, &op_errstr, ++ ret = glusterd_mgmt_v3_brick_op (op, dict, req_dict, &op_errstr, + txn_generation); + + if (ret) { +diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-mgmt.h +index 2215f17..eff070d 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.h ++++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.h +@@ -37,7 +37,11 @@ glusterd_mgmt_v3_initiate_all_phases (rpcsvc_request_t *req, glusterd_op_t op, + dict_t *dict); + + int32_t +-glusterd_mgmt_v3_initiate_snap_phases (rpcsvc_request_t *req, glusterd_op_t op, ++glusterd_mgmt_v3_initiate_profile_phases(rpcsvc_request_t *req, ++ glusterd_op_t op, dict_t *dict); ++ ++int32_t ++glusterd_mgmt_v3_initiate_snap_phases(rpcsvc_request_t *req, glusterd_op_t op, + dict_t *dict); + + int +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index 52a3db0..9f76ab3 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -2032,7 +2032,7 @@ glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr) + return ret; + } + +-static int ++int + glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr) + { + int ret = -1; +@@ -3322,7 +3322,7 @@ glusterd_remove_profile_volume_options (glusterd_volinfo_t *volinfo) + dict_del (volinfo->dict, fd_stats_key); + } + +-static int ++int + glusterd_op_stats_volume (dict_t *dict, char **op_errstr, + dict_t *rsp_dict) + { +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h +index f2aee9c..e64d368 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h +@@ -312,4 +312,10 @@ glusterd_dict_set_volid (dict_t *dict, char *volname, char **op_errstr); + + int32_t + glusterd_tier_op (xlator_t *this, void *data); ++ ++int ++glusterd_op_stats_volume (dict_t *dict, char **op_errstr, dict_t *rsp_dict); ++ ++int ++glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr); + #endif +-- +1.8.3.1 + diff --git a/0472-glusterd-introduce-a-new-op-version-for-rhgs-3.4.3.patch b/0472-glusterd-introduce-a-new-op-version-for-rhgs-3.4.3.patch new file mode 100644 index 0000000..2c54457 --- /dev/null +++ b/0472-glusterd-introduce-a-new-op-version-for-rhgs-3.4.3.patch @@ -0,0 +1,72 @@ +From ff97d22a02c02ad5edced2755a799a587b45cb79 Mon Sep 17 00:00:00 2001 +From: Sanju Rakonde +Date: Mon, 17 Dec 2018 14:07:01 +0530 +Subject: [PATCH 472/493] glusterd: introduce a new op-version for rhgs-3.4.3 + +This patch introduces a new op-version 31305 for rhgs-3.4.3 and +sets the max op-version to 31305. + +For migrating profile commands (commit e68845ff7018e5d81d7979684b18e6eda449b088) +we used GD_OP_VERSION_6_0 in upstream. we are changing +it to GD_OP_VERSION_3_13_5 here. + +Label: DOWNSTREAM ONLY + +Change-Id: Ie3a05c70eb4e406889c468343f54e999b1218f19 +BUG: 1639476 +Signed-off-by: Sanju Rakonde +Reviewed-on: https://code.engineering.redhat.com/gerrit/158795 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + libglusterfs/src/globals.h | 5 ++--- + xlators/mgmt/glusterd/src/glusterd-handler.c | 4 ++-- + 2 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h +index d2b0964..343263c 100644 +--- a/libglusterfs/src/globals.h ++++ b/libglusterfs/src/globals.h +@@ -43,7 +43,7 @@ + */ + #define GD_OP_VERSION_MIN 1 /* MIN is the fresh start op-version, mostly + should not change */ +-#define GD_OP_VERSION_MAX GD_OP_VERSION_3_13_4 /* MAX VERSION is the maximum ++#define GD_OP_VERSION_MAX GD_OP_VERSION_3_13_5 /* MAX VERSION is the maximum + count in VME table, should + keep changing with + introduction of newer +@@ -111,12 +111,11 @@ + + #define GD_OP_VERSION_3_13_3 31303 /* Op-version for GlusterFS 3.13.3 */ + +-#define GD_OP_VERSION_6_0 60000 /* Op-version for GlusterFS 6.0 */ +- + /* Downstream only change */ + #define GD_OP_VERSION_3_11_2 31102 /* Op-version for RHGS 3.3.1-async */ + #define GD_OP_VERSION_3_13_3 31303 /* Op-version for RHGS-3.4-Batch Update-1*/ + #define GD_OP_VERSION_3_13_4 31304 /* Op-version for RHGS-3.4-Batch Update-2*/ ++#define GD_OP_VERSION_3_13_5 31305 /* Op-version for RHGS-3.4-Batch Update-3*/ + + #include "xlator.h" + +diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c +index 90eaa95..c71bf3c 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-handler.c ++++ b/xlators/mgmt/glusterd/src/glusterd-handler.c +@@ -3113,10 +3113,10 @@ __glusterd_handle_cli_profile_volume (rpcsvc_request_t *req) + goto out; + } + +- if (conf->op_version < GD_OP_VERSION_6_0) { ++ if (conf->op_version < GD_OP_VERSION_3_13_5) { + gf_msg_debug(this->name, 0, "The cluster is operating at " + "version less than %d. Falling back to op-sm " +- "framework.", GD_OP_VERSION_6_0); ++ "framework.", GD_OP_VERSION_3_13_5); + ret = glusterd_op_begin(req, cli_op, dict, err_str, sizeof(err_str)); + glusterd_friend_sm(); + glusterd_op_sm(); +-- +1.8.3.1 + diff --git a/0473-rpc-bump-up-server.event-threads.patch b/0473-rpc-bump-up-server.event-threads.patch new file mode 100644 index 0000000..23548ba --- /dev/null +++ b/0473-rpc-bump-up-server.event-threads.patch @@ -0,0 +1,64 @@ +From 63e8fb2b6a3846c3f3a0e1db6275a8c03dbbc6ff Mon Sep 17 00:00:00 2001 +From: Milind Changire +Date: Thu, 13 Dec 2018 10:00:45 +0530 +Subject: [PATCH 473/493] rpc: bump up server.event-threads + +Problem: +A single event-thread causes performance issues in the system. + +Solution: +Bump up event-threads to 2 to make the system more performant. +This helps in making the system more responsive and helps avoid the +ping-timer-expiry problem as well. However, setting the event-threads +to 2 is not the only thing required to avoid ping-timer-expiry issues. + +NOTE: +NFS xlator option nfs.event-threads does not yet exist here. + +mainline: +> Change-Id: Idb0fd49e078db3bd5085dd083b0cdc77b59ddb00 +> fixes: bz#1653277 +> Signed-off-by: Milind Changire +> Reviewed-on: https://review.gluster.org/c/glusterfs/+/21719 + +Change-Id: Idb0fd49e078db3bd5085dd083b0cdc77b59ddb00 +BUG: 1652537 +Signed-off-by: Milind Changire +Reviewed-on: https://code.engineering.redhat.com/gerrit/158482 +Tested-by: RHGS Build Bot +Reviewed-by: Raghavendra Gowdappa +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + libglusterfs/src/glusterfs.h | 2 +- + xlators/protocol/server/src/server.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h +index 3e2f426..d06d8cf 100644 +--- a/libglusterfs/src/glusterfs.h ++++ b/libglusterfs/src/glusterfs.h +@@ -249,7 +249,7 @@ enum gf_internal_fop_indicator { + + #define GLUSTERFS_RPC_REPLY_SIZE 24 + +-#define STARTING_EVENT_THREADS 1 ++#define STARTING_EVENT_THREADS 2 + + #define DEFAULT_VAR_RUN_DIRECTORY DATADIR "/run/gluster" + #define DEFAULT_GLUSTERFSD_MISC_DIRETORY DATADIR "/lib/misc/glusterfsd" +diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c +index 6f510ea..1046152 100644 +--- a/xlators/protocol/server/src/server.c ++++ b/xlators/protocol/server/src/server.c +@@ -1932,7 +1932,7 @@ struct volume_options options[] = { + .type = GF_OPTION_TYPE_INT, + .min = 1, + .max = 1024, +- .default_value = "1", ++ .default_value = "2", + .description = "Specifies the number of event threads to execute " + "in parallel. Larger values would help process" + " responses faster, depending on available processing" +-- +1.8.3.1 + diff --git a/0474-afr-open_ftruncate_cbk-should-read-fd-from-local-con.patch b/0474-afr-open_ftruncate_cbk-should-read-fd-from-local-con.patch new file mode 100644 index 0000000..ffd0177 --- /dev/null +++ b/0474-afr-open_ftruncate_cbk-should-read-fd-from-local-con.patch @@ -0,0 +1,45 @@ +From cdedd41ab825bfe59e8d1739fdea625a51f659f9 Mon Sep 17 00:00:00 2001 +From: Soumya Koduri +Date: Fri, 9 Nov 2018 02:29:52 -0500 +Subject: [PATCH 474/493] afr: open_ftruncate_cbk should read fd from + local->cont.open struct + +afr_open stores the fd as part of its local->cont.open struct +but when it calls ftruncate (if open flags contain O_TRUNC), the +corresponding cbk function (afr_ open_ftruncate_cbk) is +incorrectly referencing uninitialized local->fd. This patch fixes +the same. + +Upstream reference: +Change-Id: Icbdedbd1b8cfea11d8f41b6e5c4cb4b44d989aba +> updates: bz#1648687 +> review-url: https://review.gluster.org/#/c/glusterfs/+/21617/ + +BUG: 1655578 +updates: bz#1655578 +Signed-off-by: Soumya Koduri +Change-Id: I9c26eadd811fdd32630227f3130dec28e4b6972b +Reviewed-on: https://code.engineering.redhat.com/gerrit/158799 +Tested-by: RHGS Build Bot +Reviewed-by: Karthik Subrahmanya +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + xlators/cluster/afr/src/afr-open.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xlators/cluster/afr/src/afr-open.c b/xlators/cluster/afr/src/afr-open.c +index 6c625cc..d820462 100644 +--- a/xlators/cluster/afr/src/afr-open.c ++++ b/xlators/cluster/afr/src/afr-open.c +@@ -62,7 +62,7 @@ afr_open_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + afr_local_t * local = frame->local; + + AFR_STACK_UNWIND (open, frame, local->op_ret, local->op_errno, +- local->fd, xdata); ++ local->cont.open.fd, xdata); + return 0; + } + +-- +1.8.3.1 + diff --git a/0475-glusterd-perform-store-operation-in-cleanup-lock.patch b/0475-glusterd-perform-store-operation-in-cleanup-lock.patch new file mode 100644 index 0000000..f24e47c --- /dev/null +++ b/0475-glusterd-perform-store-operation-in-cleanup-lock.patch @@ -0,0 +1,175 @@ +From db15e8fe12b7148b2da975d915573cb24c4ee1c9 Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Thu, 22 Nov 2018 09:58:52 +0530 +Subject: [PATCH 475/493] glusterd: perform store operation in cleanup lock + +All glusterd store operation and cleanup thread should work under a +critical section to avoid any partial store write. + +> Change-Id: I4f12e738f597a1f925c87ea2f42565dcf9ecdb9d +> Fixes: bz#1652430 +> Signed-off-by: Atin Mukherjee + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/21702/ + +Change-Id: I4f12e738f597a1f925c87ea2f42565dcf9ecdb9d +BUG: 1654161 +Signed-off-by: Sanju Rakonde +Reviewed-on: https://code.engineering.redhat.com/gerrit/158804 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + glusterfsd/src/glusterfsd.c | 73 ++++++++++++++++-------------- + libglusterfs/src/glusterfs.h | 1 + + xlators/mgmt/glusterd/src/glusterd-store.c | 10 +++- + 3 files changed, 49 insertions(+), 35 deletions(-) + +diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c +index 03bca24..57effbd 100644 +--- a/glusterfsd/src/glusterfsd.c ++++ b/glusterfsd/src/glusterfsd.c +@@ -1395,43 +1395,46 @@ cleanup_and_exit (int signum) + if (ctx->cleanup_started) + return; + +- ctx->cleanup_started = 1; ++ pthread_mutex_lock(&ctx->cleanup_lock); ++ { ++ ctx->cleanup_started = 1; + +- /* signout should be sent to all the bricks in case brick mux is enabled +- * and multiple brick instances are attached to this process +- */ +- if (ctx->active) { +- top = ctx->active->first; +- for (trav_p = &top->children; *trav_p; +- trav_p = &(*trav_p)->next) { +- victim = (*trav_p)->xlator; +- glusterfs_mgmt_pmap_signout (ctx, victim->name); ++ /* signout should be sent to all the bricks in case brick mux ++ * is enabled and multiple brick instances are attached to this ++ * process ++ */ ++ if (ctx->active) { ++ top = ctx->active->first; ++ for (trav_p = &top->children; *trav_p; ++ trav_p = &(*trav_p)->next) { ++ victim = (*trav_p)->xlator; ++ glusterfs_mgmt_pmap_signout (ctx, victim->name); ++ } ++ } else { ++ glusterfs_mgmt_pmap_signout (ctx, NULL); + } +- } else { +- glusterfs_mgmt_pmap_signout (ctx, NULL); +- } + +- /* below part is a racy code where the rpcsvc object is freed. +- * But in another thread (epoll thread), upon poll error in the +- * socket the transports are cleaned up where again rpcsvc object +- * is accessed (which is already freed by the below function). +- * Since the process is about to be killed dont execute the function +- * below. +- */ +- /* if (ctx->listener) { */ +- /* (void) glusterfs_listener_stop (ctx); */ +- /* } */ ++ /* below part is a racy code where the rpcsvc object is freed. ++ * But in another thread (epoll thread), upon poll error in the ++ * socket the transports are cleaned up where again rpcsvc object ++ * is accessed (which is already freed by the below function). ++ * Since the process is about to be killed dont execute the ++ * function below. ++ */ ++ /* if (ctx->listener) { */ ++ /* (void) glusterfs_listener_stop (ctx); */ ++ /* } */ + +- /* Call fini() of FUSE xlator first: +- * so there are no more requests coming and +- * 'umount' of mount point is done properly */ +- trav = ctx->master; +- if (trav && trav->fini) { +- THIS = trav; +- trav->fini (trav); +- } ++ /* Call fini() of FUSE xlator first: ++ * so there are no more requests coming and ++ * 'umount' of mount point is done properly */ ++ trav = ctx->master; ++ if (trav && trav->fini) { ++ THIS = trav; ++ trav->fini (trav); ++ } + +- glusterfs_pidfile_cleanup (ctx); ++ glusterfs_pidfile_cleanup (ctx); + + #if 0 + /* TODO: Properly do cleanup_and_exit(), with synchronization */ +@@ -1442,8 +1445,9 @@ cleanup_and_exit (int signum) + } + #endif + +- trav = NULL; +- ++ trav = NULL; ++ } ++ pthread_mutex_unlock(&ctx->cleanup_lock); + /* NOTE: Only the least significant 8 bits i.e (signum & 255) + will be available to parent process on calling exit() */ + exit(abs(signum)); +@@ -1598,6 +1602,7 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx) + goto out; + + pthread_mutex_init (&ctx->notify_lock, NULL); ++ pthread_mutex_init(&ctx->cleanup_lock, NULL); + pthread_cond_init (&ctx->notify_cond, NULL); + + ctx->clienttable = gf_clienttable_alloc(); +diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h +index d06d8cf..c12e94e 100644 +--- a/libglusterfs/src/glusterfs.h ++++ b/libglusterfs/src/glusterfs.h +@@ -574,6 +574,7 @@ struct _glusterfs_ctx { + char btbuf[GF_BACKTRACE_LEN]; + + pthread_mutex_t notify_lock; ++ pthread_mutex_t cleanup_lock; + pthread_cond_t notify_cond; + int notifying; + +diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c +index f276fef..b3c4d9a 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-store.c ++++ b/xlators/mgmt/glusterd/src/glusterd-store.c +@@ -1792,10 +1792,17 @@ out: + int32_t + glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac) + { +- int32_t ret = -1; ++ int32_t ret = -1; ++ glusterfs_ctx_t *ctx = NULL; ++ xlator_t *this = NULL; + ++ this = THIS; ++ GF_ASSERT(this); ++ ctx = this->ctx; ++ GF_ASSERT(ctx); + GF_ASSERT (volinfo); + ++ pthread_mutex_lock(&ctx->cleanup_lock); + pthread_mutex_lock(&volinfo->store_volinfo_lock); + { + glusterd_perform_volinfo_version_action(volinfo, ac); +@@ -1837,6 +1844,7 @@ glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t a + } + unlock: + pthread_mutex_unlock(&volinfo->store_volinfo_lock); ++ pthread_mutex_unlock(&ctx->cleanup_lock); + if (ret) + glusterd_store_volume_cleanup_tmp(volinfo); + +-- +1.8.3.1 + diff --git a/0476-afr-add-checks-for-allowing-lookups.patch b/0476-afr-add-checks-for-allowing-lookups.patch new file mode 100644 index 0000000..6adfb0f --- /dev/null +++ b/0476-afr-add-checks-for-allowing-lookups.patch @@ -0,0 +1,610 @@ +From e3f6fc1ccff95145b94aea9405cd136ada9000bc Mon Sep 17 00:00:00 2001 +From: Ravishankar N +Date: Wed, 16 Aug 2017 18:01:17 +0530 +Subject: [PATCH 476/493] afr: add checks for allowing lookups + +Patch in upstream master: https://review.gluster.org/#/c/glusterfs/+/17673/ + +Problem: +In an arbiter volume, lookup was being served from one of the sink +bricks (source brick was down). shard uses the iatt values from lookup cbk +to calculate the size and block count, which in this case were incorrect +values. shard_local_t->last_block was thus initialised to -1, resulting +in an infinite while loop in shard_common_resolve_shards(). + +Fix: +Use client quorum logic to allow or fail the lookups from afr if there +are no readable subvolumes. So in replica-3 or arbiter vols, if there is +no good copy or if quorum is not met, fail lookup with ENOTCONN. + +With this fix, we are also removing support for quorum-reads xlator +option. So if quorum is not met, neither read nor write txns are allowed +and we fail the fop with ENOTCONN. + +Change-Id: Ic65c00c24f77ece007328b421494eee62a505fa0 +BUG: 1362129 +Signed-off-by: Ravishankar N +Reviewed-on: https://code.engineering.redhat.com/gerrit/158650 +Tested-by: RHGS Build Bot +Reviewed-by: Karthik Subrahmanya +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + tests/basic/afr/quorum.t | 23 ---- + tests/bugs/replicate/bug-977797.t | 2 + + xlators/cluster/afr/src/afr-common.c | 244 +++++++++++++++++++++------------ + xlators/cluster/afr/src/afr-read-txn.c | 3 +- + xlators/cluster/afr/src/afr.c | 7 +- + xlators/cluster/afr/src/afr.h | 1 - + 6 files changed, 164 insertions(+), 116 deletions(-) + +diff --git a/tests/basic/afr/quorum.t b/tests/basic/afr/quorum.t +index 252e254..58116ba 100644 +--- a/tests/basic/afr/quorum.t ++++ b/tests/basic/afr/quorum.t +@@ -31,11 +31,7 @@ TEST $CLI volume set $V0 cluster.quorum-count 2 + TEST test_write + TEST kill_brick $V0 $H0 $B0/${V0}1 + TEST ! test_write +-EXPECT "abc" cat $M0/b +-TEST $CLI volume set $V0 cluster.quorum-reads on +-EXPECT_WITHIN $CONFIG_UPDATE_TIMEOUT "1" mount_get_option_value $M0 $V0-replicate-0 quorum-reads + TEST ! cat $M0/b +-TEST $CLI volume reset $V0 cluster.quorum-reads + + TEST $CLI volume set $V0 cluster.quorum-type auto + EXPECT auto volume_option $V0 cluster.quorum-type +@@ -44,11 +40,7 @@ EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0 + TEST test_write + TEST kill_brick $V0 $H0 $B0/${V0}1 + TEST ! test_write +-EXPECT "abc" cat $M0/b +-TEST $CLI volume set $V0 cluster.quorum-reads on +-EXPECT_WITHIN $CONFIG_UPDATE_TIMEOUT "1" mount_get_option_value $M0 $V0-replicate-0 quorum-reads + TEST ! cat $M0/b +-TEST $CLI volume reset $V0 cluster.quorum-reads + + TEST $CLI volume set $V0 cluster.quorum-type none + EXPECT none volume_option $V0 cluster.quorum-type +@@ -57,11 +49,6 @@ TEST test_write + TEST $CLI volume reset $V0 cluster.quorum-type + TEST test_write + EXPECT "abc" cat $M0/b +-TEST $CLI volume set $V0 cluster.quorum-reads on +-EXPECT_WITHIN $CONFIG_UPDATE_TIMEOUT "1" mount_get_option_value $M0 $V0-replicate-0 quorum-reads +-EXPECT "abc" cat $M0/b +-TEST $CLI volume reset $V0 cluster.quorum-reads +- + + cleanup; + TEST glusterd; +@@ -86,24 +73,14 @@ TEST $CLI volume set $V0 cluster.quorum-count 3 + TEST test_write + TEST kill_brick $V0 $H0 $B0/${V0}1 + TEST ! test_write +-EXPECT "abc" cat $M0/b +-TEST $CLI volume set $V0 cluster.quorum-reads on +-EXPECT_WITHIN $CONFIG_UPDATE_TIMEOUT "1" mount_get_option_value $M0 $V0-replicate-0 quorum-reads + TEST ! cat $M0/b +-TEST $CLI volume reset $V0 cluster.quorum-reads +- + + TEST $CLI volume set $V0 cluster.quorum-type auto + EXPECT auto volume_option $V0 cluster.quorum-type + TEST test_write + TEST kill_brick $V0 $H0 $B0/${V0}3 + TEST ! test_write +-EXPECT "abc" cat $M0/b +-TEST $CLI volume set $V0 cluster.quorum-reads on +-EXPECT_WITHIN $CONFIG_UPDATE_TIMEOUT "1" mount_get_option_value $M0 $V0-replicate-0 quorum-reads + TEST ! cat $M0/b +-TEST $CLI volume reset $V0 cluster.quorum-reads +- + + TEST $CLI volume set $V0 cluster.quorum-type none + EXPECT none volume_option $V0 cluster.quorum-type +diff --git a/tests/bugs/replicate/bug-977797.t b/tests/bugs/replicate/bug-977797.t +index ea9a98a..fee8205 100755 +--- a/tests/bugs/replicate/bug-977797.t ++++ b/tests/bugs/replicate/bug-977797.t +@@ -53,6 +53,8 @@ TEST chmod 757 $M0/a/file + TEST $CLI volume start $V0 force + EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1; + ++#Trigger entry heal of $M0/a ++getfattr -n user.nosuchattr $M0/a + dd if=$M0/a/file of=/dev/null bs=1024k + #read fails, but heal is triggered. + TEST [ $? -ne 0 ] +diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c +index 10d9620..231de9d 100644 +--- a/xlators/cluster/afr/src/afr-common.c ++++ b/xlators/cluster/afr/src/afr-common.c +@@ -47,9 +47,7 @@ + int32_t + afr_quorum_errno (afr_private_t *priv) + { +- if (priv->quorum_reads) +- return ENOTCONN; +- return EROFS; ++ return ENOTCONN; + } + + int +@@ -1154,8 +1152,6 @@ afr_replies_interpret (call_frame_t *frame, xlator_t *this, inode_t *inode, + return ret; + } + +- +- + int + afr_refresh_selfheal_done (int ret, call_frame_t *heal, void *opaque) + { +@@ -1726,6 +1722,29 @@ afr_inode_read_subvol_type_get (inode_t *inode, xlator_t *this, + return ret; + } + ++void ++afr_readables_intersect_get (inode_t *inode, xlator_t *this, int *event, ++ unsigned char *intersection) ++{ ++ afr_private_t *priv = NULL; ++ unsigned char *data_readable = NULL; ++ unsigned char *metadata_readable = NULL; ++ unsigned char *intersect = NULL; ++ ++ priv = this->private; ++ data_readable = alloca0 (priv->child_count); ++ metadata_readable = alloca0 (priv->child_count); ++ intersect = alloca0 (priv->child_count); ++ ++ afr_inode_read_subvol_get (inode, this, data_readable, ++ metadata_readable, event); ++ ++ AFR_INTERSECT (intersect, data_readable, metadata_readable, ++ priv->child_count); ++ if (intersection) ++ memcpy (intersection, intersect, ++ sizeof (*intersection) * priv->child_count); ++} + + int + afr_read_subvol_get (inode_t *inode, xlator_t *this, int *subvol_p, +@@ -1734,8 +1753,6 @@ afr_read_subvol_get (inode_t *inode, xlator_t *this, int *subvol_p, + afr_read_subvol_args_t *args) + { + afr_private_t *priv = NULL; +- unsigned char *data_readable = NULL; +- unsigned char *metadata_readable = NULL; + unsigned char *readable = NULL; + unsigned char *intersection = NULL; + int subvol = -1; +@@ -1744,17 +1761,11 @@ afr_read_subvol_get (inode_t *inode, xlator_t *this, int *subvol_p, + priv = this->private; + + readable = alloca0 (priv->child_count); +- data_readable = alloca0 (priv->child_count); +- metadata_readable = alloca0 (priv->child_count); + intersection = alloca0 (priv->child_count); + + afr_inode_read_subvol_type_get (inode, this, readable, &event, type); + +- afr_inode_read_subvol_get (inode, this, data_readable, metadata_readable, +- &event); +- +- AFR_INTERSECT (intersection, data_readable, metadata_readable, +- priv->child_count); ++ afr_readables_intersect_get (inode, this, &event, intersection); + + if (AFR_COUNT (intersection, priv->child_count) > 0) + subvol = afr_read_subvol_select_by_policy (inode, this, +@@ -2188,18 +2199,28 @@ afr_get_parent_read_subvol (xlator_t *this, inode_t *parent, + + int + afr_read_subvol_decide (inode_t *inode, xlator_t *this, +- afr_read_subvol_args_t *args) ++ afr_read_subvol_args_t *args, unsigned char *readable) + { +- int data_subvol = -1; +- int mdata_subvol = -1; ++ int event = 0; ++ afr_private_t *priv = NULL; ++ unsigned char *intersection = NULL; ++ ++ priv = this->private; ++ intersection = alloca0 (priv->child_count); ++ ++ afr_readables_intersect_get (inode, this, &event, intersection); + +- data_subvol = afr_data_subvol_get (inode, this, NULL, NULL, NULL, args); +- mdata_subvol = afr_metadata_subvol_get (inode, this, +- NULL, NULL, NULL, args); +- if (data_subvol == -1 || mdata_subvol == -1) ++ if (AFR_COUNT (intersection, priv->child_count) <= 0) { ++ /* TODO: If we have one brick with valid data_readable and ++ * another with metadata_readable, try to send an iatt with ++ * valid bits from both.*/ + return -1; ++ } + +- return data_subvol; ++ memcpy (readable, intersection, sizeof (*readable) * priv->child_count); ++ ++ return afr_read_subvol_select_by_policy (inode, this, intersection, ++ args); + } + + static inline int +@@ -2216,7 +2237,49 @@ afr_first_up_child (call_frame_t *frame, xlator_t *this) + if (local->replies[i].valid && + local->replies[i].op_ret == 0) + return i; +- return 0; ++ return -1; ++} ++ ++static void ++afr_attempt_readsubvol_set (call_frame_t *frame, xlator_t *this, ++ unsigned char *success_replies, ++ unsigned char *data_readable, int *read_subvol) ++{ ++ afr_private_t *priv = NULL; ++ afr_local_t *local = NULL; ++ int spb_choice = -1; ++ int child_count = -1; ++ ++ if (*read_subvol != -1) ++ return; ++ ++ priv = this->private; ++ local = frame->local; ++ child_count = priv->child_count; ++ ++ afr_inode_split_brain_choice_get (local->inode, this, ++ &spb_choice); ++ if ((spb_choice >= 0) && ++ (AFR_COUNT(success_replies, child_count) == child_count)) { ++ *read_subvol = spb_choice; ++ } else if (!priv->quorum_count) { ++ *read_subvol = afr_first_up_child (frame, this); ++ } else if (priv->quorum_count && ++ afr_has_quorum (data_readable, this)) { ++ /* read_subvol is guaranteed to be valid if we hit this path. */ ++ *read_subvol = afr_first_up_child (frame, this); ++ } else { ++ /* If quorum is enabled and we do not have a ++ readable yet, it means all good copies are down. ++ */ ++ local->op_ret = -1; ++ local->op_errno = ENOTCONN; ++ gf_msg (this->name, GF_LOG_WARNING, 0, ++ AFR_MSG_READ_SUBVOL_ERROR, "no read " ++ "subvols for %s", local->loc.path); ++ } ++ if (*read_subvol >= 0) ++ dict_del (local->replies[*read_subvol].xdata, GF_CONTENT_KEY); + } + + static void +@@ -2230,13 +2293,13 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this) + int par_read_subvol = 0; + int ret = -1; + unsigned char *readable = NULL; ++ unsigned char *success_replies = NULL; + int event = 0; + struct afr_reply *replies = NULL; + uuid_t read_gfid = {0, }; + gf_boolean_t locked_entry = _gf_false; + gf_boolean_t can_interpret = _gf_true; + inode_t *parent = NULL; +- int spb_choice = -1; + ia_type_t ia_type = IA_INVAL; + afr_read_subvol_args_t args = {0,}; + char *gfid_heal_msg = NULL; +@@ -2250,11 +2313,12 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this) + this); + + readable = alloca0 (priv->child_count); ++ success_replies = alloca0 (priv->child_count); + + afr_inode_read_subvol_get (parent, this, readable, NULL, &event); ++ par_read_subvol = afr_get_parent_read_subvol (this, parent, replies, ++ readable); + +- afr_inode_split_brain_choice_get (local->inode, this, +- &spb_choice); + /* First, check if we have a gfid-change from somewhere, + If so, propagate that so that a fresh lookup can be + issued +@@ -2262,13 +2326,17 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this) + if (local->cont.lookup.needs_fresh_lookup) { + local->op_ret = -1; + local->op_errno = ESTALE; +- goto unwind; ++ goto error; + } + + op_errno = afr_final_errno (frame->local, this->private); + local->op_errno = op_errno; + + read_subvol = -1; ++ for (i = 0; i < priv->child_count; i++) ++ if (replies[i].valid && replies[i].op_ret == 0) ++ success_replies[i] = 1; ++ + for (i = 0; i < priv->child_count; i++) { + if (!replies[i].valid) + continue; +@@ -2277,9 +2345,9 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this) + replies[i].op_errno == ENOENT) { + /* Second, check entry is still + "underway" in creation */ +- local->op_ret = -1; +- local->op_errno = ENOENT; +- goto unwind; ++ local->op_ret = -1; ++ local->op_errno = ENOENT; ++ goto error; + } + + if (replies[i].op_ret == -1) +@@ -2293,8 +2361,8 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this) + } + } + +- if (read_subvol == -1) +- goto unwind; ++ if (read_subvol == -1) ++ goto error; + /* We now have a read_subvol, which is readable[] (if there + were any). Next we look for GFID mismatches. We don't + consider a GFID mismatch as an error if read_subvol is +@@ -2318,58 +2386,61 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this) + if (readable[read_subvol] && !readable[i]) + continue; + ++ /* If we were called from glfsheal and there is still a gfid ++ * mismatch, succeed the lookup and let glfsheal print the ++ * response via gfid-heal-msg.*/ ++ if (!dict_get_str (local->xattr_req, "gfid-heal-msg", ++ &gfid_heal_msg)) ++ goto cant_interpret; ++ + /* LOG ERROR */ + local->op_ret = -1; + local->op_errno = EIO; +- goto unwind; ++ goto error; + } + + /* Forth, for the finalized GFID, pick the best subvolume + to return stats from. + */ ++ read_subvol = -1; ++ memset (readable, 0, sizeof (*readable) * priv->child_count); + if (can_interpret) { ++ if (!afr_has_quorum (success_replies, this)) ++ goto cant_interpret; + /* It is safe to call afr_replies_interpret() because we have + a response from all the UP subvolumes and all of them resolved + to the same GFID + */ + gf_uuid_copy (args.gfid, read_gfid); + args.ia_type = ia_type; +- if (afr_replies_interpret (frame, this, local->inode, NULL)) { +- read_subvol = afr_read_subvol_decide (local->inode, +- this, &args); ++ ret = afr_replies_interpret (frame, this, local->inode, NULL); ++ read_subvol = afr_read_subvol_decide (local->inode, this, &args, ++ readable); ++ if (read_subvol == -1) ++ goto cant_interpret; ++ if (ret) { + afr_inode_event_gen_reset (local->inode, this); +- goto cant_interpret; +- } else { +- read_subvol = afr_data_subvol_get (local->inode, this, +- NULL, NULL, NULL, &args); +- } ++ dict_del (local->replies[read_subvol].xdata, ++ GF_CONTENT_KEY); ++ } + } else { + cant_interpret: ++ afr_attempt_readsubvol_set (frame, this, success_replies, ++ readable, &read_subvol); + if (read_subvol == -1) { +- if (spb_choice >= 0) +- read_subvol = spb_choice; +- else +- read_subvol = afr_first_up_child (frame, this); ++ goto error; + } +- dict_del (replies[read_subvol].xdata, GF_CONTENT_KEY); + } + + afr_handle_quota_size (frame, this); + +-unwind: + afr_set_need_heal (this, local); +- if (read_subvol == -1) { +- if (spb_choice >= 0) +- read_subvol = spb_choice; +- else +- read_subvol = afr_first_up_child (frame, this); +- +- } +- par_read_subvol = afr_get_parent_read_subvol (this, parent, replies, +- readable); + if (AFR_IS_ARBITER_BRICK (priv, read_subvol) && local->op_ret == 0) { +- local->op_ret = -1; +- local->op_errno = ENOTCONN; ++ local->op_ret = -1; ++ local->op_errno = ENOTCONN; ++ gf_msg_debug(this->name, 0, "Arbiter cannot be a read subvol " ++ "for %s", local->loc.path); ++ goto error; + } + + ret = dict_get_str (local->xattr_req, "gfid-heal-msg", &gfid_heal_msg); +@@ -2389,6 +2460,11 @@ unwind: + local->inode, &local->replies[read_subvol].poststat, + local->replies[read_subvol].xdata, + &local->replies[par_read_subvol].postparent); ++ return; ++ ++error: ++ AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, NULL, ++ NULL, NULL, NULL); + } + + /* +@@ -2904,55 +2980,54 @@ afr_discover_done (call_frame_t *frame, xlator_t *this) + afr_local_t *local = NULL; + int i = -1; + int op_errno = 0; +- int spb_choice = -1; + int read_subvol = -1; ++ unsigned char *data_readable = NULL; ++ unsigned char *success_replies = NULL; + + priv = this->private; + local = frame->local; +- +- afr_inode_split_brain_choice_get (local->inode, this, +- &spb_choice); ++ data_readable = alloca0 (priv->child_count); ++ success_replies = alloca0 (priv->child_count); + + for (i = 0; i < priv->child_count; i++) { + if (!local->replies[i].valid) + continue; +- if (local->replies[i].op_ret == 0) ++ if (local->replies[i].op_ret == 0) { ++ success_replies[i] = 1; + local->op_ret = 0; ++ } + } + + op_errno = afr_final_errno (frame->local, this->private); + + if (local->op_ret < 0) { +- local->op_errno = op_errno; +- local->op_ret = -1; +- goto unwind; ++ AFR_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, ++ NULL, NULL); ++ return; + } + +- afr_replies_interpret (frame, this, local->inode, NULL); ++ if (!afr_has_quorum (success_replies, this)) ++ goto unwind; + +- read_subvol = afr_read_subvol_decide (local->inode, this, NULL); +- if (read_subvol == -1) { +- gf_msg (this->name, GF_LOG_WARNING, 0, +- AFR_MSG_READ_SUBVOL_ERROR, "no read subvols for %s", +- local->loc.path); ++ afr_replies_interpret (frame, this, local->inode, NULL); + +- if (spb_choice >= 0) { +- read_subvol = spb_choice; +- } else { +- read_subvol = afr_first_up_child (frame, this); +- } +- } ++ read_subvol = afr_read_subvol_decide (local->inode, this, NULL, ++ data_readable); + + unwind: ++ afr_attempt_readsubvol_set (frame, this, success_replies, data_readable, ++ &read_subvol); + if (read_subvol == -1) { +- if (spb_choice >= 0) +- read_subvol = spb_choice; +- else +- read_subvol = afr_first_up_child (frame, this); ++ AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, ++ NULL, NULL, NULL, NULL); ++ return; + } ++ + if (AFR_IS_ARBITER_BRICK (priv, read_subvol) && local->op_ret == 0) { +- local->op_ret = -1; +- local->op_errno = ENOTCONN; ++ local->op_ret = -1; ++ local->op_errno = ENOTCONN; ++ gf_msg_debug (this->name, 0, "Arbiter cannot be a read subvol " ++ "for %s", local->loc.path); + } + + AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, +@@ -4646,7 +4721,6 @@ afr_priv_dump (xlator_t *this) + gf_proc_dump_write("read_child", "%d", priv->read_child); + gf_proc_dump_write("favorite_child", "%d", priv->favorite_child); + gf_proc_dump_write("wait_count", "%u", priv->wait_count); +- gf_proc_dump_write("quorum-reads", "%d", priv->quorum_reads); + gf_proc_dump_write("heal-wait-queue-length", "%d", + priv->heal_wait_qlen); + gf_proc_dump_write("heal-waiters", "%d", priv->heal_waiters); +diff --git a/xlators/cluster/afr/src/afr-read-txn.c b/xlators/cluster/afr/src/afr-read-txn.c +index 50e8040..f6c491b 100644 +--- a/xlators/cluster/afr/src/afr-read-txn.c ++++ b/xlators/cluster/afr/src/afr-read-txn.c +@@ -193,8 +193,7 @@ afr_read_txn (call_frame_t *frame, xlator_t *this, inode_t *inode, + local->inode = inode_ref (inode); + local->is_read_txn = _gf_true; + +- if (priv->quorum_reads && +- priv->quorum_count && !afr_has_quorum (priv->child_up, this)) { ++ if (priv->quorum_count && !afr_has_quorum (local->child_up, this)) { + local->op_ret = -1; + local->op_errno = ENOTCONN; + read_subvol = -1; +diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c +index 0122b7f..1b738c0 100644 +--- a/xlators/cluster/afr/src/afr.c ++++ b/xlators/cluster/afr/src/afr.c +@@ -267,8 +267,6 @@ reconfigure (xlator_t *this, dict_t *options) + GF_OPTION_RECONF ("heal-timeout", priv->shd.timeout, options, + int32, out); + +- GF_OPTION_RECONF ("quorum-reads", priv->quorum_reads, options, +- bool, out); + GF_OPTION_RECONF ("consistent-metadata", priv->consistent_metadata, + options, bool, out); + +@@ -531,7 +529,6 @@ init (xlator_t *this) + GF_OPTION_INIT ("iam-self-heal-daemon", priv->shd.iamshd, bool, out); + GF_OPTION_INIT ("heal-timeout", priv->shd.timeout, int32, out); + +- GF_OPTION_INIT ("quorum-reads", priv->quorum_reads, bool, out); + GF_OPTION_INIT ("consistent-metadata", priv->consistent_metadata, bool, + out); + GF_OPTION_INIT ("consistent-io", priv->consistent_io, bool, out); +@@ -965,8 +962,8 @@ struct volume_options options[] = { + { .key = {"quorum-reads"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "no", +- .description = "If quorum-reads is \"true\" only allow reads if " +- "quorum is met when quorum is enabled.", ++ .description = "This option has been removed. Reads are not allowed " ++ "if quorum is not met.", + }, + { .key = {"node-uuid"}, + .type = GF_OPTION_TYPE_STR, +diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h +index af9dbc8..7010e9b 100644 +--- a/xlators/cluster/afr/src/afr.h ++++ b/xlators/cluster/afr/src/afr.h +@@ -131,7 +131,6 @@ typedef struct _afr_private { + gf_boolean_t pre_op_compat; /* on/off */ + uint32_t post_op_delay_secs; + unsigned int quorum_count; +- gf_boolean_t quorum_reads; + + char vol_uuid[UUID_SIZE + 1]; + int32_t *last_event; +-- +1.8.3.1 + diff --git a/0477-glusterd-perform-rcu_read_lock-unlock-under-cleanup_.patch b/0477-glusterd-perform-rcu_read_lock-unlock-under-cleanup_.patch new file mode 100644 index 0000000..a8c39ec --- /dev/null +++ b/0477-glusterd-perform-rcu_read_lock-unlock-under-cleanup_.patch @@ -0,0 +1,1808 @@ +From c0d88596bda4eb5c7e942e621a7d38c7ae6d737a Mon Sep 17 00:00:00 2001 +From: Sanju Rakonde +Date: Wed, 28 Nov 2018 16:13:58 +0530 +Subject: [PATCH 477/493] glusterd: perform rcu_read_lock/unlock() under + cleanup_lock mutex + +Problem: glusterd should not try to acquire locks on any resources, +when it already received a SIGTERM and cleanup is started. Otherwise +we might hit segfault, since the thread which is going through +cleanup path will be freeing up the resouces and some other thread +might be trying to acquire locks on freed resources. + +Solution: perform rcu_read_lock/unlock() under cleanup_lock mutex. + +> fixes: bz#1654270 +> Change-Id: I87a97cfe4f272f74f246d688660934638911ce54 +> Signed-off-by: Sanju Rakonde + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/21743/ + +Change-Id: I87a97cfe4f272f74f246d688660934638911ce54 +BUG: 1654161 +Signed-off-by: Sanju Rakonde +Reviewed-on: https://code.engineering.redhat.com/gerrit/158647 +Tested-by: RHGS Build Bot +Reviewed-by: Atin Mukherjee +--- + xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 8 +-- + xlators/mgmt/glusterd/src/glusterd-handler.c | 75 +++++++++++----------- + xlators/mgmt/glusterd/src/glusterd-handshake.c | 32 ++++----- + xlators/mgmt/glusterd/src/glusterd-mgmt.c | 28 ++++---- + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 30 ++++----- + xlators/mgmt/glusterd/src/glusterd-peer-utils.c | 40 ++++++------ + xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 4 +- + xlators/mgmt/glusterd/src/glusterd-reset-brick.c | 4 +- + xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 48 +++++++------- + xlators/mgmt/glusterd/src/glusterd-server-quorum.c | 4 +- + xlators/mgmt/glusterd/src/glusterd-sm.c | 64 +++++++++--------- + xlators/mgmt/glusterd/src/glusterd-snapshot.c | 6 +- + xlators/mgmt/glusterd/src/glusterd-store.c | 4 +- + xlators/mgmt/glusterd/src/glusterd-syncop.c | 40 ++++++------ + xlators/mgmt/glusterd/src/glusterd-utils.c | 8 +-- + xlators/mgmt/glusterd/src/glusterd.h | 20 +++++- + 16 files changed, 215 insertions(+), 200 deletions(-) + +diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +index 416412e..5ad8ab8 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c ++++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +@@ -2097,7 +2097,7 @@ check: + continue; + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find_by_uuid + (brickinfo->uuid); + if (!peerinfo) { +@@ -2105,7 +2105,7 @@ check: + "brick %s is not in cluster", brick); + *errstr = gf_strdup (msg); + ret = -1; +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + goto out; + } + if (!peerinfo->connected) { +@@ -2113,10 +2113,10 @@ check: + "brick %s is down", brick); + *errstr = gf_strdup (msg); + ret = -1; +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + goto out; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + } + + out: +diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c +index c71bf3c..d40de89 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-handler.c ++++ b/xlators/mgmt/glusterd/src/glusterd-handler.c +@@ -105,7 +105,7 @@ glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid, + + ret = glusterd_remote_hostname_get (req, rhost, sizeof (rhost)); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (uuid, rhost); + +@@ -179,7 +179,7 @@ glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid, + ret = GLUSTERD_CONNECTION_AWAITED; + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (ret && (ret != GLUSTERD_CONNECTION_AWAITED)) { + if (ctx && ctx->hostname) +@@ -198,7 +198,6 @@ out: + GF_FREE (event); + } + +- + return ret; + } + +@@ -214,7 +213,7 @@ glusterd_handle_unfriend_req (rpcsvc_request_t *req, uuid_t uuid, + if (!port) + port = GF_DEFAULT_BASE_PORT; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (uuid, hostname); + +@@ -269,7 +268,7 @@ glusterd_handle_unfriend_req (rpcsvc_request_t *req, uuid_t uuid, + ret = 0; + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (0 != ret) { + if (ctx && ctx->hostname) +@@ -902,9 +901,9 @@ __glusterd_handle_cluster_lock (rpcsvc_request_t *req) + gf_msg_debug (this->name, 0, "Received LOCK from uuid: %s", + uuid_utoa (lock_req.uuid)); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find_by_uuid (lock_req.uuid) == NULL); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) { + gf_msg (this->name, GF_LOG_WARNING, 0, + GD_MSG_PEER_NOT_FOUND, "%s doesn't " +@@ -1060,9 +1059,9 @@ __glusterd_handle_stage_op (rpcsvc_request_t *req) + gf_msg_debug (this->name, 0, "transaction ID = %s", + uuid_utoa (*txn_id)); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) { + gf_msg (this->name, GF_LOG_WARNING, 0, + GD_MSG_PEER_NOT_FOUND, "%s doesn't " +@@ -1144,9 +1143,9 @@ __glusterd_handle_commit_op (rpcsvc_request_t *req) + goto out; + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find_by_uuid (op_req.uuid) == NULL); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) { + gf_msg (this->name, GF_LOG_WARNING, 0, + GD_MSG_PEER_NOT_FOUND, "%s doesn't " +@@ -1270,12 +1269,12 @@ __glusterd_handle_cli_probe (rpcsvc_request_t *req) + goto out; + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find_by_hostname (hostname); + ret = (peerinfo && gd_peer_has_address (peerinfo, hostname)); + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (ret) { + gf_msg_debug ("glusterd", 0, "Probe host %s port %d " +@@ -2329,7 +2328,7 @@ __glusterd_handle_fsm_log (rpcsvc_request_t *req) + conf = this->private; + ret = glusterd_sm_tr_log_add_to_dict (dict, &conf->op_sm_log); + } else { +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find_by_hostname (cli_req.name); + if (!peerinfo) { +@@ -2341,7 +2340,7 @@ __glusterd_handle_fsm_log (rpcsvc_request_t *req) + (dict, &peerinfo->sm_log); + } + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + } + + out: +@@ -2482,9 +2481,9 @@ __glusterd_handle_cluster_unlock (rpcsvc_request_t *req) + gf_msg_debug (this->name, 0, + "Received UNLOCK from uuid: %s", uuid_utoa (unlock_req.uuid)); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find_by_uuid (unlock_req.uuid) == NULL); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) { + gf_msg (this->name, GF_LOG_WARNING, 0, + GD_MSG_PEER_NOT_FOUND, "%s doesn't " +@@ -2786,11 +2785,11 @@ __glusterd_handle_friend_update (rpcsvc_request_t *req) + } + + ret = 0; +- rcu_read_lock (); ++ RCU_READ_LOCK; + if (glusterd_peerinfo_find (friend_req.uuid, NULL) == NULL) { + ret = -1; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) { + gf_msg (this->name, GF_LOG_CRITICAL, 0, + GD_MSG_REQ_FROM_UNKNOWN_PEER, +@@ -2856,7 +2855,7 @@ __glusterd_handle_friend_update (rpcsvc_request_t *req) + memset (key, 0, sizeof (key)); + snprintf (key, sizeof (key), "friend%d", i); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (uuid, NULL); + if (peerinfo == NULL) { + /* Create a new peer and add it to the list as there is +@@ -2903,7 +2902,7 @@ __glusterd_handle_friend_update (rpcsvc_request_t *req) + } + } + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) + break; + +@@ -3002,7 +3001,7 @@ __glusterd_handle_probe_query (rpcsvc_request_t *req) + goto out; + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (probe_req.uuid, remote_hostname); + if ((peerinfo == NULL) && (!cds_list_empty (&conf->peers))) { + rsp.op_ret = -1; +@@ -3024,7 +3023,7 @@ __glusterd_handle_probe_query (rpcsvc_request_t *req) + rsp.op_errno = GF_PROBE_ADD_FAILED; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + respond: + gf_uuid_copy (rsp.uuid, MY_UUID); +@@ -3370,11 +3369,11 @@ glusterd_friend_remove (uuid_t uuid, char *hostname) + int ret = -1; + glusterd_peerinfo_t *peerinfo = NULL; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (uuid, hostname); + if (peerinfo == NULL) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + goto out; + } + +@@ -3382,7 +3381,7 @@ glusterd_friend_remove (uuid_t uuid, char *hostname) + if (ret) + gf_msg (THIS->name, GF_LOG_WARNING, 0, + GD_MSG_VOL_CLEANUP_FAIL, "Volumes cleanup failed"); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + /* Giving up the critical section here as glusterd_peerinfo_cleanup must + * be called from outside a critical section + */ +@@ -3715,7 +3714,7 @@ glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port, + + GF_ASSERT (hoststr); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (NULL, hoststr); + + if (peerinfo == NULL) { +@@ -3763,7 +3762,7 @@ glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port, + } + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + gf_msg_debug ("glusterd", 0, "returning %d", ret); + return ret; + } +@@ -3780,7 +3779,7 @@ glusterd_deprobe_begin (rpcsvc_request_t *req, const char *hoststr, int port, + GF_ASSERT (hoststr); + GF_ASSERT (req); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (uuid, hoststr); + if (peerinfo == NULL) { +@@ -3840,7 +3839,7 @@ glusterd_deprobe_begin (rpcsvc_request_t *req, const char *hoststr, int port, + peerinfo->detaching = _gf_true; + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + return ret; + } + +@@ -4162,7 +4161,7 @@ glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags) + + /* Reset ret to 0, needed to prevent failure incase no peers exist */ + ret = 0; +- rcu_read_lock (); ++ RCU_READ_LOCK; + if (!cds_list_empty (&priv->peers)) { + cds_list_for_each_entry_rcu (entry, &priv->peers, uuid_list) { + count++; +@@ -4173,7 +4172,7 @@ glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags) + } + } + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) + goto out; + +@@ -5592,7 +5591,7 @@ glusterd_get_state (rpcsvc_request_t *req, dict_t *dict) + if (priv->opts) + dict_foreach (priv->opts, glusterd_print_global_options, fp); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + fprintf (fp, "\n[Peers]\n"); + + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { +@@ -5621,7 +5620,7 @@ glusterd_get_state (rpcsvc_request_t *req, dict_t *dict) + count_bkp = 0; + fprintf (fp, "\n"); + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + count = 0; + fprintf (fp, "\n[Volumes]\n"); +@@ -6259,7 +6258,7 @@ glusterd_friend_remove_notify (glusterd_peerctx_t *peerctx, int32_t op_errno) + + GF_ASSERT (peerctx); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find_by_generation (peerctx->peerinfo_gen); + if (!peerinfo) { + gf_msg_debug (THIS->name, 0, "Could not find peer %s(%s). " +@@ -6300,7 +6299,7 @@ glusterd_friend_remove_notify (glusterd_peerctx_t *peerctx, int32_t op_errno) + } + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + return ret; + } + +@@ -6340,7 +6339,7 @@ __glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata, + peerctx->peername); + return 0; + } +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find_by_generation (peerctx->peerinfo_gen); + if (!peerinfo) { +@@ -6466,7 +6465,7 @@ __glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata, + } + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + glusterd_friend_sm (); + glusterd_op_sm (); +diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c +index b2a9b20..d18a7a3 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c ++++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c +@@ -1140,9 +1140,9 @@ gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req, dict_t *dict) + */ + if (!ret) { + gf_uuid_parse (uuid_str, peer_uuid); +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find (peer_uuid, NULL) != NULL); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) + return _gf_true; + } +@@ -1158,7 +1158,7 @@ gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req, dict_t *dict) + * is available in the peerinfo list but the uuid has changed of the + * node due to a reinstall, in that case the validation should fail! + */ +- rcu_read_lock (); ++ RCU_READ_LOCK; + if (!uuid_str) { + ret = (glusterd_peerinfo_find (NULL, hostname) == NULL); + } else { +@@ -1177,7 +1177,7 @@ gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req, dict_t *dict) + ret = -1; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_HANDSHAKE_REQ_REJECTED, "Rejecting management " +@@ -1728,7 +1728,7 @@ glusterd_event_connected_inject (glusterd_peerctx_t *peerctx) + goto out; + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find_by_generation (peerctx->peerinfo_gen); + if (!peerinfo) { +@@ -1754,7 +1754,7 @@ glusterd_event_connected_inject (glusterd_peerctx_t *peerctx) + GD_MSG_EVENT_INJECT_FAIL, "Unable to inject " + "EVENT_CONNECTED ret = %d", ret); + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + out: + gf_msg_debug ("glusterd", 0, "returning %d", ret); +@@ -1824,7 +1824,7 @@ __glusterd_mgmt_hndsk_version_ack_cbk (struct rpc_req *req, struct iovec *iov, + frame = myframe; + peerctx = frame->local; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find_by_generation (peerctx->peerinfo_gen); + if (!peerinfo) { + gf_msg_debug (this->name, 0, "Could not find peer %s(%s)", +@@ -1887,7 +1887,7 @@ out: + if (ret != 0 && peerinfo) + rpc_transport_disconnect (peerinfo->rpc->conn.trans, _gf_false); + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + frame->local = NULL; + STACK_DESTROY (frame->root); +@@ -1930,7 +1930,7 @@ __glusterd_mgmt_hndsk_version_cbk (struct rpc_req *req, struct iovec *iov, + frame = myframe; + peerctx = frame->local; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find_by_generation (peerctx->peerinfo_gen); + if (!peerinfo) { +@@ -2014,7 +2014,7 @@ out: + _gf_false); + } + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (rsp.hndsk.hndsk_val) + free (rsp.hndsk.hndsk_val); +@@ -2070,7 +2070,7 @@ glusterd_mgmt_handshake (xlator_t *this, glusterd_peerctx_t *peerctx) + GF_PROTOCOL_DICT_SERIALIZE (this, req_dict, (&req.hndsk.hndsk_val), + req.hndsk.hndsk_len, ret, out); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find_by_generation (peerctx->peerinfo_gen); + if (!peerinfo) { +@@ -2086,7 +2086,7 @@ glusterd_mgmt_handshake (xlator_t *this, glusterd_peerctx_t *peerctx) + (xdrproc_t)xdr_gf_mgmt_hndsk_req); + ret = 0; + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + out: + if (ret && frame) + STACK_DESTROY (frame->root); +@@ -2202,7 +2202,7 @@ __glusterd_peer_dump_version_cbk (struct rpc_req *req, struct iovec *iov, + frame = myframe; + peerctx = frame->local; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find_by_generation (peerctx->peerinfo_gen); + if (!peerinfo) { +@@ -2282,7 +2282,7 @@ out: + if (ret != 0 && peerinfo) + rpc_transport_disconnect (peerinfo->rpc->conn.trans, _gf_false); + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + glusterd_friend_sm (); + glusterd_op_sm (); +@@ -2330,7 +2330,7 @@ glusterd_peer_dump_version (xlator_t *this, struct rpc_clnt *rpc, + if (!peerctx) + goto out; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find_by_generation (peerctx->peerinfo_gen); + if (!peerinfo) { +@@ -2347,7 +2347,7 @@ glusterd_peer_dump_version (xlator_t *this, struct rpc_clnt *rpc, + glusterd_peer_dump_version_cbk, + (xdrproc_t)xdr_gf_dump_req); + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + out: + if (ret && frame) + STACK_DESTROY (frame->root); +diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c +index 751d6e4..d98c6bc 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c ++++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c +@@ -52,14 +52,14 @@ gd_mgmt_v3_collate_errors (struct syncargs *args, int op_ret, int op_errno, + args->op_ret = op_ret; + args->op_errno = op_errno; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (peerid, NULL); + if (peerinfo) + peer_str = gf_strdup (peerinfo->hostname); + else + peer_str = gf_strdup (uuid_utoa (uuid)); + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + is_operrstr_blk = (op_errstr && strcmp (op_errstr, "")); + err_string = (is_operrstr_blk) ? op_errstr : err_str; +@@ -761,7 +761,7 @@ glusterd_mgmt_v3_initiate_lockdown (glusterd_op_t op, dict_t *dict, + synctask_barrier_init((&args)); + peer_cnt = 0; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -779,7 +779,7 @@ glusterd_mgmt_v3_initiate_lockdown (glusterd_op_t op, dict_t *dict, + MY_UUID, peer_uuid); + peer_cnt++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (0 == peer_cnt) { + ret = 0; +@@ -1126,7 +1126,7 @@ glusterd_mgmt_v3_pre_validate (glusterd_op_t op, dict_t *req_dict, + synctask_barrier_init((&args)); + peer_cnt = 0; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -1144,7 +1144,7 @@ glusterd_mgmt_v3_pre_validate (glusterd_op_t op, dict_t *req_dict, + MY_UUID, peer_uuid); + peer_cnt++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (0 == peer_cnt) { + ret = 0; +@@ -1401,7 +1401,7 @@ glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *rsp_dict, dict_t *req_dict, + synctask_barrier_init((&args)); + peer_cnt = 0; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -1419,7 +1419,7 @@ glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *rsp_dict, dict_t *req_dict, + MY_UUID, peer_uuid); + peer_cnt++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (0 == peer_cnt) { + ret = 0; +@@ -1667,7 +1667,7 @@ glusterd_mgmt_v3_commit (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict, + synctask_barrier_init((&args)); + peer_cnt = 0; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -1702,7 +1702,7 @@ glusterd_mgmt_v3_commit (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict, + MY_UUID, peer_uuid); + peer_cnt++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (0 == peer_cnt) { + ret = 0; +@@ -1912,7 +1912,7 @@ glusterd_mgmt_v3_post_validate (glusterd_op_t op, int32_t op_ret, dict_t *dict, + synctask_barrier_init((&args)); + peer_cnt = 0; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -1930,7 +1930,7 @@ glusterd_mgmt_v3_post_validate (glusterd_op_t op, int32_t op_ret, dict_t *dict, + &args, MY_UUID, peer_uuid); + peer_cnt++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (0 == peer_cnt) { + ret = 0; +@@ -2094,7 +2094,7 @@ glusterd_mgmt_v3_release_peer_locks (glusterd_op_t op, dict_t *dict, + synctask_barrier_init((&args)); + peer_cnt = 0; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -2112,7 +2112,7 @@ glusterd_mgmt_v3_release_peer_locks (glusterd_op_t op, dict_t *dict, + MY_UUID, peer_uuid); + peer_cnt++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (0 == peer_cnt) { + ret = 0; +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +index 9f76ab3..6414a4e 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c +@@ -1825,7 +1825,7 @@ glusterd_op_stage_sync_volume (dict_t *dict, char **op_errstr) + ret = 0; + } + } else { +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (NULL, hostname); + if (peerinfo == NULL) { +@@ -1841,7 +1841,7 @@ glusterd_op_stage_sync_volume (dict_t *dict, char **op_errstr) + ret = -1; + } + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + } + + out: +@@ -3964,7 +3964,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) + priv = this->private; + GF_ASSERT (priv); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -3985,7 +3985,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) + if (proc->fn) { + ret = proc->fn (NULL, this, peerinfo); + if (ret) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + gf_msg (this->name, GF_LOG_WARNING, 0, + GD_MSG_LOCK_REQ_SEND_FAIL, + "Failed to send lock request " +@@ -4009,7 +4009,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) + ret = dict_set_static_ptr (dict, "peerinfo", + peerinfo); + if (ret) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_DICT_SET_FAILED, + "failed to set peerinfo"); +@@ -4019,7 +4019,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) + + ret = proc->fn (NULL, this, dict); + if (ret) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + gf_msg (this->name, GF_LOG_WARNING, 0, + GD_MSG_MGMTV3_LOCK_REQ_SEND_FAIL, + "Failed to send mgmt_v3 lock " +@@ -4036,7 +4036,7 @@ glusterd_op_ac_send_lock (glusterd_op_sm_event_t *event, void *ctx) + } + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + opinfo.pending_count = pending_count; + +@@ -4074,7 +4074,7 @@ glusterd_op_ac_send_unlock (glusterd_op_sm_event_t *event, void *ctx) + priv = this->private; + GF_ASSERT (priv); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -4152,7 +4152,7 @@ glusterd_op_ac_send_unlock (glusterd_op_sm_event_t *event, void *ctx) + } + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + opinfo.pending_count = pending_count; + +@@ -4762,7 +4762,7 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) + goto out; + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -4781,7 +4781,7 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) + if (proc->fn) { + ret = dict_set_static_ptr (dict, "peerinfo", peerinfo); + if (ret) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_DICT_SET_FAILED, "failed to " + "set peerinfo"); +@@ -4800,7 +4800,7 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx) + pending_count++; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + opinfo.pending_count = pending_count; + out: +@@ -5413,7 +5413,7 @@ glusterd_op_ac_send_commit_op (glusterd_op_sm_event_t *event, void *ctx) + goto out; + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -5432,7 +5432,7 @@ glusterd_op_ac_send_commit_op (glusterd_op_sm_event_t *event, void *ctx) + if (proc->fn) { + ret = dict_set_static_ptr (dict, "peerinfo", peerinfo); + if (ret) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_DICT_SET_FAILED, + "failed to set peerinfo"); +@@ -5451,7 +5451,7 @@ glusterd_op_ac_send_commit_op (glusterd_op_sm_event_t *event, void *ctx) + pending_count++; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + opinfo.pending_count = pending_count; + gf_msg_debug (this->name, 0, "Sent commit op req for 'Volume %s' " +diff --git a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c +index 592aa16..6ed5831 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-peer-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-peer-utils.c +@@ -190,7 +190,7 @@ glusterd_peerinfo_find_by_uuid (uuid_t uuid) + if (gf_uuid_is_null (uuid)) + return NULL; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (entry, &priv->peers, uuid_list) { + if (!gf_uuid_compare (entry->uuid, uuid)) { + +@@ -201,7 +201,7 @@ glusterd_peerinfo_find_by_uuid (uuid_t uuid) + break; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (!found) + gf_msg_debug (this->name, 0, +@@ -330,7 +330,7 @@ glusterd_chk_peers_connected_befriended (uuid_t skip_uuid) + priv= THIS->private; + GF_ASSERT (priv); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + + if (!gf_uuid_is_null (skip_uuid) && !gf_uuid_compare (skip_uuid, +@@ -343,7 +343,7 @@ glusterd_chk_peers_connected_befriended (uuid_t skip_uuid) + break; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + gf_msg_debug (THIS->name, 0, "Returning %s", + (ret?"TRUE":"FALSE")); +@@ -366,7 +366,7 @@ glusterd_uuid_to_hostname (uuid_t uuid) + if (!gf_uuid_compare (MY_UUID, uuid)) { + hostname = gf_strdup ("localhost"); + } +- rcu_read_lock (); ++ RCU_READ_LOCK; + if (!cds_list_empty (&priv->peers)) { + cds_list_for_each_entry_rcu (entry, &priv->peers, uuid_list) { + if (!gf_uuid_compare (entry->uuid, uuid)) { +@@ -375,7 +375,7 @@ glusterd_uuid_to_hostname (uuid_t uuid) + } + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + return hostname; + } +@@ -406,14 +406,14 @@ glusterd_are_all_peers_up () + conf = this->private; + GF_VALIDATE_OR_GOTO (this->name, conf, out); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + if (!peerinfo->connected) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + goto out; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + peers_up = _gf_true; + +@@ -434,7 +434,7 @@ glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo, + if (!gf_uuid_compare (brickinfo->uuid, MY_UUID)) + continue; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, peers, uuid_list) { + if (gf_uuid_compare (peerinfo->uuid, brickinfo->uuid)) + continue; +@@ -447,11 +447,11 @@ glusterd_are_vol_all_peers_up (glusterd_volinfo_t *volinfo, + *down_peerstr = gf_strdup (peerinfo->hostname); + gf_msg_debug (THIS->name, 0, "Peer %s is down. ", + peerinfo->hostname); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + goto out; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + } + + ret = _gf_true; +@@ -664,7 +664,7 @@ gd_peerinfo_find_from_hostname (const char *hoststr) + + GF_VALIDATE_OR_GOTO (this->name, (hoststr != NULL), out); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peer, &priv->peers, uuid_list) { + cds_list_for_each_entry_rcu (tmphost, &peer->hostnames, + hostname_list) { +@@ -679,7 +679,7 @@ gd_peerinfo_find_from_hostname (const char *hoststr) + } + } + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + out: + return found; + } +@@ -713,7 +713,7 @@ gd_peerinfo_find_from_addrinfo (const struct addrinfo *addr) + + GF_VALIDATE_OR_GOTO (this->name, (addr != NULL), out); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peer, &conf->peers, uuid_list) { + cds_list_for_each_entry_rcu (address, &peer->hostnames, + hostname_list) { +@@ -747,7 +747,7 @@ gd_peerinfo_find_from_addrinfo (const struct addrinfo *addr) + } + } + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + out: + return found; + } +@@ -1014,7 +1014,7 @@ glusterd_peerinfo_find_by_generation (uint32_t generation) { + + GF_ASSERT (priv); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (entry, &priv->peers, uuid_list) { + if (entry->generation == generation) { + +@@ -1025,7 +1025,7 @@ glusterd_peerinfo_find_by_generation (uint32_t generation) { + break; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (!found) + gf_msg_debug (this->name, 0, +@@ -1047,10 +1047,10 @@ glusterd_get_peers_count () { + conf = this->private; + GF_VALIDATE_OR_GOTO (this->name, conf, out); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peer, &conf->peers, uuid_list) + count++; +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + out: + return count; +diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c +index 5fc3669..f9ad524 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c ++++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c +@@ -278,7 +278,7 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, + } + + if (!gf_is_local_addr (host)) { +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (NULL, host); + if (peerinfo == NULL) { +@@ -300,7 +300,7 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr, + *op_errstr = gf_strdup (msg); + ret = -1; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (ret) + goto out; +diff --git a/xlators/mgmt/glusterd/src/glusterd-reset-brick.c b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c +index c1de043..60c5716 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-reset-brick.c ++++ b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c +@@ -165,7 +165,7 @@ glusterd_reset_brick_prevalidate (dict_t *dict, char **op_errstr, + if (ret) + goto out; + } else { +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (NULL, host); + if (peerinfo == NULL) { +@@ -190,7 +190,7 @@ glusterd_reset_brick_prevalidate (dict_t *dict, char **op_errstr, + *op_errstr = gf_strdup (msg); + ret = -1; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (ret) + goto out; +diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +index 86e1256..c669240 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c ++++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +@@ -280,7 +280,7 @@ __glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov, + goto out; + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (rsp.uuid, rsp.hostname); + if (peerinfo == NULL) { + ret = -1; +@@ -422,7 +422,7 @@ cont: + GD_MSG_PROBE_REQ_RESP_RCVD, "Received resp to probe req"); + + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + out: + free (rsp.hostname);//malloced by xdr +@@ -485,7 +485,7 @@ __glusterd_friend_add_cbk (struct rpc_req * req, struct iovec *iov, + "Received %s from uuid: %s, host: %s, port: %d", + (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid), rsp.hostname, rsp.port); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (rsp.uuid, rsp.hostname); + if (peerinfo == NULL) { +@@ -527,7 +527,7 @@ __glusterd_friend_add_cbk (struct rpc_req * req, struct iovec *iov, + ret = glusterd_friend_sm_inject_event (event); + + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + out: + ctx = ((call_frame_t *)myframe)->local; + ((call_frame_t *)myframe)->local = NULL; +@@ -605,7 +605,7 @@ __glusterd_friend_remove_cbk (struct rpc_req * req, struct iovec *iov, + (op_ret)?"RJT":"ACC", uuid_utoa (rsp.uuid), rsp.hostname, rsp.port); + + inject: +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (rsp.uuid, ctx->hostname); + if (peerinfo == NULL) { +@@ -640,7 +640,7 @@ inject: + op_ret = 0; + + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + respond: + ret = glusterd_xfer_cli_deprobe_resp (ctx->req, op_ret, op_errno, NULL, +@@ -769,9 +769,9 @@ __glusterd_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov, + uuid_utoa (rsp.uuid)); + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find (rsp.uuid, NULL) == NULL); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (ret) { + gf_msg (this->name, GF_LOG_CRITICAL, 0, +@@ -889,9 +889,9 @@ glusterd_mgmt_v3_lock_peers_cbk_fn (struct rpc_req *req, struct iovec *iov, + uuid_utoa (rsp.uuid)); + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find (rsp.uuid, NULL) == NULL); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (ret) { + gf_msg (this->name, GF_LOG_CRITICAL, 0, +@@ -1000,9 +1000,9 @@ glusterd_mgmt_v3_unlock_peers_cbk_fn (struct rpc_req *req, struct iovec *iov, + uuid_utoa (rsp.uuid)); + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find (rsp.uuid, NULL) == NULL); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (ret) { + gf_msg (this->name, GF_LOG_CRITICAL, 0, +@@ -1109,9 +1109,9 @@ __glusterd_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov, + uuid_utoa (rsp.uuid)); + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find (rsp.uuid, NULL) == NULL); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (ret) { + gf_msg (this->name, GF_LOG_CRITICAL, 0, +@@ -1239,7 +1239,7 @@ out: + uuid_utoa (rsp.uuid)); + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL); + if (peerinfo == NULL) { + gf_msg (this->name, GF_LOG_CRITICAL, 0, +@@ -1268,7 +1268,7 @@ out: + event_type = GD_OP_EVENT_RCVD_ACC; + } + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + + ret = glusterd_set_txn_opinfo (txn_id, &opinfo); +@@ -1399,7 +1399,7 @@ __glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov, + "for txn_id = %s", uuid_utoa (*txn_id)); + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (rsp.uuid, NULL); + if (peerinfo == NULL) { + gf_msg (this->name, GF_LOG_CRITICAL, 0, +@@ -1450,7 +1450,7 @@ __glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov, + } + } + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + out: + +@@ -1554,11 +1554,11 @@ glusterd_rpc_friend_add (call_frame_t *frame, xlator_t *this, + + GF_ASSERT (priv); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (event->peerid, event->peername); + if (!peerinfo) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + ret = -1; + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", +@@ -1570,7 +1570,7 @@ glusterd_rpc_friend_add (call_frame_t *frame, xlator_t *this, + req.hostname = gf_strdup (peerinfo->hostname); + req.port = peerinfo->port; + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + ret = glusterd_add_volumes_to_export_dict (&peer_data); + if (ret) { +@@ -1653,11 +1653,11 @@ glusterd_rpc_friend_remove (call_frame_t *frame, xlator_t *this, + + GF_ASSERT (priv); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (event->peerid, event->peername); + if (!peerinfo) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + ret = -1; + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", +@@ -1674,7 +1674,7 @@ glusterd_rpc_friend_remove (call_frame_t *frame, xlator_t *this, + this, glusterd_friend_remove_cbk, + (xdrproc_t)xdr_gd1_mgmt_friend_req); + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + out: + GF_FREE (req.hostname); + +diff --git a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c +index b01bfaa..ef97bfd 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-server-quorum.c ++++ b/xlators/mgmt/glusterd/src/glusterd-server-quorum.c +@@ -224,14 +224,14 @@ glusterd_get_quorum_cluster_counts (xlator_t *this, int *active_count, + if (active_count) + *active_count = 1; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + if (_is_contributing_to_quorum (peerinfo->quorum_contrib)) + inquorum_count = inquorum_count + 1; + if (active_count && (peerinfo->quorum_contrib == QUORUM_UP)) + *active_count = *active_count + 1; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + ret = dict_get_str (conf->opts, GLUSTERD_QUORUM_RATIO_KEY, &val); + if (ret == 0) { +diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c +index 6c56837..a2ef9f7 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-sm.c ++++ b/xlators/mgmt/glusterd/src/glusterd-sm.c +@@ -157,7 +157,7 @@ glusterd_broadcast_friend_delete (char *hostname, uuid_t uuid) + if (ret) + goto out; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + if (!peerinfo->connected || !peerinfo->peer) + continue; +@@ -180,7 +180,7 @@ glusterd_broadcast_friend_delete (char *hostname, uuid_t uuid) + } + } + unlock: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + gf_msg_debug ("glusterd", 0, "Returning with %d", ret); + +@@ -224,7 +224,7 @@ glusterd_ac_reverse_probe_begin (glusterd_friend_sm_event_t *event, void *ctx) + GF_ASSERT (event); + GF_ASSERT (ctx); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (event->peerid, event->peername); + if (!peerinfo) { +@@ -271,7 +271,7 @@ glusterd_ac_reverse_probe_begin (glusterd_friend_sm_event_t *event, void *ctx) + } + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (ret) { + if (new_event) +@@ -302,7 +302,7 @@ glusterd_ac_friend_add (glusterd_friend_sm_event_t *event, void *ctx) + + GF_ASSERT (conf); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (event->peerid, event->peername); + if (!peerinfo) { +@@ -326,7 +326,7 @@ glusterd_ac_friend_add (glusterd_friend_sm_event_t *event, void *ctx) + } + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (ret && frame) + STACK_DESTROY (frame->root); +@@ -359,7 +359,7 @@ glusterd_ac_friend_probe (glusterd_friend_sm_event_t *event, void *ctx) + + GF_ASSERT (conf); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (NULL, probe_ctx->hostname); + if (peerinfo == NULL) { + //We should not reach this state ideally +@@ -406,7 +406,7 @@ glusterd_ac_friend_probe (glusterd_friend_sm_event_t *event, void *ctx) + } + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (dict) + dict_unref (dict); +@@ -439,7 +439,7 @@ glusterd_ac_send_friend_remove_req (glusterd_friend_sm_event_t *event, + + GF_ASSERT (conf); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (event->peerid, event->peername); + if (!peerinfo) { +@@ -489,7 +489,7 @@ glusterd_ac_send_friend_remove_req (glusterd_friend_sm_event_t *event, + } + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + gf_msg_debug ("glusterd", 0, "Returning with %d", ret); + +@@ -533,7 +533,7 @@ glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx) + + GF_ASSERT (priv); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + cur_peerinfo = glusterd_peerinfo_find (event->peerid, event->peername); + if (!cur_peerinfo) { +@@ -596,7 +596,7 @@ glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx) + gf_msg_debug ("glusterd", 0, "Returning with %d", ret); + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (friends) + dict_unref (friends); +@@ -628,7 +628,7 @@ glusterd_ac_update_friend (glusterd_friend_sm_event_t *event, void *ctx) + + GF_ASSERT (priv); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + cur_peerinfo = glusterd_peerinfo_find (event->peerid, event->peername); + if (!cur_peerinfo) { +@@ -690,7 +690,7 @@ glusterd_ac_update_friend (glusterd_friend_sm_event_t *event, void *ctx) + gf_msg_debug (this->name, 0, "Returning with %d", ret); + + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (friends) + dict_unref (friends); +@@ -790,13 +790,13 @@ glusterd_ac_handle_friend_remove_req (glusterd_friend_sm_event_t *event, + ret = glusterd_xfer_friend_remove_resp (ev_ctx->req, ev_ctx->hostname, + ev_ctx->port); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + + ret = glusterd_friend_sm_new_event (GD_FRIEND_EVENT_REMOVE_FRIEND, + &new_event); + if (ret) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + goto out; + } + +@@ -805,13 +805,13 @@ glusterd_ac_handle_friend_remove_req (glusterd_friend_sm_event_t *event, + + ret = glusterd_friend_sm_inject_event (new_event); + if (ret) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + goto out; + } + + new_event = NULL; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + glusterd_peer_detach_cleanup (priv); + out: +@@ -831,7 +831,7 @@ glusterd_ac_friend_remove (glusterd_friend_sm_event_t *event, void *ctx) + + GF_ASSERT (event); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (event->peerid, event->peername); + if (!peerinfo) { +@@ -839,7 +839,7 @@ glusterd_ac_friend_remove (glusterd_friend_sm_event_t *event, void *ctx) + GD_MSG_PEER_NOT_FOUND, + "Could not find peer %s(%s)", + event->peername, uuid_utoa (event->peerid)); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + goto out; + } + ret = glusterd_friend_remove_cleanup_vols (peerinfo->uuid); +@@ -847,7 +847,7 @@ glusterd_ac_friend_remove (glusterd_friend_sm_event_t *event, void *ctx) + gf_msg (THIS->name, GF_LOG_WARNING, 0, GD_MSG_VOL_CLEANUP_FAIL, + "Volumes cleanup failed"); + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + /* Exiting read critical section as glusterd_peerinfo_cleanup calls + * synchronize_rcu before freeing the peerinfo + */ +@@ -896,14 +896,14 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx) + ev_ctx = ctx; + gf_uuid_copy (uuid, ev_ctx->uuid); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (event->peerid, event->peername); + if (!peerinfo) { + gf_msg (this->name, GF_LOG_ERROR, 0, + GD_MSG_PEER_NOT_FOUND, "Could not find peer %s(%s)", + event->peername, uuid_utoa (event->peerid)); + ret = -1; +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + goto out; + } + +@@ -913,7 +913,7 @@ glusterd_ac_handle_friend_add_req (glusterd_friend_sm_event_t *event, void *ctx) + */ + gf_uuid_copy (peerinfo->uuid, ev_ctx->uuid); + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + conf = this->private; + GF_ASSERT (conf); +@@ -1032,7 +1032,7 @@ glusterd_friend_sm_transition_state (uuid_t peerid, char *peername, + GF_ASSERT (state); + GF_ASSERT (peername); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (peerid, peername); + if (!peerinfo) { + goto out; +@@ -1047,7 +1047,7 @@ glusterd_friend_sm_transition_state (uuid_t peerid, char *peername, + + ret = 0; + out: +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + return ret; + } + +@@ -1357,7 +1357,7 @@ glusterd_friend_sm () + cds_list_del_init (&event->list); + event_type = event->event; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + + peerinfo = glusterd_peerinfo_find (event->peerid, + event->peername); +@@ -1368,7 +1368,7 @@ glusterd_friend_sm () + glusterd_friend_sm_event_name_get (event_type)); + + GF_FREE (event); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + continue; + } + gf_msg_debug ("glusterd", 0, "Dequeued event of type: '%s'", +@@ -1377,7 +1377,7 @@ glusterd_friend_sm () + + old_state = peerinfo->state.state; + +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + /* Giving up read-critical section here as we only need + * the current state to call the handler. + * +@@ -1435,11 +1435,11 @@ glusterd_friend_sm () + /* We need to obtain peerinfo reference once again as we + * had exited the read critical section above. + */ +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (event->peerid, + event->peername); + if (!peerinfo) { +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + /* A peer can only be deleted as a effect of + * this state machine, and two such state + * machines can never run at the same time. +@@ -1463,7 +1463,7 @@ glusterd_friend_sm () + } + + ret = glusterd_store_peerinfo (peerinfo); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + glusterd_destroy_friend_event_context (event); + GF_FREE (event); +diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c +index 830a67f..3c362e1 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c ++++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c +@@ -185,7 +185,7 @@ glusterd_find_missed_snap (dict_t *rsp_dict, glusterd_volinfo_t *vol, + continue; + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, peers, uuid_list) { + if (gf_uuid_compare (peerinfo->uuid, brickinfo->uuid)) { + /* If the brick doesnt belong to this peer */ +@@ -210,12 +210,12 @@ glusterd_find_missed_snap (dict_t *rsp_dict, glusterd_volinfo_t *vol, + "info for %s:%s in the " + "rsp_dict", brickinfo->hostname, + brickinfo->path); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + goto out; + } + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + brick_count++; + } + +diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c +index b3c4d9a..1db2c7c 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-store.c ++++ b/xlators/mgmt/glusterd/src/glusterd-store.c +@@ -4593,13 +4593,13 @@ glusterd_store_retrieve_peers (xlator_t *this) + + args.mode = GD_MODE_ON; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &priv->peers, uuid_list) { + ret = glusterd_friend_rpc_create (this, peerinfo, &args); + if (ret) + break; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + peerinfo = NULL; + + out: +diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c +index 5aaa7f8..9a67d1c 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c ++++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c +@@ -52,13 +52,13 @@ gd_collate_errors (struct syncargs *args, int op_ret, int op_errno, + args->op_ret = op_ret; + args->op_errno = op_errno; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (peerid, NULL); + if (peerinfo) + peer_str = gf_strdup (peerinfo->hostname); + else + peer_str = gf_strdup (uuid_utoa (uuid)); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (op_errstr && strcmp (op_errstr, "")) { + len = snprintf (err_str, sizeof(err_str) - 1, +@@ -571,7 +571,7 @@ _gd_syncop_mgmt_lock_cbk (struct rpc_req *req, struct iovec *iov, + + gf_uuid_copy (args->uuid, rsp.uuid); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (*peerid, NULL); + if (peerinfo) { + /* Set peer as locked, so we unlock only the locked peers */ +@@ -584,7 +584,7 @@ _gd_syncop_mgmt_lock_cbk (struct rpc_req *req, struct iovec *iov, + "Could not find peer with " + "ID %s", uuid_utoa (*peerid)); + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + op_ret = rsp.op_ret; + op_errno = rsp.op_errno; +@@ -670,7 +670,7 @@ _gd_syncop_mgmt_unlock_cbk (struct rpc_req *req, struct iovec *iov, + + gf_uuid_copy (args->uuid, rsp.uuid); + +- rcu_read_lock (); ++ RCU_READ_LOCK; + peerinfo = glusterd_peerinfo_find (*peerid, NULL); + if (peerinfo) { + peerinfo->locked = _gf_false; +@@ -680,7 +680,7 @@ _gd_syncop_mgmt_unlock_cbk (struct rpc_req *req, struct iovec *iov, + GD_MSG_PEER_NOT_FOUND, "Could not find peer with " + "ID %s", uuid_utoa (*peerid)); + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + op_ret = rsp.op_ret; + op_errno = rsp.op_errno; +@@ -780,9 +780,9 @@ _gd_syncop_stage_op_cbk (struct rpc_req *req, struct iovec *iov, + } + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find (rsp.uuid, NULL) == NULL); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) { + ret = -1; + gf_msg (this->name, GF_LOG_CRITICAL, 0, +@@ -1110,9 +1110,9 @@ _gd_syncop_commit_op_cbk (struct rpc_req *req, struct iovec *iov, + } + } + +- rcu_read_lock (); ++ RCU_READ_LOCK; + ret = (glusterd_peerinfo_find (rsp.uuid, NULL) == 0); +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + if (ret) { + ret = -1; + gf_msg (this->name, GF_LOG_CRITICAL, 0, +@@ -1227,7 +1227,7 @@ gd_lock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, dict_t *op_ctx, + synctask_barrier_init((&args)); + peer_cnt = 0; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -1252,7 +1252,7 @@ gd_lock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, dict_t *op_ctx, + MY_UUID, peer_uuid, txn_id); + peer_cnt++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (0 == peer_cnt) { + ret = 0; +@@ -1360,7 +1360,7 @@ stage_done: + synctask_barrier_init((&args)); + peer_cnt = 0; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -1379,7 +1379,7 @@ stage_done: + op, req_dict, op_ctx); + peer_cnt++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (0 == peer_cnt) { + ret = 0; +@@ -1491,7 +1491,7 @@ commit_done: + synctask_barrier_init((&args)); + peer_cnt = 0; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + /* Only send requests to peers who were available before the + * transaction started +@@ -1510,7 +1510,7 @@ commit_done: + op, req_dict, op_ctx); + peer_cnt++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + if (0 == peer_cnt) { + ret = 0; +@@ -1568,7 +1568,7 @@ gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret, + peer_cnt = 0; + + if (cluster_lock) { +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, + uuid_list) { + /* Only send requests to peers who were available before +@@ -1590,7 +1590,7 @@ gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret, + peer_cnt++; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + } else { + + ret = dict_get_int32 (op_ctx, "hold_global_locks", &global); +@@ -1599,7 +1599,7 @@ gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret, + else + type = "vol"; + if (volname || global) { +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, + uuid_list) { + /* Only send requests to peers who were +@@ -1620,7 +1620,7 @@ gd_unlock_op_phase (glusterd_conf_t *conf, glusterd_op_t op, int *op_ret, + tmp_uuid, txn_id); + peer_cnt++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + } + } + +diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c +index d789c53..2290343 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-utils.c +@@ -10934,7 +10934,7 @@ glusterd_volume_rebalance_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict) + node_uuid_str = gf_strdup (node_uuid); + + /* Finding the index of the node-uuid in the peer-list */ +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, + uuid_list) { + peer_uuid_str = gd_peer_uuid_str (peerinfo); +@@ -10943,7 +10943,7 @@ glusterd_volume_rebalance_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict) + + current_index++; + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + /* Setting the largest index value as the total count. */ + ret = dict_get_int32 (ctx_dict, "count", &count); +@@ -13716,7 +13716,7 @@ glusterd_count_connected_peers (int32_t *count) + + *count = 1; + +- rcu_read_lock (); ++ RCU_READ_LOCK; + cds_list_for_each_entry_rcu (peerinfo, &conf->peers, uuid_list) { + /* Find peer who is connected and is a friend */ + if ((peerinfo->connected) && +@@ -13724,7 +13724,7 @@ glusterd_count_connected_peers (int32_t *count) + (*count)++; + } + } +- rcu_read_unlock (); ++ RCU_READ_UNLOCK; + + ret = 0; + out: +diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h +index cbdca52..42c8821 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.h ++++ b/xlators/mgmt/glusterd/src/glusterd.h +@@ -804,6 +804,22 @@ do { \ + *snap_volname_ptr = '\0'; \ + } while (0) + ++#define RCU_READ_LOCK do { \ ++ pthread_mutex_lock(&(THIS->ctx)->cleanup_lock); \ ++ { \ ++ rcu_read_lock(); \ ++ } \ ++ pthread_mutex_unlock(&(THIS->ctx)->cleanup_lock); \ ++ } while (0) ++ ++#define RCU_READ_UNLOCK do { \ ++ pthread_mutex_lock(&(THIS->ctx)->cleanup_lock); \ ++ { \ ++ rcu_read_unlock(); \ ++ } \ ++ pthread_mutex_unlock(&(THIS->ctx)->cleanup_lock); \ ++ } while (0) ++ + #define GLUSTERD_DUMP_PEERS(head, member, xpeers) do { \ + glusterd_peerinfo_t *_peerinfo = NULL; \ + int index = 1; \ +@@ -815,7 +831,7 @@ do { \ + snprintf (key, sizeof (key), \ + "glusterd.xaction_peer"); \ + \ +- rcu_read_lock (); \ ++ RCU_READ_LOCK; \ + cds_list_for_each_entry_rcu (_peerinfo, head, member) { \ + glusterd_dump_peer (_peerinfo, key, index, xpeers); \ + if (!xpeers) \ +@@ -823,7 +839,7 @@ do { \ + index); \ + index++; \ + } \ +- rcu_read_unlock (); \ ++ RCU_READ_UNLOCK; \ + \ + } while (0) + +-- +1.8.3.1 + diff --git a/0478-libglusterfs-fix-memory-corruption-caused-by-per-thr.patch b/0478-libglusterfs-fix-memory-corruption-caused-by-per-thr.patch new file mode 100644 index 0000000..d3a3376 --- /dev/null +++ b/0478-libglusterfs-fix-memory-corruption-caused-by-per-thr.patch @@ -0,0 +1,289 @@ +From a5471a84069631ab0d0605cf7b68f16285f5079f Mon Sep 17 00:00:00 2001 +From: Xavi Hernandez +Date: Fri, 14 Dec 2018 11:26:36 +0100 +Subject: [PATCH 478/493] libglusterfs: fix memory corruption caused by + per-thread mem pools + +There was a race in the per-thread memory pool management that could lead +to memory corruption. The race appeared when the following sequence of +events happened: + +1. Thread T1 allocated a memory object O1 from its own private pool P1 +2. T1 terminates and P1 is marked to be destroyed +3. The mem-sweeper thread is woken up and scans all private pools +4. It detects that P1 needs to be destroyed and starts releasing the + objects from hot and cold lists. +5. Thread T2 releases O1 +6. O1 is added to the hot list of P1 + +The problem happens because steps 4 and 6 are protected by diferent locks, +so they can run concurrently. This means that both T1 and T2 are modifying +the same list at the same time, potentially causing corruption. + +This patch fixes the problem using the following approach: + +1. When an object is released, it's only returned to the hot list of the + corresponding memory pool if it's not marked to be destroyed. Otherwise + the memory is released to the system. +2. Object release and mem-sweeper thread synchronize access to the deletion + mark of the memory pool to prevent simultaneous access to the list. + +Some other minor adjustments are made to reduce the lengths of the locked +regions. + +This patch is not 100% identical to upstream version because changes +coming from https://github.com/gluster/glusterfs/issues/307 are not +backported. + +Upstream patch: https://review.gluster.org/c/glusterfs/+/21583 +> Fixes: bz#1651165 +> Change-Id: I63be3893f92096e57f54a6150e0461340084ddde +> Signed-off-by: Xavi Hernandez + +Upstream patch: https://review.gluster.org/c/glusterfs/+/21727 +> Change-Id: Idbf23bda7f9228d60c644a1bea4b6c2cfc582090 +> updates: bz#1193929 +> Signed-off-by: Xavi Hernandez + +Change-Id: I63be3893f92096e57f54a6150e0461340084ddde +BUG: 1647499 +Signed-off-by: Xavi Hernandez +Reviewed-on: https://code.engineering.redhat.com/gerrit/158658 +Tested-by: RHGS Build Bot +Reviewed-by: Pranith Kumar Karampuri +--- + libglusterfs/src/mem-pool.c | 137 ++++++++++++++++++++++++++------------------ + 1 file changed, 81 insertions(+), 56 deletions(-) + +diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c +index ba29137..8ff261c 100644 +--- a/libglusterfs/src/mem-pool.c ++++ b/libglusterfs/src/mem-pool.c +@@ -411,37 +411,34 @@ static unsigned int init_count = 0; + static pthread_t sweeper_tid; + + +-void ++gf_boolean_t + collect_garbage (sweep_state_t *state, per_thread_pool_list_t *pool_list) + { + unsigned int i; + per_thread_pool_t *pt_pool; +- +- if (pool_list->poison) { +- list_del (&pool_list->thr_list); +- list_add (&pool_list->thr_list, &state->death_row); +- return; +- } +- +- if (state->n_cold_lists >= N_COLD_LISTS) { +- return; +- } ++ gf_boolean_t poisoned; + + (void) pthread_spin_lock (&pool_list->lock); +- for (i = 0; i < NPOOLS; ++i) { +- pt_pool = &pool_list->pools[i]; +- if (pt_pool->cold_list) { +- state->cold_lists[state->n_cold_lists++] +- = pt_pool->cold_list; +- } +- pt_pool->cold_list = pt_pool->hot_list; +- pt_pool->hot_list = NULL; +- if (state->n_cold_lists >= N_COLD_LISTS) { +- /* We'll just catch up on a future pass. */ +- break; ++ ++ poisoned = pool_list->poison != 0; ++ if (!poisoned) { ++ for (i = 0; i < NPOOLS; ++i) { ++ pt_pool = &pool_list->pools[i]; ++ if (pt_pool->cold_list) { ++ if (state->n_cold_lists >= N_COLD_LISTS) { ++ break; ++ } ++ state->cold_lists[state->n_cold_lists++] ++ = pt_pool->cold_list; ++ } ++ pt_pool->cold_list = pt_pool->hot_list; ++ pt_pool->hot_list = NULL; + } + } ++ + (void) pthread_spin_unlock (&pool_list->lock); ++ ++ return poisoned; + } + + +@@ -469,6 +466,7 @@ pool_sweeper (void *arg) + struct timeval begin_time; + struct timeval end_time; + struct timeval elapsed; ++ gf_boolean_t poisoned; + + /* + * This is all a bit inelegant, but the point is to avoid doing +@@ -488,7 +486,13 @@ pool_sweeper (void *arg) + (void) pthread_mutex_lock (&pool_lock); + list_for_each_entry_safe (pool_list, next_pl, + &pool_threads, thr_list) { +- collect_garbage (&state, pool_list); ++ (void) pthread_mutex_unlock (&pool_lock); ++ poisoned = collect_garbage (&state, pool_list); ++ (void) pthread_mutex_lock (&pool_lock); ++ if (poisoned) { ++ list_move(&pool_list->thr_list, ++ &state.death_row); ++ } + } + (void) pthread_mutex_unlock (&pool_lock); + (void) gettimeofday (&end_time, NULL); +@@ -525,7 +529,15 @@ pool_destructor (void *arg) + { + per_thread_pool_list_t *pool_list = arg; + +- /* The pool-sweeper thread will take it from here. */ ++ /* The pool-sweeper thread will take it from here. ++ * ++ * We can change 'poison' here without taking locks because the change ++ * itself doesn't interact with other parts of the code and a simple ++ * write is already atomic from the point of view of the processor. ++ * ++ * 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; + } + +@@ -736,7 +748,7 @@ mem_get_pool_list (void) + (void) pthread_mutex_unlock (&pool_free_lock); + + if (!pool_list) { +- pool_list = CALLOC (pool_list_size, 1); ++ pool_list = MALLOC (pool_list_size); + if (!pool_list) { + return NULL; + } +@@ -761,26 +773,47 @@ mem_get_pool_list (void) + } + + pooled_obj_hdr_t * +-mem_get_from_pool (per_thread_pool_t *pt_pool) ++mem_get_from_pool (struct mem_pool *mem_pool) + { ++ per_thread_pool_list_t *pool_list; ++ per_thread_pool_t *pt_pool; + pooled_obj_hdr_t *retval; + ++ pool_list = mem_get_pool_list (); ++ if (!pool_list || pool_list->poison) { ++ return NULL; ++ } ++ ++ pt_pool = &pool_list->pools[mem_pool->power_of_two-POOL_SMALLEST]; ++ ++ (void) pthread_spin_lock (&pool_list->lock); ++ + retval = pt_pool->hot_list; + if (retval) { +- GF_ATOMIC_INC (pt_pool->parent->allocs_hot); + pt_pool->hot_list = retval->next; +- return retval; ++ (void) pthread_spin_unlock (&pool_list->lock); ++ GF_ATOMIC_INC (pt_pool->parent->allocs_hot); ++ } else { ++ retval = pt_pool->cold_list; ++ if (retval) { ++ pt_pool->cold_list = retval->next; ++ (void) pthread_spin_unlock (&pool_list->lock); ++ GF_ATOMIC_INC (pt_pool->parent->allocs_cold); ++ } else { ++ (void) pthread_spin_unlock (&pool_list->lock); ++ GF_ATOMIC_INC (pt_pool->parent->allocs_stdc); ++ retval = malloc (1 << mem_pool->power_of_two); ++ } + } + +- retval = pt_pool->cold_list; + if (retval) { +- GF_ATOMIC_INC (pt_pool->parent->allocs_cold); +- pt_pool->cold_list = retval->next; +- return retval; ++ retval->magic = GF_MEM_HEADER_MAGIC; ++ retval->next = NULL; ++ retval->pool_list = pool_list; ++ retval->power_of_two = mem_pool->power_of_two; + } + +- GF_ATOMIC_INC (pt_pool->parent->allocs_stdc); +- return malloc (1 << pt_pool->parent->power_of_two); ++ return retval; + } + + +@@ -791,8 +824,6 @@ mem_get (struct mem_pool *mem_pool) + return GF_CALLOC (1, AVAILABLE_SIZE (mem_pool->power_of_two), + gf_common_mt_mem_pool); + #else +- per_thread_pool_list_t *pool_list; +- per_thread_pool_t *pt_pool; + pooled_obj_hdr_t *retval; + + if (!mem_pool) { +@@ -801,25 +832,11 @@ mem_get (struct mem_pool *mem_pool) + return NULL; + } + +- pool_list = mem_get_pool_list (); +- if (!pool_list || pool_list->poison) { +- return NULL; +- } +- +- (void) pthread_spin_lock (&pool_list->lock); +- pt_pool = &pool_list->pools[mem_pool->power_of_two-POOL_SMALLEST]; +- retval = mem_get_from_pool (pt_pool); +- (void) pthread_spin_unlock (&pool_list->lock); +- ++ retval = mem_get_from_pool (mem_pool); + if (!retval) { + return NULL; + } + +- retval->magic = GF_MEM_HEADER_MAGIC; +- retval->next = NULL; +- retval->pool_list = pool_list;; +- retval->power_of_two = mem_pool->power_of_two; +- + return retval + 1; + #endif /* GF_DISABLE_MEMPOOL */ + } +@@ -849,12 +866,20 @@ mem_put (void *ptr) + pool_list = hdr->pool_list; + pt_pool = &pool_list->pools[hdr->power_of_two-POOL_SMALLEST]; + +- (void) pthread_spin_lock (&pool_list->lock); + hdr->magic = GF_MEM_INVALID_MAGIC; +- hdr->next = pt_pool->hot_list; +- pt_pool->hot_list = hdr; +- GF_ATOMIC_INC (pt_pool->parent->frees_to_list); +- (void) pthread_spin_unlock (&pool_list->lock); ++ ++ (void) pthread_spin_lock (&pool_list->lock); ++ if (!pool_list->poison) { ++ hdr->next = pt_pool->hot_list; ++ pt_pool->hot_list = hdr; ++ (void) pthread_spin_unlock (&pool_list->lock); ++ GF_ATOMIC_INC (pt_pool->parent->frees_to_list); ++ } else { ++ (void) pthread_spin_unlock (&pool_list->lock); ++ /* If the owner thread of this element has terminated, we ++ * simply release its memory. */ ++ free(hdr); ++ } + #endif /* GF_DISABLE_MEMPOOL */ + } + +-- +1.8.3.1 + diff --git a/0479-ganesha-ha-ensure-pacemaker-is-enabled-after-setup.patch b/0479-ganesha-ha-ensure-pacemaker-is-enabled-after-setup.patch new file mode 100644 index 0000000..a541716 --- /dev/null +++ b/0479-ganesha-ha-ensure-pacemaker-is-enabled-after-setup.patch @@ -0,0 +1,51 @@ +From e42fcda7ca4becd4e14b36c6318ed6c3a3068783 Mon Sep 17 00:00:00 2001 +From: "Kaleb S. KEITHLEY" +Date: Tue, 11 Dec 2018 10:09:42 -0500 +Subject: [PATCH 479/493] ganesha-ha: ensure pacemaker is enabled after setup + +There appears to be a race between `pcs cluster setup ...` early +in the setup and the `systemctl enable pacemaker` at the end. The +`pcs cluster setup ...` disables pacemaker and corosync. (Now, in +pacemaker-1.1.18. Was it always the case?) + +I am not able to reproduce this on my devel system. I speculate that +on a busy system that the `pcs cluster setup ...` disable may, under +the right conditions, not run until after the setup script enables +it. It must require the right alignment of the Sun, Moon, and all +the planets. + +Regardless, we'll use the --enable option to `pcs cluster setup ...` +to ensure that the cluster (re)starts pacemaker. + +Label: DOWNSTREAM ONLY + +Change-Id: I771ff62c37426438b80e61651a8b4ecaf2d549c3 +BUG: 1637564 +Signed-off-by: Kaleb S. KEITHLEY +Reviewed-on: https://code.engineering.redhat.com/gerrit/158294 +Tested-by: RHGS Build Bot +Reviewed-by: Soumya Koduri +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + extras/ganesha/scripts/ganesha-ha.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh +index 5cdafad..5a7f5ae 100644 +--- a/extras/ganesha/scripts/ganesha-ha.sh ++++ b/extras/ganesha/scripts/ganesha-ha.sh +@@ -195,9 +195,9 @@ setup_cluster() + + pcs cluster auth ${servers} + # pcs cluster setup --name ${name} ${servers} +- pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --transport udpu ${servers} ++ pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --enable --transport udpu ${servers} + if [ $? -ne 0 ]; then +- logger "pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} ${servers} failed" ++ logger "pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} --enable --transport udpu ${servers} failed" + #set up failed stop all ganesha process and clean up symlinks in cluster + stop_ganesha_all "${servers}" + exit 1; +-- +1.8.3.1 + diff --git a/0480-geo-rep-Make-slave-volume-read-only-by-default.patch b/0480-geo-rep-Make-slave-volume-read-only-by-default.patch new file mode 100644 index 0000000..017b1bd --- /dev/null +++ b/0480-geo-rep-Make-slave-volume-read-only-by-default.patch @@ -0,0 +1,101 @@ +From ecb5c63d41daf98c3bca73d2ab24aa77e1b34886 Mon Sep 17 00:00:00 2001 +From: Sunny Kumar +Date: Mon, 17 Dec 2018 12:56:33 +0530 +Subject: [PATCH 480/493] geo-rep: Make slave volume read-only (by default) + +Added a command to set "features.read-only" option +to a default value "on" for slave volume. +Changes are made in: +$SRC//extras/hook-scripts/S56glusterd-geo-rep-create-post.sh +for root geo-rep and +$SRC/geo-replication/src/set_geo_rep_pem_keys.sh +for non-root geo-rep. + +Upstream patch : https://review.gluster.org/#/c/glusterfs/+/21739 +>Fixes: bz#1654187 +>Signed-off-by: Harpreet Kaur + +Change-Id: I15beeae3506f3f6b1dcba0a5c50b6344fd468c7c +BUG: 1643370 +Signed-off-by: Sunny Kumar +Reviewed-on: https://code.engineering.redhat.com/gerrit/158790 +Tested-by: RHGS Build Bot +Reviewed-by: Kotresh Hiremath Ravishankar +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + extras/hook-scripts/S56glusterd-geo-rep-create-post.sh | 1 + + geo-replication/src/set_geo_rep_pem_keys.sh | 1 + + tests/geo-rep.rc | 7 +++++++ + tests/geo-rep/georep-basic-dr-rsync.t | 3 +++ + tests/geo-rep/georep-basic-dr-tarssh.t | 3 +++ + 5 files changed, 15 insertions(+) + +diff --git a/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh b/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh +index a5e472e..589c263 100755 +--- a/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh ++++ b/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh +@@ -90,5 +90,6 @@ if [ -f $pub_file ]; then + ssh -p ${SSH_PORT} $slave_ip "mv $pub_file_tmp ${pub_file_dname}/${mastervol}_${slavevol}_${pub_file_bname}" + ssh -p ${SSH_PORT} $slave_ip "gluster system:: copy file /geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null" + ssh -p ${SSH_PORT} $slave_ip "gluster system:: execute add_secret_pub root geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null" ++ ssh -p ${SSH_PORT} $slave_ip "gluster vol set ${slavevol} features.read-only on" + fi + fi +diff --git a/geo-replication/src/set_geo_rep_pem_keys.sh b/geo-replication/src/set_geo_rep_pem_keys.sh +index ae23f4f..8a43fa3 100755 +--- a/geo-replication/src/set_geo_rep_pem_keys.sh ++++ b/geo-replication/src/set_geo_rep_pem_keys.sh +@@ -47,6 +47,7 @@ function main() + cp $home_dir/${COMMON_SECRET_PEM_PUB} ${GLUSTERD_WORKDIR}/geo-replication/ + gluster system:: copy file /geo-replication/${COMMON_SECRET_PEM_PUB} + gluster system:: execute add_secret_pub $user geo-replication/${master_vol}_${slave_vol}_common_secret.pem.pub ++ gluster vol set ${slave_vol} features.read-only on + else + echo "$home_dir/common_secret.pem.pub not present. Please run geo-replication command on master with push-pem option to generate the file" + exit 1; +diff --git a/tests/geo-rep.rc b/tests/geo-rep.rc +index 1a44b4a..f9ab3fc 100644 +--- a/tests/geo-rep.rc ++++ b/tests/geo-rep.rc +@@ -230,3 +230,10 @@ function hardlink_rename_ok() + fi + return 0 + } ++ ++function check_slave_read_only() ++{ ++ volum=$1 ++ gluster volume info $1 | grep 'features.read-only: on' ++ echo $? ++} +diff --git a/tests/geo-rep/georep-basic-dr-rsync.t b/tests/geo-rep/georep-basic-dr-rsync.t +index 39da524..fd0c4aa 100644 +--- a/tests/geo-rep/georep-basic-dr-rsync.t ++++ b/tests/geo-rep/georep-basic-dr-rsync.t +@@ -57,6 +57,9 @@ EXPECT 4 check_status_num_rows "Created" #15 + #Enable_metavolume + TEST $GEOREP_CLI $master $slave config use_meta_volume true + ++#Verify "features.read-only" Option ++EXPECT_WITHIN $GEO_REP_TIMEOUT 0 check_slave_read_only $GSV0 ++ + #Start_georep + TEST $GEOREP_CLI $master $slave start + +diff --git a/tests/geo-rep/georep-basic-dr-tarssh.t b/tests/geo-rep/georep-basic-dr-tarssh.t +index 5f879db..5331df9 100644 +--- a/tests/geo-rep/georep-basic-dr-tarssh.t ++++ b/tests/geo-rep/georep-basic-dr-tarssh.t +@@ -62,6 +62,9 @@ TEST $GEOREP_CLI $master $slave config use_meta_volume true + #Config tarssh as sync-engine + TEST $GEOREP_CLI $master $slave config use_tarssh true + ++#Verify "features.read-only" Option ++EXPECT_WITHIN $GEO_REP_TIMEOUT 0 check_slave_read_only $GSV0 ++ + #Start_georep + TEST $GEOREP_CLI $master $slave start + +-- +1.8.3.1 + diff --git a/0481-extras-hooks-Do-not-blindly-remove-volume-share-from.patch b/0481-extras-hooks-Do-not-blindly-remove-volume-share-from.patch new file mode 100644 index 0000000..f055981 --- /dev/null +++ b/0481-extras-hooks-Do-not-blindly-remove-volume-share-from.patch @@ -0,0 +1,102 @@ +From 644bcd954000b77fc8f49e3a7941de23ca869427 Mon Sep 17 00:00:00 2001 +From: Anoop C S +Date: Wed, 21 Mar 2018 13:09:01 +0530 +Subject: [PATCH 481/493] extras/hooks: Do not blindly remove volume share from + smb.conf + +When Gluster volumes are shared via Samba, any extra smb.conf parameter +setting done by administrator to those shares are lost during restart +of the volume. Instead of removing the whole share completely from +smb.conf(via hook scripts during volume stop) it is better to make it +temporarily unavailable to end-users till the volume is started again. +Therefore we make use of a smb.conf parameter named 'available'[1] to +achieve the above intend. + +[1] https://www.samba.org/samba/docs/current/man-html/smb.conf.5.html + +upstream ref: https://review.gluster.org/c/glusterfs/+/19750 + +Change-Id: I68a9055b50791f6ffd3b95a3c13d858a75fa6530 +BUG: 1164778 +Signed-off-by: Anoop C S +Reviewed-on: https://code.engineering.redhat.com/gerrit/158495 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + extras/hook-scripts/set/post/S30samba-set.sh | 11 ++++++----- + extras/hook-scripts/start/post/S30samba-start.sh | 4 +++- + extras/hook-scripts/stop/pre/S30samba-stop.sh | 6 +++--- + 3 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/extras/hook-scripts/set/post/S30samba-set.sh b/extras/hook-scripts/set/post/S30samba-set.sh +index b93415b..c596db0 100755 +--- a/extras/hook-scripts/set/post/S30samba-set.sh ++++ b/extras/hook-scripts/set/post/S30samba-set.sh +@@ -103,9 +103,9 @@ function sighup_samba () { + fi + } + +-function del_samba_share () { ++function deactivate_samba_share () { + volname=$1 +- sed -i "/\[gluster-$volname\]/,/^$/d" ${CONFIGFILE} ++ sed -i -e '/^\[gluster-'"$volname"'\]/{ :a' -e 'n; /available = no/H; /^$/!{$!ba;}; x; /./!{ s/^/available = no/; $!{G;x}; $H; }; s/.*//; x; };' ${CONFIGFILE} + } + + function is_volume_started () { +@@ -140,12 +140,13 @@ if [ "$USERCIFS_SET" = "YES" ] || [ "$USERSMB_SET" = "YES" ]; then + find_config_info + + if [ "$(get_smb "$VOL")" = "disable" ]; then +- del_samba_share $VOL +- sighup_samba ++ deactivate_samba_share $VOL + else + if ! grep --quiet "\[gluster-$VOL\]" ${CONFIGFILE} ; then + add_samba_share $VOL +- sighup_samba ++ else ++ sed -i '/\[gluster-'"$VOL"'\]/,/^$/!b;/available = no/d' ${CONFIGFILE} + fi + fi ++ sighup_samba + fi +diff --git a/extras/hook-scripts/start/post/S30samba-start.sh b/extras/hook-scripts/start/post/S30samba-start.sh +index 92ddaf4..5d586ee 100755 +--- a/extras/hook-scripts/start/post/S30samba-start.sh ++++ b/extras/hook-scripts/start/post/S30samba-start.sh +@@ -127,5 +127,7 @@ find_config_info + + if ! grep --quiet "\[gluster-$VOL\]" ${CONFIGFILE} ; then + add_samba_share $VOL +- sighup_samba ++else ++ sed -i '/\[gluster-'"$VOL"'\]/,/^$/!b;/available = no/d' ${CONFIGFILE} + fi ++sighup_samba +diff --git a/extras/hook-scripts/stop/pre/S30samba-stop.sh b/extras/hook-scripts/stop/pre/S30samba-stop.sh +index 5e87845..ea79938 100755 +--- a/extras/hook-scripts/stop/pre/S30samba-stop.sh ++++ b/extras/hook-scripts/stop/pre/S30samba-stop.sh +@@ -56,9 +56,9 @@ function find_config_info () { + PIDDIR=`smbd -b | grep PIDDIR | awk '{print $2}'` + } + +-function del_samba_share () { ++function deactivate_samba_share () { + volname=$1 +- sed -i "/\[gluster-$volname\]/,/^$/d" ${CONFIGFILE} ++ sed -i -e '/^\[gluster-'"$volname"'\]/{ :a' -e 'n; /available = no/H; /^$/!{$!ba;}; x; /./!{ s/^/available = no/; $!{G;x}; $H; }; s/.*//; x; };' ${CONFIGFILE} + } + + function sighup_samba () { +@@ -73,5 +73,5 @@ function sighup_samba () { + + parse_args "$@" + find_config_info +-del_samba_share $VOL ++deactivate_samba_share $VOL + sighup_samba +-- +1.8.3.1 + diff --git a/0482-extras-hooks-General-improvements-to-S30samba-start..patch b/0482-extras-hooks-General-improvements-to-S30samba-start..patch new file mode 100644 index 0000000..65e2cf6 --- /dev/null +++ b/0482-extras-hooks-General-improvements-to-S30samba-start..patch @@ -0,0 +1,91 @@ +From 121180edc218432a782a153e94b9f884d4c56a7c Mon Sep 17 00:00:00 2001 +From: Anoop C S +Date: Sun, 9 Sep 2018 11:39:47 +0530 +Subject: [PATCH 482/493] extras/hooks: General improvements to + S30samba-start.sh + +Based on https://review.gluster.org/c/glusterfs/+/19204 from +Milan Zink + +upstream ref: https://review.gluster.org/c/glusterfs/+/21124 + +Change-Id: I61f62407a62475a74a6cc046c24748a31c66e6cd +BUG: 1541568 +Signed-off-by: Anoop C S +Reviewed-on: https://code.engineering.redhat.com/gerrit/158496 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + extras/hook-scripts/start/post/S30samba-start.sh | 26 ++++++++++++------------ + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/extras/hook-scripts/start/post/S30samba-start.sh b/extras/hook-scripts/start/post/S30samba-start.sh +index 5d586ee..dfd9c1b 100755 +--- a/extras/hook-scripts/start/post/S30samba-start.sh ++++ b/extras/hook-scripts/start/post/S30samba-start.sh +@@ -68,14 +68,14 @@ function parse_args () { + } + + function find_config_info () { +- cmdout=`smbd -b | grep smb.conf` +- if [ $? -ne 0 ];then ++ cmdout=$(smbd -b 2> /dev/null) ++ CONFIGFILE=$(echo "$cmdout" | grep CONFIGFILE | awk '{print $2}') ++ if [ -z "$CONFIGFILE" ]; then + echo "Samba is not installed" + exit 1 + fi +- CONFIGFILE=`echo $cmdout | awk '{print $2}'` +- PIDDIR=`smbd -b | grep PIDDIR | awk '{print $2}'` +- LOGFILEBASE=`smbd -b | grep 'LOGFILEBASE' | awk '{print $2}'` ++ PIDDIR=$(echo "$cmdout" | grep PIDDIR | awk '{print $2}') ++ LOGFILEBASE=$(echo "$cmdout" | grep 'LOGFILEBASE' | awk '{print $2}') + } + + function add_samba_share () { +@@ -89,11 +89,11 @@ function add_samba_share () { + STRING+="path = /\n" + STRING+="read only = no\n" + STRING+="guest ok = yes\n" +- printf "$STRING" >> ${CONFIGFILE} ++ printf "$STRING" >> "${CONFIGFILE}" + } + + function sighup_samba () { +- pid=`cat ${PIDDIR}/smbd.pid` ++ pid=$(cat "${PIDDIR}/smbd.pid" 2> /dev/null) + if [ "x$pid" != "x" ] + then + kill -HUP "$pid"; +@@ -106,12 +106,12 @@ function get_smb () { + volname=$1 + uservalue= + +- usercifsvalue=$(grep user.cifs $GLUSTERD_WORKDIR/vols/"$volname"/info |\ ++ usercifsvalue=$(grep user.cifs "$GLUSTERD_WORKDIR"/vols/"$volname"/info |\ + cut -d"=" -f2) +- usersmbvalue=$(grep user.smb $GLUSTERD_WORKDIR/vols/"$volname"/info |\ ++ usersmbvalue=$(grep user.smb "$GLUSTERD_WORKDIR"/vols/"$volname"/info |\ + cut -d"=" -f2) + +- if [ $usercifsvalue = "disable" ] || [ $usersmbvalue = "disable" ]; then ++ if [ "$usercifsvalue" = "disable" ] || [ "$usersmbvalue" = "disable" ]; then + uservalue="disable" + fi + echo "$uservalue" +@@ -125,9 +125,9 @@ fi + #Find smb.conf, smbd pid directory and smbd logfile path + find_config_info + +-if ! grep --quiet "\[gluster-$VOL\]" ${CONFIGFILE} ; then +- add_samba_share $VOL ++if ! grep --quiet "\[gluster-$VOL\]" "${CONFIGFILE}" ; then ++ add_samba_share "$VOL" + else +- sed -i '/\[gluster-'"$VOL"'\]/,/^$/!b;/available = no/d' ${CONFIGFILE} ++ sed -i '/\[gluster-'"$VOL"'\]/,/^$/!b;/available = no/d' "${CONFIGFILE}" + fi + sighup_samba +-- +1.8.3.1 + diff --git a/0483-Do-not-blindly-add-volume-share-section-to-smb.conf.patch b/0483-Do-not-blindly-add-volume-share-section-to-smb.conf.patch new file mode 100644 index 0000000..60f5d1a --- /dev/null +++ b/0483-Do-not-blindly-add-volume-share-section-to-smb.conf.patch @@ -0,0 +1,86 @@ +From c807ba5a11364d8eb83b86b0e4262a32b6834267 Mon Sep 17 00:00:00 2001 +From: Anoop C S +Date: Thu, 13 Dec 2018 12:05:37 +0530 +Subject: [PATCH 483/493] Do not blindly add volume share section to smb.conf + +With this change, by default GlusterFS volume share section will +no longer be added to smb.conf for client access unless user.cifs +or user.smb volume set options are enabled. This also fixes the +hook script to check for presence of all configuration possibilities +for those volume set options like 'enable' or 'on'. + +upstream ref: https://review.gluster.org/c/glusterfs/+/19204 + +Change-Id: Ibecf7fffb4507d7255d963c3b1482afb0d0db984 +BUG: 1541568 +Signed-off-by: Anoop C S +Reviewed-on: https://code.engineering.redhat.com/gerrit/158497 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + extras/hook-scripts/set/post/S30samba-set.sh | 13 +++++++++++-- + extras/hook-scripts/start/post/S30samba-start.sh | 18 +++++++++++++++--- + 2 files changed, 26 insertions(+), 5 deletions(-) + +diff --git a/extras/hook-scripts/set/post/S30samba-set.sh b/extras/hook-scripts/set/post/S30samba-set.sh +index c596db0..d2a62d3 100755 +--- a/extras/hook-scripts/set/post/S30samba-set.sh ++++ b/extras/hook-scripts/set/post/S30samba-set.sh +@@ -123,9 +123,18 @@ function get_smb () { + usersmbvalue=$(grep user.smb $GLUSTERD_WORKDIR/vols/"$volname"/info |\ + cut -d"=" -f2) + +- if [ $usercifsvalue = "disable" ] || [ $usersmbvalue = "disable" ]; then +- uservalue="disable" ++ if [ -n "$usercifsvalue" ]; then ++ if [ "$usercifsvalue" = "disable" ] || [ "$usercifsvalue" = "off" ]; then ++ uservalue="disable" ++ fi + fi ++ ++ if [ -n "$usersmbvalue" ]; then ++ if [ "$usersmbvalue" = "disable" ] || [ "$usersmbvalue" = "off" ]; then ++ uservalue="disable" ++ fi ++ fi ++ + echo "$uservalue" + } + +diff --git a/extras/hook-scripts/start/post/S30samba-start.sh b/extras/hook-scripts/start/post/S30samba-start.sh +index dfd9c1b..2854bdd 100755 +--- a/extras/hook-scripts/start/post/S30samba-start.sh ++++ b/extras/hook-scripts/start/post/S30samba-start.sh +@@ -111,14 +111,26 @@ function get_smb () { + usersmbvalue=$(grep user.smb "$GLUSTERD_WORKDIR"/vols/"$volname"/info |\ + cut -d"=" -f2) + +- if [ "$usercifsvalue" = "disable" ] || [ "$usersmbvalue" = "disable" ]; then +- uservalue="disable" ++ if [ -n "$usercifsvalue" ]; then ++ if [ "$usercifsvalue" = "enable" ] || [ "$usercifsvalue" = "on" ]; then ++ uservalue="enable" ++ fi + fi ++ ++ if [ -n "$usersmbvalue" ]; then ++ if [ "$usersmbvalue" = "enable" ] || [ "$usersmbvalue" = "on" ]; then ++ uservalue="enable" ++ fi ++ fi ++ + echo "$uservalue" + } + + parse_args "$@" +-if [ "$(get_smb "$VOL")" = "disable" ]; then ++ ++value=$(get_smb "$VOL") ++ ++if [ -z "$value" ] || [ "$value" != "enable" ]; then + exit 0 + fi + +-- +1.8.3.1 + diff --git a/0484-extras-New-group-volume-set-command-for-Samba-integr.patch b/0484-extras-New-group-volume-set-command-for-Samba-integr.patch new file mode 100644 index 0000000..215d0e2 --- /dev/null +++ b/0484-extras-New-group-volume-set-command-for-Samba-integr.patch @@ -0,0 +1,84 @@ +From bf8ca8c73df0a114b9728150934d6b7ecd3cbd6f Mon Sep 17 00:00:00 2001 +From: Anoop C S +Date: Thu, 6 Dec 2018 15:05:20 +0530 +Subject: [PATCH 484/493] extras: New group volume set command for Samba + integration + + # gluster volume set group samba + +List of volume set options from group-samba are aimed at improving the below +workloads which consumes time and network hops in SMB world: + +* Listing of large directories +* Negative lookups during creation of files + +Caching the necessary metadata required for these workloads saves us time and +network hops. On the other side we have to ensure correctness(avoiding stale +cache) in caching(via md-cache) with the help of cache invalidation in an +environment where multiple client access is expected. + +upstream ref: https://review.gluster.org/c/glusterfs/+/21814 + +Change-Id: Icdd2d8e5eb290e12bc509105418c668f432f4eae +BUG: 1655385 +Signed-off-by: Anoop C S +Reviewed-on: https://code.engineering.redhat.com/gerrit/158723 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + extras/Makefile.am | 4 +++- + extras/group-samba | 10 ++++++++++ + glusterfs.spec.in | 1 + + 3 files changed, 14 insertions(+), 1 deletion(-) + create mode 100644 extras/group-samba + +diff --git a/extras/Makefile.am b/extras/Makefile.am +index e0e05b5..f898245 100644 +--- a/extras/Makefile.am ++++ b/extras/Makefile.am +@@ -14,7 +14,7 @@ confdir = $(sysconfdir)/glusterfs + conf_DATA = glusterfs-logrotate gluster-rsyslog-7.2.conf gluster-rsyslog-5.8.conf \ + logger.conf.example glusterfs-georep-logrotate group-virt.example \ + group-metadata-cache group-gluster-block group-nl-cache group-db-workload \ +- group-distributed-virt ++ group-distributed-virt group-samba + + voldir = $(sysconfdir)/glusterfs + vol_DATA = glusterd.vol +@@ -53,3 +53,5 @@ install-data-local: + $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/db-workload + $(INSTALL_DATA) $(top_srcdir)/extras/group-distributed-virt \ + $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/distributed-virt ++ $(INSTALL_DATA) $(top_srcdir)/extras/group-samba \ ++ $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/samba +diff --git a/extras/group-samba b/extras/group-samba +new file mode 100644 +index 0000000..ee39202 +--- /dev/null ++++ b/extras/group-samba +@@ -0,0 +1,10 @@ ++features.cache-invalidation=on ++features.cache-invalidation-timeout=600 ++performance.cache-samba-metadata=on ++performance.stat-prefetch=on ++performance.cache-invalidation=on ++performance.md-cache-timeout=600 ++network.inode-lru-limit=200000 ++performance.nl-cache=on ++performance.nl-cache-timeout=600 ++performance.parallel-readdir=on +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index a4accd9..16dc5d7 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1524,6 +1524,7 @@ exit 0 + %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/db-workload + %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/distributed-virt + %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/nl-cache ++ %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/samba + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glusterfind + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glusterfind/.keys + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glustershd +-- +1.8.3.1 + diff --git a/0485-cluster-ec-Prevent-volume-create-without-redundant-b.patch b/0485-cluster-ec-Prevent-volume-create-without-redundant-b.patch new file mode 100644 index 0000000..72e202e --- /dev/null +++ b/0485-cluster-ec-Prevent-volume-create-without-redundant-b.patch @@ -0,0 +1,60 @@ +From f3982cf5bf3250ee29da3ea4477591c298780043 Mon Sep 17 00:00:00 2001 +From: Sunil Kumar Acharya +Date: Mon, 17 Dec 2018 16:37:21 +0530 +Subject: [PATCH 485/493] cluster/ec : Prevent volume create without redundant + brick + +Problem: +EC volumes can be created without any redundant brick. + +Solution: +Updated the conditional check to avoid volume create +without redundant brick. + +>fixes: bz#1642448 +>Change-Id: I0cb334b1b9378d67fcb8abf793dbe312c3179c0b +>Signed-off-by: Sunil Kumar Acharya +Upstream Patch: https://review.gluster.org/#/c/glusterfs/+/21478/ + +BUG: 1597252 +Change-Id: I0cb334b1b9378d67fcb8abf793dbe312c3179c0b +Signed-off-by: Sunil Kumar Acharya +Reviewed-on: https://code.engineering.redhat.com/gerrit/158910 +Tested-by: RHGS Build Bot +--- + cli/src/cli-cmd-parser.c | 6 +++--- + tests/basic/glusterd/disperse-create.t | 1 + + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c +index 3745fb4..e790d79 100644 +--- a/cli/src/cli-cmd-parser.c ++++ b/cli/src/cli-cmd-parser.c +@@ -275,9 +275,9 @@ cli_cmd_create_disperse_check (struct cli_state *state, int *disperse, + tmp = *disperse - *redundancy; + } + +- if (*redundancy > (*disperse - 1) / 2) { +- cli_err ("redundancy must be less than %d for a " +- "disperse %d volume", ++ if ((*redundancy < 1) || (*redundancy > (*disperse - 1) / 2)) { ++ cli_err ("redundancy must be greater than or equal to 1 and" ++ " less than %d for a disperse %d volume", + (*disperse + 1) / 2, *disperse); + + return -1; +diff --git a/tests/basic/glusterd/disperse-create.t b/tests/basic/glusterd/disperse-create.t +index e5ce74c..5b3ed13 100644 +--- a/tests/basic/glusterd/disperse-create.t ++++ b/tests/basic/glusterd/disperse-create.t +@@ -48,6 +48,7 @@ TEST ! $CLI volume create $V0 redundancy 1 redundancy 1 $H0:$B0/b20 $H0:$B0/b21 + #Minimum counts test + TEST ! $CLI volume create $V0 disperse 2 $H0:$B0/b20 $H0:$B0/b22 + TEST ! $CLI volume create $V0 disperse-data 1 redundancy 0 $H0:$B0/b20 $H0:$B0/b22 ++TEST ! $CLI volume create $V0 disperse 4 disperse-data 4 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b23 $H0:$B0/b24 + TEST ! $CLI volume create $V0 redundancy 0 $H0:$B0/b20 $H0:$B0/b22 + + #Wrong count n != k+m +-- +1.8.3.1 + diff --git a/0486-performance-rda-Fixed-dict_t-memory-leak.patch b/0486-performance-rda-Fixed-dict_t-memory-leak.patch new file mode 100644 index 0000000..2c29a2a --- /dev/null +++ b/0486-performance-rda-Fixed-dict_t-memory-leak.patch @@ -0,0 +1,51 @@ +From 64cfb0126d88bd6b841777fefb63e413b587a7b1 Mon Sep 17 00:00:00 2001 +From: N Balachandran +Date: Tue, 18 Dec 2018 14:08:04 +0530 +Subject: [PATCH 486/493] performance/rda: Fixed dict_t memory leak + +Removed all references to dict_t xdata_from_req which is +allocated but not used anywhere. It is also not cleaned up +and hence causes a memory leak. + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/21859/ + +> Change-Id: I2edb857696191e872ad12a12efc36999626bacc7 +> fixes: bz#1659432 +> Signed-off-by: N Balachandran + +Change-Id: Ic07ecbefef3140aeb24a2afaf97c80ee65768e7e +BUG: 1659439 +Signed-off-by: N Balachandran +Reviewed-on: https://code.engineering.redhat.com/gerrit/158915 +Tested-by: RHGS Build Bot +Reviewed-by: Raghavendra Gowdappa +--- + xlators/performance/readdir-ahead/src/readdir-ahead.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/xlators/performance/readdir-ahead/src/readdir-ahead.c b/xlators/performance/readdir-ahead/src/readdir-ahead.c +index 6501a6b..3e0951c 100644 +--- a/xlators/performance/readdir-ahead/src/readdir-ahead.c ++++ b/xlators/performance/readdir-ahead/src/readdir-ahead.c +@@ -505,18 +505,10 @@ rda_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, + { + int op_errno = 0; + struct rda_local *local = NULL; +- dict_t *xdata_from_req = NULL; + + if (xdata) { +- xdata_from_req = dict_new(); +- if (!xdata_from_req) { +- op_errno = ENOMEM; +- goto unwind; +- } +- + local = mem_get0(this->local_pool); + if (!local) { +- dict_unref(xdata_from_req); + op_errno = ENOMEM; + goto unwind; + } +-- +1.8.3.1 + diff --git a/0487-mem-pool-add-tracking-of-mem_pool-that-requested-the.patch b/0487-mem-pool-add-tracking-of-mem_pool-that-requested-the.patch new file mode 100644 index 0000000..baa6715 --- /dev/null +++ b/0487-mem-pool-add-tracking-of-mem_pool-that-requested-the.patch @@ -0,0 +1,270 @@ +From 3cc901acea41632df0c342639c4292c10bd90964 Mon Sep 17 00:00:00 2001 +From: Mohit Agrawal +Date: Tue, 18 Dec 2018 15:39:14 +0530 +Subject: [PATCH 487/493] mem-pool: add tracking of mem_pool that requested the + allocation + +This renames the current 'struct mem_pool' to 'struct mem_pool_shared'. +The mem_pool_shared is globally allocated and not specific for +particular objects. + +A new 'struct mem_pool' gets allocated when mem_pool_new() is called. It +points to the mem_pool_shared that handles the actual allocation +requests. The 'struct mem_pool' is only used for accounting of the +objects that the caller requested and free'd. + +All of these changes will be used to collect all the memory pools a +glusterfs_ctx_t is consuming, so that statedumps can be collected per +context. + +> Updates: #307 +> Change-Id: I6355d3f0251c928e0bbfc71be3431307c6f3a3da +> Signed-off-by: Niels de Vos +> Reviewed-on: https://review.gluster.org/18073 +> Smoke: Gluster Build System +> CentOS-regression: Gluster Build System +> Reviewed-by: Amar Tumballi +> Reviewed-by: Jeff Darcy +> Cherry picked from commit 2645e730b79b44fc035170657e43bb52f3e855c5 + +Change-Id: I6cce6284e4553c6ca59a90ad124c23c950db3148 +BUG: 1648893 +Signed-off-by: Mohit Agrawal + +Signed-off-by: Mohit Agrawal +Change-Id: I363d71152b1dd17eca53d9c327fcdf2f26c0fb61 +Reviewed-on: https://code.engineering.redhat.com/gerrit/158930 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + libglusterfs/src/mem-pool.c | 69 +++++++++++++++++++++++++++----------------- + libglusterfs/src/mem-pool.h | 20 +++++++++++-- + libglusterfs/src/mem-types.h | 2 -- + 3 files changed, 60 insertions(+), 31 deletions(-) + +diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c +index 8ff261c..a8a9347 100644 +--- a/libglusterfs/src/mem-pool.c ++++ b/libglusterfs/src/mem-pool.c +@@ -14,15 +14,6 @@ + #include + #include + +-#define GF_MEM_POOL_LIST_BOUNDARY (sizeof(struct list_head)) +-#define GF_MEM_POOL_PTR (sizeof(struct mem_pool*)) +-#define GF_MEM_POOL_PAD_BOUNDARY (GF_MEM_POOL_LIST_BOUNDARY + GF_MEM_POOL_PTR + sizeof(int)) +-#define mem_pool_chunkhead2ptr(head) ((head) + GF_MEM_POOL_PAD_BOUNDARY) +-#define mem_pool_ptr2chunkhead(ptr) ((ptr) - GF_MEM_POOL_PAD_BOUNDARY) +-#define is_mem_chunk_in_use(ptr) (*ptr == 1) +-#define mem_pool_from_ptr(ptr) ((ptr) + GF_MEM_POOL_LIST_BOUNDARY) +- +-#define GLUSTERFS_ENV_MEM_ACCT_STR "GLUSTERFS_DISABLE_MEM_ACCT" + + #include "unittest/unittest.h" + #include "libglusterfs-messages.h" +@@ -380,7 +371,7 @@ 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; + static struct list_head pool_free_threads; +-static struct mem_pool pools[NPOOLS]; ++static struct mem_pool_shared pools[NPOOLS]; + static size_t pool_list_size; + + #if !defined(GF_DISABLE_MEMPOOL) +@@ -689,6 +680,8 @@ mem_pool_new_fn (unsigned long sizeof_type, + unsigned long count, char *name) + { + unsigned int i; ++ struct mem_pool *new = NULL; ++ struct mem_pool_shared *pool = NULL; + + if (!sizeof_type) { + gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL, +@@ -698,13 +691,27 @@ mem_pool_new_fn (unsigned long sizeof_type, + + for (i = 0; i < NPOOLS; ++i) { + if (sizeof_type <= AVAILABLE_SIZE(pools[i].power_of_two)) { +- return &pools[i]; ++ pool = &pools[i]; ++ break; + } + } + +- gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL, +- LG_MSG_INVALID_ARG, "invalid argument"); +- return NULL; ++ if (!pool) { ++ gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL, ++ LG_MSG_INVALID_ARG, "invalid argument"); ++ return NULL; ++ } ++ ++ new = GF_CALLOC (sizeof (struct mem_pool), 1, gf_common_mt_mem_pool); ++ if (!new) ++ return NULL; ++ ++ new->sizeof_type = sizeof_type; ++ new->count = count; ++ new->name = name; ++ new->pool = pool; ++ ++ return new; + } + + void* +@@ -721,7 +728,7 @@ mem_get0 (struct mem_pool *mem_pool) + ptr = mem_get(mem_pool); + + if (ptr) { +- memset (ptr, 0, AVAILABLE_SIZE(mem_pool->power_of_two)); ++ memset (ptr, 0, AVAILABLE_SIZE(mem_pool->pool->power_of_two)); + } + + return ptr; +@@ -784,7 +791,7 @@ mem_get_from_pool (struct mem_pool *mem_pool) + return NULL; + } + +- pt_pool = &pool_list->pools[mem_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); + +@@ -802,7 +809,7 @@ mem_get_from_pool (struct mem_pool *mem_pool) + } else { + (void) pthread_spin_unlock (&pool_list->lock); + GF_ATOMIC_INC (pt_pool->parent->allocs_stdc); +- retval = malloc (1 << mem_pool->power_of_two); ++ retval = malloc (1 << mem_pool->pool->power_of_two); + } + } + +@@ -810,7 +817,7 @@ mem_get_from_pool (struct mem_pool *mem_pool) + retval->magic = GF_MEM_HEADER_MAGIC; + retval->next = NULL; + retval->pool_list = pool_list; +- retval->power_of_two = mem_pool->power_of_two; ++ retval->power_of_two = mem_pool->pool->power_of_two; + } + + return retval; +@@ -821,9 +828,10 @@ void * + mem_get (struct mem_pool *mem_pool) + { + #if defined(GF_DISABLE_MEMPOOL) +- return GF_CALLOC (1, AVAILABLE_SIZE (mem_pool->power_of_two), ++ return GF_CALLOC (1, AVAILABLE_SIZE (mem_pool->pool->power_of_two), + gf_common_mt_mem_pool); + #else ++ per_thread_pool_list_t *pool_list; + pooled_obj_hdr_t *retval; + + if (!mem_pool) { +@@ -832,11 +840,22 @@ mem_get (struct mem_pool *mem_pool) + return NULL; + } + ++ pool_list = mem_get_pool_list (); ++ if (!pool_list || pool_list->poison) { ++ return NULL; ++ } ++ + retval = mem_get_from_pool (mem_pool); ++ + if (!retval) { + return NULL; + } + ++ retval->magic = GF_MEM_HEADER_MAGIC; ++ retval->pool = mem_pool; ++ retval->pool_list = pool_list; ++ retval->power_of_two = mem_pool->pool->power_of_two; ++ + return retval + 1; + #endif /* GF_DISABLE_MEMPOOL */ + } +@@ -886,14 +905,12 @@ mem_put (void *ptr) + void + mem_pool_destroy (struct mem_pool *pool) + { +- if (!pool) +- return; ++ GF_FREE (pool); + + /* +- * Pools are now permanent, so this does nothing. Yes, this means we +- * can keep allocating from a pool after calling mem_destroy on it, but +- * that's kind of OK. All of the objects *in* the pool will eventually +- * be freed via the pool-sweeper thread, and this way we don't have to +- * add a lot of reference-counting complexity. ++ * Pools are now permanent, so the mem_pool->pool is kept around. All ++ * of the objects *in* the pool will eventually be freed via the ++ * pool-sweeper thread, and this way we don't have to add a lot of ++ * reference-counting complexity. + */ + } +diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h +index dfe1f9a..057d957 100644 +--- a/libglusterfs/src/mem-pool.h ++++ b/libglusterfs/src/mem-pool.h +@@ -204,18 +204,31 @@ out: + return dup_mem; + } + ++/* kind of 'header' for the actual mem_pool_shared structure, this might make ++ * it possible to dump some more details in a statedump */ ++struct mem_pool { ++ unsigned long sizeof_type; ++ unsigned long count; ++ char *name; ++ ++ struct mem_pool_shared *pool; ++}; ++ + typedef struct pooled_obj_hdr { + unsigned long magic; + struct pooled_obj_hdr *next; + struct per_thread_pool_list *pool_list; + unsigned int power_of_two; ++ ++ /* track the pool that was used to request this object */ ++ struct mem_pool *pool; + } pooled_obj_hdr_t; + + #define AVAILABLE_SIZE(p2) ((1 << (p2)) - sizeof(pooled_obj_hdr_t)) + + typedef struct per_thread_pool { +- /* This never changes, so doesn't need a lock. */ +- struct mem_pool *parent; ++ /* the pool that was used to request this allocation */ ++ struct mem_pool_shared *parent; + /* Everything else is protected by our own lock. */ + pooled_obj_hdr_t *hot_list; + pooled_obj_hdr_t *cold_list; +@@ -243,7 +256,8 @@ typedef struct per_thread_pool_list { + per_thread_pool_t pools[1]; + } per_thread_pool_list_t; + +-struct mem_pool { ++/* actual pool structure, shared between different mem_pools */ ++struct mem_pool_shared { + unsigned int power_of_two; + /* + * Updates to these are *not* protected by a global lock, so races +diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h +index 85cb5d2..64d0e90 100644 +--- a/libglusterfs/src/mem-types.h ++++ b/libglusterfs/src/mem-types.h +@@ -61,9 +61,7 @@ enum gf_common_mem_types_ { + gf_common_mt_char, + gf_common_mt_rbthash_table_t, + gf_common_mt_rbthash_bucket, +-#if defined(GF_DISABLE_MEMPOOL) + gf_common_mt_mem_pool, +-#endif + gf_common_mt_long, + gf_common_mt_rpcsvc_auth_list, + gf_common_mt_rpcsvc_t, +-- +1.8.3.1 + diff --git a/0488-cluster-afr-Allow-lookup-on-root-if-it-is-from-ADD_R.patch b/0488-cluster-afr-Allow-lookup-on-root-if-it-is-from-ADD_R.patch new file mode 100644 index 0000000..9e8c6a3 --- /dev/null +++ b/0488-cluster-afr-Allow-lookup-on-root-if-it-is-from-ADD_R.patch @@ -0,0 +1,459 @@ +From f398b6b9705f1b75d17d965ffcd72157d5be3daf Mon Sep 17 00:00:00 2001 +From: karthik-us +Date: Tue, 18 Dec 2018 16:04:42 +0530 +Subject: [PATCH 488/493] cluster/afr: Allow lookup on root if it is from + ADD_REPLICA_MOUNT + +Problem: When trying to convert a plain distribute volume to replica-3 +or arbiter type it is failing with ENOTCONN error as the lookup on +the root will fail as there is no quorum. + +Fix: Allow lookup on root if it is coming from the ADD_REPLICA_MOUNT +which is used while adding bricks to a volume. It will try to set the +pending xattrs for the newly added bricks to allow the heal to happen +in the right direction and avoid data loss scenarios. + +Note: This fix will solve the problem of type conversion only in the +case where the volume was mounted at least once. The conversion of +non mounted volumes will still fail since the dht selfheal tries to +set the directory layout will fail as they do that with the PID +GF_CLIENT_PID_NO_ROOT_SQUASH set in the frame->root. + +Backport of: https://review.gluster.org/#/c/glusterfs/+/21791/ + +Change-Id: Ie31d429dfebbfb0f60610c9c5739595c54b19c46 +BUG: 1645480 +Signed-off-by: karthik-us +Reviewed-on: https://code.engineering.redhat.com/gerrit/158932 +Tested-by: RHGS Build Bot +Reviewed-by: Ravishankar Narayanankutty +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + libglusterfs/src/common-utils.h | 3 +- + ...g-1655854-support-dist-to-rep3-arb-conversion.t | 95 ++++++++++++++++++++++ + xlators/cluster/afr/src/afr-common.c | 80 +++++++++++++----- + xlators/cluster/afr/src/afr-inode-write.c | 2 +- + xlators/cluster/afr/src/afr-read-txn.c | 3 +- + xlators/cluster/afr/src/afr-transaction.c | 11 ++- + xlators/cluster/afr/src/afr-transaction.h | 3 +- + xlators/cluster/afr/src/afr.c | 2 +- + xlators/cluster/afr/src/afr.h | 4 + + xlators/mgmt/glusterd/src/glusterd-utils.c | 2 +- + 10 files changed, 175 insertions(+), 30 deletions(-) + create mode 100644 tests/bugs/replicate/bug-1655854-support-dist-to-rep3-arb-conversion.t + +diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h +index c804ed5..50c1f9a 100644 +--- a/libglusterfs/src/common-utils.h ++++ b/libglusterfs/src/common-utils.h +@@ -162,7 +162,8 @@ enum _gf_special_pid + GF_CLIENT_PID_BITD = -8, + GF_CLIENT_PID_SCRUB = -9, + GF_CLIENT_PID_TIER_DEFRAG = -10, +- GF_SERVER_PID_TRASH = -11 ++ GF_SERVER_PID_TRASH = -11, ++ GF_CLIENT_PID_ADD_REPLICA_MOUNT = -12 + }; + + enum _gf_xlator_ipc_targets { +diff --git a/tests/bugs/replicate/bug-1655854-support-dist-to-rep3-arb-conversion.t b/tests/bugs/replicate/bug-1655854-support-dist-to-rep3-arb-conversion.t +new file mode 100644 +index 0000000..783016d +--- /dev/null ++++ b/tests/bugs/replicate/bug-1655854-support-dist-to-rep3-arb-conversion.t +@@ -0,0 +1,95 @@ ++#!/bin/bash ++. $(dirname $0)/../../include.rc ++. $(dirname $0)/../../volume.rc ++cleanup; ++ ++TEST glusterd ++TEST pidof glusterd ++ ++# Conversion from 2x1 to 2x3 ++ ++TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1} ++EXPECT 'Created' volinfo_field $V0 'Status'; ++TEST $CLI volume start $V0 ++EXPECT 'Started' volinfo_field $V0 'Status'; ++ ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}0 ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}1 ++ ++TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0; ++TEST mkdir $M0/dir ++TEST dd if=/dev/urandom of=$M0/dir/file bs=100K count=5 ++file_md5sum=$(md5sum $M0/dir/file | awk '{print $1}') ++ ++TEST $CLI volume add-brick $V0 replica 3 $H0:$B0/${V0}{2..5} ++ ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}2 ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}3 ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}4 ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}5 ++ ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" glustershd_up_status ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0 ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1 ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 2 ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 3 ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 4 ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 5 ++ ++# Trigger heal and wait for for it to complete ++TEST $CLI volume heal $V0 ++EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V0 ++ ++# Check whether the directory & file are healed to the newly added bricks ++TEST ls $B0/${V0}2/dir ++TEST ls $B0/${V0}3/dir ++TEST ls $B0/${V0}4/dir ++TEST ls $B0/${V0}5/dir ++ ++TEST [ $file_md5sum == $(md5sum $B0/${V0}4/dir/file | awk '{print $1}') ] ++TEST [ $file_md5sum == $(md5sum $B0/${V0}5/dir/file | awk '{print $1}') ] ++ ++ ++# Conversion from 2x1 to 2x(2+1) ++ ++TEST $CLI volume create $V1 $H0:$B0/${V1}{0,1} ++EXPECT 'Created' volinfo_field $V1 'Status'; ++TEST $CLI volume start $V1 ++EXPECT 'Started' volinfo_field $V1 'Status'; ++ ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V1 $H0 $B0/${V1}0 ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V1 $H0 $B0/${V1}1 ++ ++TEST $GFS --volfile-id=$V1 --volfile-server=$H0 $M1; ++TEST mkdir $M1/dir ++TEST dd if=/dev/urandom of=$M1/dir/file bs=100K count=5 ++file_md5sum=$(md5sum $M1/dir/file | awk '{print $1}') ++ ++TEST $CLI volume add-brick $V1 replica 3 arbiter 1 $H0:$B0/${V1}{2..5} ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V1 $H0 $B0/${V1}2 ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V1 $H0 $B0/${V1}3 ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V1 $H0 $B0/${V1}4 ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V1 $H0 $B0/${V1}5 ++ ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" glustershd_up_status ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V1 0 ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V1 1 ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V1 2 ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V1 3 ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V1 4 ++EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V1 5 ++ ++# Trigger heal and wait for for it to complete ++TEST $CLI volume heal $V1 ++EXPECT_WITHIN $HEAL_TIMEOUT "^0$" get_pending_heal_count $V1 ++ ++# Check whether the directory & file are healed to the newly added bricks ++TEST ls $B0/${V1}2/dir ++TEST ls $B0/${V1}3/dir ++TEST ls $B0/${V1}4/dir ++TEST ls $B0/${V1}5/dir ++ ++EXPECT "0" stat -c %s $B0/${V1}5/dir/file ++TEST [ $file_md5sum == $(md5sum $B0/${V1}4/dir/file | awk '{print $1}') ] ++ ++cleanup; +diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c +index 231de9d..322dfbe 100644 +--- a/xlators/cluster/afr/src/afr-common.c ++++ b/xlators/cluster/afr/src/afr-common.c +@@ -2265,7 +2265,7 @@ afr_attempt_readsubvol_set (call_frame_t *frame, xlator_t *this, + } else if (!priv->quorum_count) { + *read_subvol = afr_first_up_child (frame, this); + } else if (priv->quorum_count && +- afr_has_quorum (data_readable, this)) { ++ afr_has_quorum (data_readable, this, NULL)) { + /* read_subvol is guaranteed to be valid if we hit this path. */ + *read_subvol = afr_first_up_child (frame, this); + } else { +@@ -2405,7 +2405,7 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this) + read_subvol = -1; + memset (readable, 0, sizeof (*readable) * priv->child_count); + if (can_interpret) { +- if (!afr_has_quorum (success_replies, this)) ++ if (!afr_has_quorum (success_replies, this, NULL)) + goto cant_interpret; + /* It is safe to call afr_replies_interpret() because we have + a response from all the UP subvolumes and all of them resolved +@@ -2887,7 +2887,7 @@ afr_lookup_entry_heal (call_frame_t *frame, xlator_t *this) + if (name_state_mismatch) { + if (!priv->quorum_count) + goto name_heal; +- if (!afr_has_quorum (success, this)) ++ if (!afr_has_quorum (success, this, NULL)) + goto name_heal; + if (op_errno) + goto name_heal; +@@ -2979,7 +2979,6 @@ afr_discover_done (call_frame_t *frame, xlator_t *this) + afr_private_t *priv = NULL; + afr_local_t *local = NULL; + int i = -1; +- int op_errno = 0; + int read_subvol = -1; + unsigned char *data_readable = NULL; + unsigned char *success_replies = NULL; +@@ -2998,15 +2997,13 @@ afr_discover_done (call_frame_t *frame, xlator_t *this) + } + } + +- op_errno = afr_final_errno (frame->local, this->private); +- + if (local->op_ret < 0) { +- AFR_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, +- NULL, NULL); +- return; +- } ++ local->op_ret = -1; ++ local->op_errno = afr_final_errno (frame->local, this->private); ++ goto error; ++ } + +- if (!afr_has_quorum (success_replies, this)) ++ if (!afr_has_quorum (success_replies, this, frame)) + goto unwind; + + afr_replies_interpret (frame, this, local->inode, NULL); +@@ -3017,11 +3014,8 @@ afr_discover_done (call_frame_t *frame, xlator_t *this) + unwind: + afr_attempt_readsubvol_set (frame, this, success_replies, data_readable, + &read_subvol); +- if (read_subvol == -1) { +- AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, +- NULL, NULL, NULL, NULL); +- return; +- } ++ if (read_subvol == -1) ++ goto error; + + if (AFR_IS_ARBITER_BRICK (priv, read_subvol) && local->op_ret == 0) { + local->op_ret = -1; +@@ -3034,6 +3028,11 @@ unwind: + local->inode, &local->replies[read_subvol].poststat, + local->replies[read_subvol].xdata, + &local->replies[read_subvol].postparent); ++ return; ++ ++error: ++ AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno, NULL, ++ NULL, NULL, NULL); + } + + +@@ -3977,7 +3976,8 @@ afr_fop_lock_done (call_frame_t *frame, xlator_t *this) + + if (afr_is_conflicting_lock_present (local->op_ret, local->op_errno)) { + afr_unlock_locks_and_proceed (frame, this, lock_count); +- } else if (priv->quorum_count && !afr_has_quorum (success, this)) { ++ } else if (priv->quorum_count && ++ !afr_has_quorum (success, this, NULL)) { + local->fop_lock_state = AFR_FOP_LOCK_QUORUM_FAILED; + local->op_ret = -1; + local->op_errno = afr_final_errno (local, priv); +@@ -4485,7 +4485,7 @@ afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + &local->cont.lk.user_flock, + local->xdata_req); + } else if (priv->quorum_count && +- !afr_has_quorum (local->cont.lk.locked_nodes, this)) { ++ !afr_has_quorum (local->cont.lk.locked_nodes, this, NULL)) { + local->op_ret = -1; + local->op_errno = afr_final_errno (local, priv); + +@@ -5199,7 +5199,7 @@ afr_notify (xlator_t *this, int32_t event, + } + + had_quorum = priv->quorum_count && afr_has_quorum (priv->child_up, +- this); ++ this, NULL); + if (priv->halo_enabled) { + halo_max_latency_msec = afr_get_halo_latency (this); + +@@ -5328,7 +5328,7 @@ afr_notify (xlator_t *this, int32_t event, + UNLOCK (&priv->lock); + + if (priv->quorum_count) { +- has_quorum = afr_has_quorum (priv->child_up, this); ++ has_quorum = afr_has_quorum (priv->child_up, this, NULL); + if (!had_quorum && has_quorum) { + gf_msg (this->name, GF_LOG_INFO, 0, AFR_MSG_QUORUM_MET, + "Client-quorum is met"); +@@ -6543,3 +6543,43 @@ afr_set_inode_local (xlator_t *this, afr_local_t *local, inode_t *inode) + } + return ret; + } ++ ++gf_boolean_t ++afr_is_add_replica_mount_lookup_on_root (call_frame_t *frame) ++{ ++ afr_local_t *local = NULL; ++ ++ local = frame->local; ++ ++ if (frame->root->pid != GF_CLIENT_PID_ADD_REPLICA_MOUNT) ++ return _gf_false; ++ ++ if (local->op != GF_FOP_LOOKUP) ++ /* TODO:If the replica count is being increased on a plain ++ * distribute volume that was never mounted, we need to allow ++ * setxattr on '/' with GF_CLIENT_PID_NO_ROOT_SQUASH to ++ * accomodate for DHT layout setting */ ++ return _gf_false; ++ ++ if (local->inode == NULL) ++ return _gf_false; ++ ++ if (!__is_root_gfid (local->inode->gfid)) ++ return _gf_false; ++ ++ return _gf_true; ++} ++ ++gf_boolean_t ++afr_lookup_has_quorum (call_frame_t *frame, xlator_t *this, ++ unsigned char *subvols) ++{ ++ afr_private_t *priv = this->private; ++ ++ if (frame && afr_is_add_replica_mount_lookup_on_root (frame)) { ++ if (AFR_COUNT (subvols, priv->child_count) > 0) ++ return _gf_true; ++ } ++ ++ return _gf_false; ++} +diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c +index 8b1dcfd..ea4755a 100644 +--- a/xlators/cluster/afr/src/afr-inode-write.c ++++ b/xlators/cluster/afr/src/afr-inode-write.c +@@ -1539,7 +1539,7 @@ afr_handle_empty_brick (xlator_t *this, call_frame_t *frame, loc_t *loc, + if (ret && ab_ret) + goto out; + +- if (frame->root->pid != GF_CLIENT_PID_SELF_HEALD) { ++ if (frame->root->pid != GF_CLIENT_PID_ADD_REPLICA_MOUNT) { + gf_msg (this->name, GF_LOG_ERROR, EPERM, + afr_get_msg_id (op_type), + "'%s' is an internal extended attribute.", +diff --git a/xlators/cluster/afr/src/afr-read-txn.c b/xlators/cluster/afr/src/afr-read-txn.c +index f6c491b..ec322ae 100644 +--- a/xlators/cluster/afr/src/afr-read-txn.c ++++ b/xlators/cluster/afr/src/afr-read-txn.c +@@ -193,7 +193,8 @@ afr_read_txn (call_frame_t *frame, xlator_t *this, inode_t *inode, + local->inode = inode_ref (inode); + local->is_read_txn = _gf_true; + +- if (priv->quorum_count && !afr_has_quorum (local->child_up, this)) { ++ if (priv->quorum_count && ++ !afr_has_quorum (local->child_up, this, NULL)) { + local->op_ret = -1; + local->op_errno = ENOTCONN; + read_subvol = -1; +diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c +index 0a67a83..0e58e02 100644 +--- a/xlators/cluster/afr/src/afr-transaction.c ++++ b/xlators/cluster/afr/src/afr-transaction.c +@@ -160,7 +160,7 @@ afr_changelog_has_quorum (afr_local_t *local, xlator_t *this) + } + } + +- if (afr_has_quorum (success_children, this)) { ++ if (afr_has_quorum (success_children, this, NULL)) { + return _gf_true; + } + +@@ -690,7 +690,7 @@ afr_handle_symmetric_errors (call_frame_t *frame, xlator_t *this) + } + + gf_boolean_t +-afr_has_quorum (unsigned char *subvols, xlator_t *this) ++afr_has_quorum (unsigned char *subvols, xlator_t *this, call_frame_t *frame) + { + unsigned int quorum_count = 0; + afr_private_t *priv = NULL; +@@ -699,6 +699,9 @@ afr_has_quorum (unsigned char *subvols, xlator_t *this) + priv = this->private; + up_children_count = AFR_COUNT (subvols, priv->child_count); + ++ if (afr_lookup_has_quorum (frame, this, subvols)) ++ return _gf_true; ++ + if (priv->quorum_count == AFR_QUORUM_AUTO) { + /* + * Special case for auto-quorum with an even number of nodes. +@@ -753,7 +756,7 @@ afr_has_fop_quorum (call_frame_t *frame) + + locked_nodes = afr_locked_nodes_get (local->transaction.type, + &local->internal_lock); +- return afr_has_quorum (locked_nodes, this); ++ return afr_has_quorum (locked_nodes, this, NULL); + } + + static gf_boolean_t +@@ -771,7 +774,7 @@ afr_has_fop_cbk_quorum (call_frame_t *frame) + success[i] = 1; + } + +- return afr_has_quorum (success, this); ++ return afr_has_quorum (success, this, NULL); + } + + gf_boolean_t +diff --git a/xlators/cluster/afr/src/afr-transaction.h b/xlators/cluster/afr/src/afr-transaction.h +index a27e9a3..1c42c66 100644 +--- a/xlators/cluster/afr/src/afr-transaction.h ++++ b/xlators/cluster/afr/src/afr-transaction.h +@@ -38,7 +38,8 @@ int afr_read_txn (call_frame_t *frame, xlator_t *this, inode_t *inode, + int afr_read_txn_continue (call_frame_t *frame, xlator_t *this, int subvol); + + call_frame_t *afr_transaction_detach_fop_frame (call_frame_t *frame); +-gf_boolean_t afr_has_quorum (unsigned char *subvols, xlator_t *this); ++gf_boolean_t afr_has_quorum (unsigned char *subvols, xlator_t *this, ++ call_frame_t *frame); + gf_boolean_t afr_needs_changelog_update (afr_local_t *local); + void afr_zero_fill_stat (afr_local_t *local); + +diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c +index 1b738c0..d5347e9 100644 +--- a/xlators/cluster/afr/src/afr.c ++++ b/xlators/cluster/afr/src/afr.c +@@ -244,7 +244,7 @@ reconfigure (xlator_t *this, dict_t *options) + GF_OPTION_RECONF ("quorum-count", priv->quorum_count, options, + uint32, out); + fix_quorum_options (this, priv, qtype, options); +- if (priv->quorum_count && !afr_has_quorum (priv->child_up, this)) ++ if (priv->quorum_count && !afr_has_quorum (priv->child_up, this, NULL)) + gf_msg (this->name, GF_LOG_WARNING, 0, AFR_MSG_QUORUM_FAIL, + "Client-quorum is not met"); + +diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h +index 7010e9b..febc509 100644 +--- a/xlators/cluster/afr/src/afr.h ++++ b/xlators/cluster/afr/src/afr.h +@@ -1227,4 +1227,8 @@ afr_is_symmetric_error (call_frame_t *frame, xlator_t *this); + + gf_boolean_t + afr_is_pending_set (xlator_t *this, dict_t *xdata, int type); ++ ++gf_boolean_t ++afr_lookup_has_quorum (call_frame_t *frame, xlator_t *this, ++ unsigned char *subvols); + #endif /* __AFR_H__ */ +diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c +index 2290343..6468ecb 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-utils.c +@@ -13788,7 +13788,7 @@ glusterd_handle_replicate_brick_ops (glusterd_volinfo_t *volinfo, + goto out; + } + +- ret = gf_asprintf (&pid, "%d", GF_CLIENT_PID_SELF_HEALD); ++ ret = gf_asprintf (&pid, "%d", GF_CLIENT_PID_ADD_REPLICA_MOUNT); + if (ret < 0) + goto out; + +-- +1.8.3.1 + diff --git a/0489-cluster-afr-Do-not-update-read_subvol-in-inode_ctx-a.patch b/0489-cluster-afr-Do-not-update-read_subvol-in-inode_ctx-a.patch new file mode 100644 index 0000000..b2b7cb6 --- /dev/null +++ b/0489-cluster-afr-Do-not-update-read_subvol-in-inode_ctx-a.patch @@ -0,0 +1,91 @@ +From adeeec1fbe7241d18903ae3830a1fabb1061be21 Mon Sep 17 00:00:00 2001 +From: karthik-us +Date: Mon, 17 Dec 2018 14:28:07 +0530 +Subject: [PATCH 489/493] cluster/afr: Do not update read_subvol in inode_ctx + after rename/link fop + +Since rename/link fops on a file will not change any data in it, it should +not update the read_subvol values in the inode_ctx, which interprets the +data & metadata readable subvols for that file. The old read_subvol values +should be retained even after the rename/link operations. + +Backport of: https://review.gluster.org/#/c/glusterfs/+/21841 + +Change-Id: I22787938b3f8295a48162ab4f498e4010d66a1ab +BUG: 1645480 +Signed-off-by: karthik-us +Reviewed-on: https://code.engineering.redhat.com/gerrit/158803 +Tested-by: RHGS Build Bot +Tested-by: Ravishankar Narayanankutty +Reviewed-by: Ravishankar Narayanankutty +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + ...7783-do-not-update-read-subvol-on-rename-link.t | 40 ++++++++++++++++++++++ + xlators/cluster/afr/src/afr-dir-write.c | 4 ++- + 2 files changed, 43 insertions(+), 1 deletion(-) + create mode 100644 tests/bugs/replicate/bug-1657783-do-not-update-read-subvol-on-rename-link.t + +diff --git a/tests/bugs/replicate/bug-1657783-do-not-update-read-subvol-on-rename-link.t b/tests/bugs/replicate/bug-1657783-do-not-update-read-subvol-on-rename-link.t +new file mode 100644 +index 0000000..b180f0e +--- /dev/null ++++ b/tests/bugs/replicate/bug-1657783-do-not-update-read-subvol-on-rename-link.t +@@ -0,0 +1,40 @@ ++#!/bin/bash ++. $(dirname $0)/../../include.rc ++. $(dirname $0)/../../volume.rc ++cleanup; ++ ++TEST glusterd ++TEST pidof glusterd ++TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0..2} ++TEST $CLI volume set $V0 self-heal-daemon off ++TEST $CLI volume set $V0 cluster.data-self-heal off ++TEST $CLI volume set $V0 cluster.metadata-self-heal off ++TEST $CLI volume set $V0 cluster.entry-self-heal off ++TEST $CLI volume set $V0 performance.write-behind off ++ ++TEST $CLI volume start $V0 ++TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0; ++TEST mkdir $M0/dir ++TEST "echo abc > $M0/file1" ++TEST "echo uvw > $M0/file2" ++ ++TEST kill_brick $V0 $H0 $B0/${V0}0 ++TEST "echo def > $M0/file1" ++TEST "echo xyz > $M0/file2" ++ ++TEST $CLI volume start $V0 force ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}0 ++EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0 ++ ++TEST kill_brick $V0 $H0 $B0/${V0}1 ++ ++# Rename file1 and read it. Read should be served from the 3rd brick ++TEST mv $M0/file1 $M0/file3 ++EXPECT "def" cat $M0/file3 ++ ++# Create a link to file2 and read it. Read should be served from the 3rd brick ++TEST ln $M0/file2 $M0/dir/file4 ++EXPECT "xyz" cat $M0/dir/file4 ++EXPECT "xyz" cat $M0/file2 ++ ++cleanup +diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c +index 75889de..c508034 100644 +--- a/xlators/cluster/afr/src/afr-dir-write.c ++++ b/xlators/cluster/afr/src/afr-dir-write.c +@@ -99,7 +99,9 @@ __afr_dir_write_finalize (call_frame_t *frame, xlator_t *this) + } + + if (local->inode) { +- afr_replies_interpret (frame, this, local->inode, NULL); ++ if (local->op != GF_FOP_RENAME && local->op != GF_FOP_LINK) ++ afr_replies_interpret (frame, this, local->inode, NULL); ++ + inode_read_subvol = afr_data_subvol_get (local->inode, this, + NULL, NULL, NULL, &args); + } +-- +1.8.3.1 + diff --git a/0490-glusterd-migrating-rebalance-commands-to-mgmt_v3-fra.patch b/0490-glusterd-migrating-rebalance-commands-to-mgmt_v3-fra.patch new file mode 100644 index 0000000..1ce1b73 --- /dev/null +++ b/0490-glusterd-migrating-rebalance-commands-to-mgmt_v3-fra.patch @@ -0,0 +1,921 @@ +From 783c36e573a9c937422e63af038bb35648483b9e Mon Sep 17 00:00:00 2001 +From: Sanju Rakonde +Date: Fri, 30 Nov 2018 16:16:55 +0530 +Subject: [PATCH 490/493] glusterd: migrating rebalance commands to mgmt_v3 + framework + +Current rebalance commands use the op_state machine framework. +Porting it to use the mgmt_v3 framework. + +> Change-Id: I6faf4a6335c2e2f3d54bbde79908a7749e4613e7 +> fixes: bz#1655827 +> Signed-off-by: Sanju Rakonde + +upstream patch: https://review.gluster.org/#/c/glusterfs/+/21762/ + +Change-Id: I6faf4a6335c2e2f3d54bbde79908a7749e4613e7 +BUG: 1652466 +Signed-off-by: Sanju Rakonde +Reviewed-on: https://code.engineering.redhat.com/gerrit/158917 +Reviewed-by: Atin Mukherjee +Tested-by: RHGS Build Bot +--- + libglusterfs/src/globals.h | 2 + + xlators/mgmt/glusterd/src/glusterd-handler.c | 4 +- + xlators/mgmt/glusterd/src/glusterd-mgmt.c | 128 ++++++- + xlators/mgmt/glusterd/src/glusterd-mgmt.h | 5 +- + xlators/mgmt/glusterd/src/glusterd-op-sm.h | 3 + + xlators/mgmt/glusterd/src/glusterd-rebalance.c | 495 ++++++++++++++++++++++++- + xlators/mgmt/glusterd/src/glusterd-syncop.c | 9 + + xlators/mgmt/glusterd/src/glusterd-utils.c | 4 +- + xlators/mgmt/glusterd/src/glusterd.h | 9 + + 9 files changed, 637 insertions(+), 22 deletions(-) + +diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h +index 343263c..5e3b180 100644 +--- a/libglusterfs/src/globals.h ++++ b/libglusterfs/src/globals.h +@@ -111,6 +111,8 @@ + + #define GD_OP_VERSION_3_13_3 31303 /* Op-version for GlusterFS 3.13.3 */ + ++#define GD_OP_VERSION_6_0 60000 /* Op-version for GlusterFS 6.0 */ ++ + /* Downstream only change */ + #define GD_OP_VERSION_3_11_2 31102 /* Op-version for RHGS 3.3.1-async */ + #define GD_OP_VERSION_3_13_3 31303 /* Op-version for RHGS-3.4-Batch Update-1*/ +diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c +index d40de89..d8e3335 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-handler.c ++++ b/xlators/mgmt/glusterd/src/glusterd-handler.c +@@ -3120,7 +3120,9 @@ __glusterd_handle_cli_profile_volume (rpcsvc_request_t *req) + glusterd_friend_sm(); + glusterd_op_sm(); + } else { +- ret = glusterd_mgmt_v3_initiate_profile_phases(req, cli_op, dict); ++ ret = glusterd_mgmt_v3_initiate_all_phases_with_brickop_phase(req, ++ cli_op, ++ dict); + } + + out: +diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c +index d98c6bc..ef8a2d9 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c ++++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c +@@ -224,6 +224,16 @@ gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict, + } + break; + ++ case GD_OP_REBALANCE: ++ case GD_OP_DEFRAG_BRICK_VOLUME: ++ ret = glusterd_mgmt_v3_op_stage_rebalance(dict, op_errstr); ++ if (ret) { ++ gf_log(this->name, GF_LOG_WARNING, ++ "Rebalance Prevalidate Failed"); ++ goto out; ++ } ++ break; ++ + case GD_OP_MAX_OPVERSION: + ret = 0; + break; +@@ -264,6 +274,8 @@ gd_mgmt_v3_brick_op_fn (glusterd_op_t op, dict_t *dict, + break; + } + case GD_OP_PROFILE_VOLUME: ++ case GD_OP_REBALANCE: ++ case GD_OP_DEFRAG_BRICK_VOLUME: + { + ret = gd_brick_op_phase(op, rsp_dict, dict, op_errstr); + if (ret) { +@@ -438,6 +450,19 @@ gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict, + } + break; + } ++ case GD_OP_REBALANCE: ++ case GD_OP_DEFRAG_BRICK_VOLUME: ++ { ++ ret = glusterd_mgmt_v3_op_rebalance(dict, op_errstr, ++ rsp_dict); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_ERROR, 0, ++ GD_MSG_COMMIT_OP_FAIL, ++ "Rebalance Commit Failed"); ++ goto out; ++ } ++ break; ++ } + + default: + break; +@@ -880,6 +905,8 @@ glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op, + case GD_OP_TIER_START_STOP: + case GD_OP_REMOVE_TIER_BRICK: + case GD_OP_PROFILE_VOLUME: ++ case GD_OP_DEFRAG_BRICK_VOLUME: ++ case GD_OP_REBALANCE: + break; + case GD_OP_MAX_OPVERSION: + break; +@@ -1197,6 +1224,7 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict, + break; + case GD_OP_START_VOLUME: + case GD_OP_ADD_BRICK: ++ case GD_OP_DEFRAG_BRICK_VOLUME: + case GD_OP_REPLACE_BRICK: + case GD_OP_RESET_BRICK: + case GD_OP_ADD_TIER_BRICK: +@@ -1221,6 +1249,30 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict, + dict_copy (dict, req_dict); + } + break; ++ ++ case GD_OP_REBALANCE: { ++ if (gd_set_commit_hash(dict) != 0) { ++ ret = -1; ++ goto out; ++ } ++ ret = dict_get_str (dict, "volname", &volname); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_CRITICAL, errno, ++ GD_MSG_DICT_GET_FAILED, ++ "volname is not present in " ++ "operation ctx"); ++ goto out; ++ } ++ ++ if (strcasecmp(volname, "all")) { ++ ret = glusterd_dict_set_volid(dict, volname, op_errstr); ++ if (ret) ++ goto out; ++ } ++ dict_copy(dict, req_dict); ++ } ++ break; ++ + case GD_OP_TIER_START_STOP: + case GD_OP_REMOVE_TIER_BRICK: + case GD_OP_DETACH_TIER_STATUS: +@@ -1247,6 +1299,7 @@ gd_mgmt_v3_brick_op_cbk_fn (struct rpc_req *req, struct iovec *iov, + call_frame_t *frame = NULL; + int32_t op_ret = -1; + int32_t op_errno = -1; ++ dict_t *rsp_dict = NULL; + xlator_t *this = NULL; + uuid_t *peerid = NULL; + +@@ -1278,10 +1331,45 @@ gd_mgmt_v3_brick_op_cbk_fn (struct rpc_req *req, struct iovec *iov, + if (ret < 0) + goto out; + ++ if (rsp.dict.dict_len) { ++ /* Unserialize the dictionary */ ++ rsp_dict = dict_new (); ++ ++ ret = dict_unserialize (rsp.dict.dict_val, ++ rsp.dict.dict_len, ++ &rsp_dict); ++ if (ret < 0) { ++ free (rsp.dict.dict_val); ++ goto out; ++ } else { ++ rsp_dict->extra_stdfree = rsp.dict.dict_val; ++ } ++ } ++ + gf_uuid_copy (args->uuid, rsp.uuid); ++ pthread_mutex_lock (&args->lock_dict); ++ { ++ if (rsp.op == GD_OP_DEFRAG_BRICK_VOLUME) ++ ret = glusterd_syncop_aggr_rsp_dict (rsp.op, args->dict, ++ rsp_dict); ++ } ++ pthread_mutex_unlock (&args->lock_dict); + +- op_ret = rsp.op_ret; +- op_errno = rsp.op_errno; ++ if (ret) { ++ gf_msg (this->name, GF_LOG_ERROR, 0, ++ GD_MSG_RESP_AGGR_FAIL, "%s", ++ "Failed to aggregate response from " ++ " node/brick"); ++ if (!rsp.op_ret) ++ op_ret = ret; ++ else { ++ op_ret = rsp.op_ret; ++ op_errno = rsp.op_errno; ++ } ++ } else { ++ op_ret = rsp.op_ret; ++ op_errno = rsp.op_errno; ++ } + + out: + gd_mgmt_v3_collate_errors (args, op_ret, op_errno, rsp.op_errstr, +@@ -1353,11 +1441,12 @@ out: + } + + int +-glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *rsp_dict, dict_t *req_dict, ++glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict, + char **op_errstr, uint32_t txn_generation) + { + int32_t ret = -1; + int32_t peer_cnt = 0; ++ dict_t *rsp_dict = NULL; + glusterd_peerinfo_t *peerinfo = NULL; + struct syncargs args = {0}; + uuid_t peer_uuid = {0}; +@@ -1372,6 +1461,13 @@ glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *rsp_dict, dict_t *req_dict, + GF_ASSERT (req_dict); + GF_ASSERT (op_errstr); + ++ rsp_dict = dict_new(); ++ if (!rsp_dict) { ++ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL, ++ "Failed to create response dictionary"); ++ goto out; ++ } ++ + /* Perform brick op on local node */ + ret = gd_mgmt_v3_brick_op_fn (op, req_dict, op_errstr, + rsp_dict); +@@ -1395,9 +1491,21 @@ glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *rsp_dict, dict_t *req_dict, + } + goto out; + } ++ if (op == GD_OP_DEFRAG_BRICK_VOLUME || op == GD_OP_PROFILE_VOLUME) { ++ ret = glusterd_syncop_aggr_rsp_dict(op, op_ctx, rsp_dict); ++ if (ret) { ++ gf_log(this->name, GF_LOG_ERROR, "%s", ++ "Failed to aggregate response from " ++ " node/brick"); ++ goto out; ++ } ++ } ++ ++ dict_unref(rsp_dict); ++ rsp_dict = NULL; + + /* Sending brick op req to other nodes in the cluster */ +- gd_syncargs_init (&args, rsp_dict); ++ gd_syncargs_init (&args, op_ctx); + synctask_barrier_init((&args)); + peer_cnt = 0; + +@@ -1616,6 +1724,13 @@ glusterd_mgmt_v3_commit (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict, + GF_ASSERT (op_errstr); + GF_VALIDATE_OR_GOTO (this->name, op_errno, out); + ++ if (op == GD_OP_REBALANCE || op == GD_OP_DEFRAG_BRICK_VOLUME) { ++ ret = glusterd_set_rebalance_id_in_rsp_dict(req_dict, op_ctx); ++ if (ret) { ++ gf_log(this->name, GF_LOG_WARNING, ++ "Failed to set rebalance id in dict."); ++ } ++ } + rsp_dict = dict_new (); + if (!rsp_dict) { + gf_msg (this->name, GF_LOG_ERROR, 0, +@@ -2140,8 +2255,9 @@ out: + } + + int32_t +-glusterd_mgmt_v3_initiate_profile_phases (rpcsvc_request_t *req, +- glusterd_op_t op, dict_t *dict) ++glusterd_mgmt_v3_initiate_all_phases_with_brickop_phase (rpcsvc_request_t *req, ++ glusterd_op_t op, ++ dict_t *dict) + { + int32_t ret = -1; + int32_t op_ret = -1; +diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-mgmt.h +index eff070d..ef0fe10 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.h ++++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.h +@@ -37,8 +37,9 @@ glusterd_mgmt_v3_initiate_all_phases (rpcsvc_request_t *req, glusterd_op_t op, + dict_t *dict); + + int32_t +-glusterd_mgmt_v3_initiate_profile_phases(rpcsvc_request_t *req, +- glusterd_op_t op, dict_t *dict); ++glusterd_mgmt_v3_initiate_all_phases_with_brickop_phase(rpcsvc_request_t *req, ++ glusterd_op_t op, ++ dict_t *dict); + + int32_t + glusterd_mgmt_v3_initiate_snap_phases(rpcsvc_request_t *req, glusterd_op_t op, +diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h +index e64d368..cf1e61c 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h ++++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h +@@ -318,4 +318,7 @@ glusterd_op_stats_volume (dict_t *dict, char **op_errstr, dict_t *rsp_dict); + + int + glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr); ++ ++int ++gd_set_commit_hash(dict_t *dict); + #endif +diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c +index 5ab828c..7ba5f65 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c ++++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c +@@ -23,6 +23,7 @@ + #include "glusterd.h" + #include "glusterd-sm.h" + #include "glusterd-op-sm.h" ++#include "glusterd-mgmt.h" + #include "glusterd-utils.h" + #include "glusterd-messages.h" + #include "glusterd-store.h" +@@ -501,6 +502,7 @@ __glusterd_handle_defrag_volume (rpcsvc_request_t *req) + int32_t ret = -1; + gf_cli_req cli_req = {{0,}}; + glusterd_conf_t *priv = NULL; ++ int32_t op = GD_OP_NONE; + dict_t *dict = NULL; + char *volname = NULL; + gf_cli_defrag_type cmd = 0; +@@ -563,17 +565,25 @@ __glusterd_handle_defrag_volume (rpcsvc_request_t *req) + (cmd == GF_DEFRAG_CMD_STOP_DETACH_TIER) || + (cmd == GF_DEFRAG_CMD_STOP) || + (cmd == GF_DEFRAG_CMD_DETACH_STATUS)) { +- ret = glusterd_op_begin (req, GD_OP_DEFRAG_BRICK_VOLUME, +- dict, msg, sizeof (msg)); ++ op = GD_OP_DEFRAG_BRICK_VOLUME; + } else +- ret = glusterd_op_begin (req, GD_OP_REBALANCE, dict, +- msg, sizeof (msg)); +- ++ op = GD_OP_REBALANCE; ++ ++ if (priv->op_version < GD_OP_VERSION_6_0) { ++ gf_msg_debug(this->name, 0, ++ "The cluster is operating at " ++ "version less than %d. Falling back " ++ "to op-sm framework.", ++ GD_OP_VERSION_6_0); ++ ret = glusterd_op_begin(req, op, dict, msg, sizeof(msg)); ++ glusterd_friend_sm(); ++ glusterd_op_sm(); ++ } else { ++ ret = glusterd_mgmt_v3_initiate_all_phases_with_brickop_phase(req, ++ op, ++ dict); ++ } + out: +- +- glusterd_friend_sm (); +- glusterd_op_sm (); +- + if (ret) { + if (msg[0] == '\0') + snprintf (msg, sizeof (msg), "Operation failed"); +@@ -583,8 +593,8 @@ out: + } + + free (cli_req.dict.dict_val);//malloced by xdr +- +- return 0; ++ gf_msg_debug(this->name, 0, "Returning %d", ret); ++ return ret; + } + + int +@@ -628,6 +638,469 @@ glusterd_brick_validation (dict_t *dict, char *key, data_t *value, + } + + int ++glusterd_set_rebalance_id_in_rsp_dict(dict_t *req_dict, dict_t *rsp_dict) ++{ ++ int ret = -1; ++ int32_t cmd = 0; ++ char *volname = NULL; ++ glusterd_volinfo_t *volinfo = NULL; ++ char msg[2048] = {0}; ++ char *task_id_str = NULL; ++ xlator_t *this = NULL; ++ ++ this = THIS; ++ GF_ASSERT(this); ++ ++ GF_ASSERT(rsp_dict); ++ GF_ASSERT(req_dict); ++ ++ ret = dict_get_str(rsp_dict, "volname", &volname); ++ if (ret) { ++ gf_msg_debug(this->name, 0, "volname not found"); ++ goto out; ++ } ++ ++ ret = dict_get_int32(rsp_dict, "rebalance-command", &cmd); ++ if (ret) { ++ gf_msg_debug(this->name, 0, "cmd not found"); ++ goto out; ++ } ++ ++ ret = glusterd_rebalance_cmd_validate(cmd, volname, &volinfo, msg, ++ sizeof(msg)); ++ if (ret) { ++ gf_msg_debug(this->name, 0, "failed to validate"); ++ goto out; ++ } ++ ++ /* reblance id is generted in glusterd_mgmt_v3_op_stage_rebalance(), but ++ * rsp_dict is unavailable there. So copying it to rsp_dict from req_dict ++ * here. So that cli can display the rebalance id.*/ ++ if ((cmd == GF_DEFRAG_CMD_START) || ++ (cmd == GF_DEFRAG_CMD_START_LAYOUT_FIX) || ++ (cmd == GF_DEFRAG_CMD_START_FORCE) || ++ (cmd == GF_DEFRAG_CMD_START_TIER)) { ++ if (is_origin_glusterd(rsp_dict)) { ++ ret = dict_get_str(req_dict, GF_REBALANCE_TID_KEY, ++ &task_id_str); ++ if (ret) { ++ snprintf(msg, sizeof(msg), "Missing rebalance-id"); ++ gf_msg(this->name, GF_LOG_WARNING, 0, ++ GD_MSG_REBALANCE_ID_MISSING, "%s", msg); ++ ret = 0; ++ } else { ++ gf_uuid_parse(task_id_str, ++ volinfo->rebal.rebalance_id); ++ ret = glusterd_copy_uuid_to_dict( ++ volinfo->rebal.rebalance_id, rsp_dict, ++ GF_REBALANCE_TID_KEY); ++ if (ret) { ++ snprintf(msg, sizeof(msg), ++ "Failed to set rebalance id for volume %s", ++ volname); ++ gf_msg(this->name, GF_LOG_WARNING, 0, ++ GD_MSG_DICT_SET_FAILED, "%s", ++ msg); ++ } ++ } ++ } ++ } ++ ++ /* Set task-id, if available, in rsp_dict for operations other than ++ * start. This is needed when we want rebalance id in xml output ++ */ ++ if (cmd == GF_DEFRAG_CMD_STATUS || cmd == GF_DEFRAG_CMD_STOP || ++ cmd == GF_DEFRAG_CMD_STATUS_TIER) { ++ if (!gf_uuid_is_null(volinfo->rebal.rebalance_id)) { ++ if (GD_OP_REMOVE_BRICK == volinfo->rebal.op) ++ ret = glusterd_copy_uuid_to_dict( ++ volinfo->rebal.rebalance_id, rsp_dict, ++ GF_REMOVE_BRICK_TID_KEY); ++ else ++ ret = glusterd_copy_uuid_to_dict( ++ volinfo->rebal.rebalance_id, ++ rsp_dict, GF_REBALANCE_TID_KEY); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_ERROR, 0, ++ GD_MSG_DICT_SET_FAILED, ++ "Failed to set task-id for volume %s", ++ volname); ++ goto out; ++ } ++ } ++ } ++out: ++ return ret; ++} ++ ++int ++glusterd_mgmt_v3_op_stage_rebalance(dict_t *dict, char **op_errstr) ++{ ++ char *volname = NULL; ++ char *cmd_str = NULL; ++ int ret = 0; ++ int32_t cmd = 0; ++ char msg[2048] = {0}; ++ glusterd_volinfo_t *volinfo = NULL; ++ char *task_id_str = NULL; ++ xlator_t *this = 0; ++ int32_t is_force = 0; ++ ++ this = THIS; ++ GF_ASSERT(this); ++ ++ ret = dict_get_str (dict, "volname", &volname); ++ if (ret) { ++ gf_msg_debug(this->name, 0, "volname not found"); ++ goto out; ++ } ++ ++ ret = dict_get_int32 (dict, "rebalance-command", &cmd); ++ if (ret) { ++ gf_msg_debug(this->name, 0, "cmd not found"); ++ goto out; ++ } ++ ++ ret = glusterd_rebalance_cmd_validate(cmd, volname, &volinfo, msg, ++ sizeof(msg)); ++ if (ret) { ++ gf_msg_debug(this->name, 0, "failed to validate"); ++ goto out; ++ } ++ switch (cmd) { ++ case GF_DEFRAG_CMD_START_TIER: ++ ret = dict_get_int32 (dict, "force", &is_force); ++ if (ret) ++ is_force = 0; ++ ++ if (volinfo->type != GF_CLUSTER_TYPE_TIER) { ++ gf_asprintf(op_errstr, ++ "volume %s is not a tier " ++ "volume.", ++ volinfo->volname); ++ ret = -1; ++ goto out; ++ } ++ if ((!is_force) && glusterd_is_tier_daemon_running(volinfo)) { ++ ret = gf_asprintf(op_errstr, ++ "A Tier daemon is " ++ "already running on volume %s", ++ volname); ++ ret = -1; ++ goto out; ++ } ++ /* Fall through */ ++ case GF_DEFRAG_CMD_START: ++ case GF_DEFRAG_CMD_START_LAYOUT_FIX: ++ /* Check if the connected clients are all of version ++ * glusterfs-3.6 and higher. This is needed to prevent some data ++ * loss issues that could occur when older clients are connected ++ * when rebalance is run. This check can be bypassed by using ++ * 'force' ++ */ ++ ret = glusterd_check_client_op_version_support(volname, ++ GD_OP_VERSION_RHS_3_0, ++ NULL); ++ if (ret) { ++ ret = gf_asprintf(op_errstr, ++ "Volume %s has one or " ++ "more connected clients of a version" ++ " lower than GlusterFS-v3.6.0. " ++ "Starting rebalance in this state " ++ "could lead to data loss.\nPlease " ++ "disconnect those clients before " ++ "attempting this command again.", ++ volname); ++ goto out; ++ } ++ /* Fall through */ ++ case GF_DEFRAG_CMD_START_FORCE: ++ if (is_origin_glusterd(dict)) { ++ ret = glusterd_generate_and_set_task_id(dict, ++ GF_REBALANCE_TID_KEY); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TASKID_GEN_FAIL, ++ "Failed to generate task-id"); ++ goto out; ++ } ++ } else { ++ ret = dict_get_str(dict, GF_REBALANCE_TID_KEY, &task_id_str); ++ if (ret) { ++ snprintf(msg, sizeof(msg), "Missing rebalance-id"); ++ gf_msg(this->name, GF_LOG_WARNING, 0, ++ GD_MSG_REBALANCE_ID_MISSING, "%s", msg); ++ ret = 0; ++ } ++ } ++ ret = glusterd_defrag_start_validate(volinfo, msg, sizeof(msg), ++ GD_OP_REBALANCE); ++ if (ret) { ++ gf_msg_debug(this->name, 0, ++ "defrag start validate " ++ "failed for volume %s.", ++ volinfo->volname); ++ goto out; ++ } ++ break; ++ case GF_DEFRAG_CMD_STATUS_TIER: ++ case GF_DEFRAG_CMD_STATUS: ++ case GF_DEFRAG_CMD_STOP: ++ ++ ret = dict_get_str(dict, "cmd-str", &cmd_str); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED, ++ "Failed to get " ++ "command string"); ++ ret = -1; ++ goto out; ++ } ++ if ((strstr(cmd_str, "rebalance") != NULL) && ++ (volinfo->rebal.op != GD_OP_REBALANCE)) { ++ snprintf(msg, sizeof(msg), ++ "Rebalance not started " ++ "for volume %s.", volinfo->volname); ++ ret = -1; ++ goto out; ++ } ++ ++ if (strstr(cmd_str, "remove-brick") != NULL) { ++ if (volinfo->rebal.op != GD_OP_REMOVE_BRICK) { ++ snprintf(msg, sizeof(msg), ++ "remove-brick not " ++ "started for volume %s.", ++ volinfo->volname); ++ ret = -1; ++ goto out; ++ } ++ ++ /* For remove-brick status/stop command check whether ++ * given input brick is part of volume or not.*/ ++ ++ ret = dict_foreach_fnmatch(dict, "brick*", ++ glusterd_brick_validation, volinfo); ++ if (ret == -1) { ++ snprintf(msg, sizeof(msg), ++ "Incorrect brick for volume %s", ++ volinfo->volname); ++ goto out; ++ } ++ } ++ if (cmd == GF_DEFRAG_CMD_STATUS_TIER) { ++ if (volinfo->type != GF_CLUSTER_TYPE_TIER) { ++ snprintf(msg, sizeof(msg), ++ "volume %s is not " ++ "a tier volume.", ++ volinfo->volname); ++ ret = -1; ++ goto out; ++ } ++ } ++ ++ break; ++ ++ case GF_DEFRAG_CMD_STOP_DETACH_TIER: ++ case GF_DEFRAG_CMD_DETACH_STATUS: ++ if (volinfo->type != GF_CLUSTER_TYPE_TIER) { ++ snprintf(msg, sizeof(msg), ++ "volume %s is not " ++ "a tier volume.", ++ volinfo->volname); ++ ret = -1; ++ goto out; ++ } ++ ++ if (volinfo->rebal.op != GD_OP_REMOVE_BRICK) { ++ snprintf(msg, sizeof(msg), ++ "Detach-tier " ++ "not started"); ++ ret = -1; ++ goto out; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ ret = 0; ++out: ++ if (ret && op_errstr && msg[0]) ++ *op_errstr = gf_strdup(msg); ++ ++ return ret; ++} ++ ++int ++glusterd_mgmt_v3_op_rebalance(dict_t *dict, char **op_errstr, dict_t *rsp_dict) ++{ ++ char *volname = NULL; ++ int ret = 0; ++ int32_t cmd = 0; ++ char msg[2048] = {0}; ++ glusterd_volinfo_t *volinfo = NULL; ++ glusterd_brickinfo_t *brickinfo = NULL; ++ glusterd_brickinfo_t *tmp = NULL; ++ gf_boolean_t volfile_update = _gf_false; ++ char *task_id_str = NULL; ++ xlator_t *this = NULL; ++ uint32_t commit_hash; ++ int32_t is_force = 0; ++ ++ this = THIS; ++ GF_ASSERT(this); ++ ++ ret = dict_get_str(dict, "volname", &volname); ++ if (ret) { ++ gf_msg_debug(this->name, 0, "volname not given"); ++ goto out; ++ } ++ ++ ret = dict_get_int32(dict, "rebalance-command", &cmd); ++ if (ret) { ++ gf_msg_debug(this->name, 0, "command not given"); ++ goto out; ++ } ++ ++ ret = glusterd_rebalance_cmd_validate(cmd, volname, &volinfo, msg, ++ sizeof(msg)); ++ if (ret) { ++ gf_msg_debug(this->name, 0, "cmd validate failed"); ++ goto out; ++ } ++ ++ switch (cmd) { ++ case GF_DEFRAG_CMD_START: ++ case GF_DEFRAG_CMD_START_LAYOUT_FIX: ++ case GF_DEFRAG_CMD_START_FORCE: ++ case GF_DEFRAG_CMD_START_TIER: ++ ++ ret = dict_get_int32(dict, "force", &is_force); ++ if (ret) ++ is_force = 0; ++ if (!is_force) { ++ /* Reset defrag status to 'NOT STARTED' whenever a ++ * remove-brick/rebalance command is issued to remove ++ * stale information from previous run. ++ */ ++ volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_NOT_STARTED; ++ ++ ret = dict_get_str(dict, GF_REBALANCE_TID_KEY, &task_id_str); ++ if (ret) { ++ gf_msg_debug(this->name, 0, ++ "Missing rebalance id"); ++ ret = 0; ++ } else { ++ gf_uuid_parse(task_id_str, volinfo->rebal.rebalance_id); ++ volinfo->rebal.op = GD_OP_REBALANCE; ++ } ++ if (!gd_should_i_start_rebalance(volinfo)) { ++ /* Store the rebalance-id and rebalance command ++ * even if the peer isn't starting a rebalance ++ * process. On peers where a rebalance process ++ * is started, glusterd_handle_defrag_start ++ * performs the storing. ++ * Storing this is needed for having ++ * 'volume status' work correctly. ++ */ ++ glusterd_store_perform_node_state_store(volinfo); ++ break; ++ } ++ if (dict_get_uint32(dict, "commit-hash", &commit_hash) == 0) { ++ volinfo->rebal.commit_hash = commit_hash; ++ } ++ ret = glusterd_handle_defrag_start(volinfo, msg, sizeof(msg), ++ cmd, NULL, GD_OP_REBALANCE); ++ break; ++ } else { ++ /* Reset defrag status to 'STARTED' so that the ++ * pid is checked and restarted accordingly. ++ * If the pid is not running it executes the ++ * "NOT_STARTED" case and restarts the process ++ */ ++ volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_STARTED; ++ volinfo->rebal.defrag_cmd = cmd; ++ volinfo->rebal.op = GD_OP_REBALANCE; ++ ++ ret = dict_get_str(dict, GF_REBALANCE_TID_KEY, &task_id_str); ++ if (ret) { ++ gf_msg_debug(this->name, 0, ++ "Missing rebalance id"); ++ ret = 0; ++ } else { ++ gf_uuid_parse(task_id_str, volinfo->rebal.rebalance_id); ++ volinfo->rebal.op = GD_OP_REBALANCE; ++ } ++ if (dict_get_uint32(dict, "commit-hash", &commit_hash) == 0) { ++ volinfo->rebal.commit_hash = commit_hash; ++ } ++ ret = glusterd_restart_rebalance_for_volume(volinfo); ++ break; ++ } ++ case GF_DEFRAG_CMD_STOP: ++ case GF_DEFRAG_CMD_STOP_DETACH_TIER: ++ /* Clear task-id only on explicitly stopping rebalance. ++ * Also clear the stored operation, so it doesn't cause trouble ++ * with future rebalance/remove-brick starts ++ */ ++ gf_uuid_clear(volinfo->rebal.rebalance_id); ++ volinfo->rebal.op = GD_OP_NONE; ++ ++ /* Fall back to the old volume file in case of decommission*/ ++ cds_list_for_each_entry_safe(brickinfo, tmp, &volinfo->bricks, ++ brick_list) ++ { ++ if (!brickinfo->decommissioned) ++ continue; ++ brickinfo->decommissioned = 0; ++ volfile_update = _gf_true; ++ } ++ ++ if (volfile_update == _gf_false) { ++ ret = 0; ++ break; ++ } ++ ++ ret = glusterd_create_volfiles_and_notify_services(volinfo); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_WARNING, 0, ++ GD_MSG_VOLFILE_CREATE_FAIL, "failed to create volfiles"); ++ goto out; ++ } ++ ++ ret = glusterd_store_volinfo(volinfo, ++ GLUSTERD_VOLINFO_VER_AC_INCREMENT); ++ if (ret) { ++ gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_VOLINFO_SET_FAIL, ++ "failed to store volinfo"); ++ goto out; ++ } ++ ++ if (volinfo->type == GF_CLUSTER_TYPE_TIER && ++ cmd == GF_OP_CMD_STOP_DETACH_TIER) { ++ glusterd_defrag_info_set(volinfo, dict, ++ GF_DEFRAG_CMD_START_TIER, ++ GF_DEFRAG_CMD_START, GD_OP_REBALANCE); ++ glusterd_restart_rebalance_for_volume(volinfo); ++ } ++ ++ ret = 0; ++ break; ++ ++ case GF_DEFRAG_CMD_START_DETACH_TIER: ++ case GF_DEFRAG_CMD_STATUS: ++ case GF_DEFRAG_CMD_STATUS_TIER: ++ break; ++ default: ++ break; ++ } ++ ++out: ++ if (ret && op_errstr && msg[0]) ++ *op_errstr = gf_strdup(msg); ++ ++ return ret; ++} ++ ++int + glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr) + { + char *volname = NULL; +diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c +index 9a67d1c..7baef64 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c ++++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c +@@ -317,6 +317,15 @@ glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp) + ret = glusterd_max_opversion_use_rsp_dict (aggr, rsp); + break; + ++ case GD_OP_PROFILE_VOLUME: ++ ret = glusterd_profile_volume_use_rsp_dict(aggr, rsp); ++ break; ++ ++ case GD_OP_REBALANCE: ++ case GD_OP_DEFRAG_BRICK_VOLUME: ++ ret = glusterd_volume_rebalance_use_rsp_dict(aggr, rsp); ++ break; ++ + case GD_OP_TIER_STATUS: + case GD_OP_DETACH_TIER_STATUS: + case GD_OP_REMOVE_TIER_BRICK: +diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c +index 6468ecb..0fe56eb 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-utils.c ++++ b/xlators/mgmt/glusterd/src/glusterd-utils.c +@@ -10884,7 +10884,7 @@ glusterd_volume_rebalance_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict) + int ret = 0; + int32_t index = 0; + int32_t count = 0; +- int32_t current_index = 2; ++ int32_t current_index = 1; + int32_t value32 = 0; + uint64_t value = 0; + char *peer_uuid_str = NULL; +@@ -10925,7 +10925,7 @@ glusterd_volume_rebalance_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict) + if (ret) + gf_msg ("glusterd", GF_LOG_ERROR, 0, + GD_MSG_DICT_GET_FAILED, +- "failed to get index"); ++ "failed to get index from rsp dict"); + + memset (key, 0, 256); + snprintf (key, 256, "node-uuid-%d", index); +diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h +index 42c8821..f1e41be 100644 +--- a/xlators/mgmt/glusterd/src/glusterd.h ++++ b/xlators/mgmt/glusterd/src/glusterd.h +@@ -1223,6 +1223,15 @@ int glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, + dict_t *rsp_dict); + int glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr); + ++int ++glusterd_set_rebalance_id_in_rsp_dict(dict_t *req_dict, dict_t *rsp_dict); ++ ++int ++glusterd_mgmt_v3_op_stage_rebalance(dict_t *dict, char **op_errstr); ++ ++int ++glusterd_mgmt_v3_op_rebalance(dict_t *dict, char **op_errstr, dict_t *rsp_dict); ++ + int glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr); + int glusterd_op_rebalance (dict_t *dict, char **op_errstr, dict_t *rsp_dict); + +-- +1.8.3.1 + diff --git a/0491-glusterd-tag-rebalance-mgmt_v3-command-to-op-version.patch b/0491-glusterd-tag-rebalance-mgmt_v3-command-to-op-version.patch new file mode 100644 index 0000000..669a2e0 --- /dev/null +++ b/0491-glusterd-tag-rebalance-mgmt_v3-command-to-op-version.patch @@ -0,0 +1,56 @@ +From d12c2c34484f92e968dea4a52538205a69d5484f Mon Sep 17 00:00:00 2001 +From: Atin Mukherjee +Date: Tue, 18 Dec 2018 17:57:25 +0530 +Subject: [PATCH 491/493] glusterd: tag rebalance mgmt_v3 command to op-version + 31305 + +In upstream migrating rebalance command is tagged to op-version 60000 +but in downstream the latest new op-version is 31305. + +Label: DOWNSTREAM ONLY + +Change-Id: I30bbad3efca29bf42b9a750581eb1aebc8a30ff9 +BUG: 1652466 +Signed-off-by: Atin Mukherjee +Reviewed-on: https://code.engineering.redhat.com/gerrit/158943 +Tested-by: RHGS Build Bot +--- + libglusterfs/src/globals.h | 2 -- + xlators/mgmt/glusterd/src/glusterd-rebalance.c | 4 ++-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h +index 5e3b180..343263c 100644 +--- a/libglusterfs/src/globals.h ++++ b/libglusterfs/src/globals.h +@@ -111,8 +111,6 @@ + + #define GD_OP_VERSION_3_13_3 31303 /* Op-version for GlusterFS 3.13.3 */ + +-#define GD_OP_VERSION_6_0 60000 /* Op-version for GlusterFS 6.0 */ +- + /* Downstream only change */ + #define GD_OP_VERSION_3_11_2 31102 /* Op-version for RHGS 3.3.1-async */ + #define GD_OP_VERSION_3_13_3 31303 /* Op-version for RHGS-3.4-Batch Update-1*/ +diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c +index 7ba5f65..ba32241 100644 +--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c ++++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c +@@ -569,12 +569,12 @@ __glusterd_handle_defrag_volume (rpcsvc_request_t *req) + } else + op = GD_OP_REBALANCE; + +- if (priv->op_version < GD_OP_VERSION_6_0) { ++ if (priv->op_version < GD_OP_VERSION_3_13_5) { + gf_msg_debug(this->name, 0, + "The cluster is operating at " + "version less than %d. Falling back " + "to op-sm framework.", +- GD_OP_VERSION_6_0); ++ GD_OP_VERSION_3_13_5); + ret = glusterd_op_begin(req, op, dict, msg, sizeof(msg)); + glusterd_friend_sm(); + glusterd_op_sm(); +-- +1.8.3.1 + diff --git a/0492-mem-pool-track-glusterfs_ctx_t-in-struct-mem_pool.patch b/0492-mem-pool-track-glusterfs_ctx_t-in-struct-mem_pool.patch new file mode 100644 index 0000000..ff0460b --- /dev/null +++ b/0492-mem-pool-track-glusterfs_ctx_t-in-struct-mem_pool.patch @@ -0,0 +1,282 @@ +From c8e58e3a577e70a64df77fe885847285f682d9fb Mon Sep 17 00:00:00 2001 +From: Niels de Vos +Date: Tue, 29 Aug 2017 00:16:22 +0200 +Subject: [PATCH 492/493] mem-pool: track glusterfs_ctx_t in struct mem_pool + +In order to generate statedumps per glusterfs_ctx_t, it is needed to +place all the memory pools in a structure that the context can reach. +The 'struct mem_pool' has been extended with a 'list_head owner' that is +linked with the glusterfs_ctx_t->mempool_list. + +All callers of mem_pool_new() have been updated to pass the current +glusterfs_ctx_t along. This context is needed to add the new memory pool +to the list and for grabbing the ctx->lock while updating the +glusterfs_ctx_t->mempool_list. + +> Updates: #307 +> Change-Id: Ia9384424d8d1630ef3efc9d5d523bf739c356c6e +> Signed-off-by: Niels de Vos +> Reviewed-on: https://review.gluster.org/18075 +> Smoke: Gluster Build System +> CentOS-regression: Gluster Build System +> Reviewed-by: Jeff Darcy + +Change-Id: Id3b193f366f7c46f91b77bced8729a4eb538837b +BUG: 1648893 +Signed-off-by: Mohit Agrawal +Reviewed-on: https://code.engineering.redhat.com/gerrit/158937 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + libglusterfs/src/ctx.c | 2 -- + libglusterfs/src/glusterfs.h | 2 -- + libglusterfs/src/mem-pool.c | 18 +++++++++++++++++- + libglusterfs/src/mem-pool.h | 16 +++++++++++++--- + libglusterfs/src/rbthash.c | 5 +++-- + libglusterfs/src/rbthash.h | 2 +- + libglusterfs/src/statedump.c | 16 +++++++++++++++- + xlators/cluster/ec/src/ec-method.c | 2 +- + xlators/nfs/server/src/nfs3.c | 3 ++- + xlators/performance/io-cache/src/io-cache.c | 2 +- + 10 files changed, 53 insertions(+), 15 deletions(-) + +diff --git a/libglusterfs/src/ctx.c b/libglusterfs/src/ctx.c +index 94c56ac..90480d0 100644 +--- a/libglusterfs/src/ctx.c ++++ b/libglusterfs/src/ctx.c +@@ -31,9 +31,7 @@ glusterfs_ctx_new () + ctx->mem_acct_enable = gf_global_mem_acct_enable_get(); + + INIT_LIST_HEAD (&ctx->graphs); +-#if defined(OLD_MEM_POOLS) + INIT_LIST_HEAD (&ctx->mempool_list); +-#endif + INIT_LIST_HEAD (&ctx->volfile_list); + + ctx->daemon_pipe[0] = -1; +diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h +index c12e94e..157437c 100644 +--- a/libglusterfs/src/glusterfs.h ++++ b/libglusterfs/src/glusterfs.h +@@ -526,11 +526,9 @@ struct _glusterfs_ctx { + int process_mode; /*mode in which process is runninng*/ + struct syncenv *env; /* The env pointer to the synctasks */ + +-#if defined(OLD_MEM_POOLS) + struct list_head mempool_list; /* used to keep a global list of + mempools, used to log details of + mempool in statedump */ +-#endif + char *statedump_path; + + struct mem_pool *dict_pool; +diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c +index a8a9347..999a83f 100644 +--- a/libglusterfs/src/mem-pool.c ++++ b/libglusterfs/src/mem-pool.c +@@ -676,7 +676,7 @@ void mem_pools_fini (void) {} + #endif + + struct mem_pool * +-mem_pool_new_fn (unsigned long sizeof_type, ++mem_pool_new_fn (glusterfs_ctx_t *ctx, unsigned long sizeof_type, + unsigned long count, char *name) + { + unsigned int i; +@@ -706,10 +706,18 @@ mem_pool_new_fn (unsigned long sizeof_type, + if (!new) + return NULL; + ++ new->ctx = ctx; + new->sizeof_type = sizeof_type; + new->count = count; + new->name = name; + new->pool = pool; ++ INIT_LIST_HEAD (&new->owner); ++ ++ LOCK (&ctx->lock); ++ { ++ list_add (&new->owner, &ctx->mempool_list); ++ } ++ UNLOCK (&ctx->lock); + + return new; + } +@@ -905,6 +913,14 @@ mem_put (void *ptr) + void + mem_pool_destroy (struct mem_pool *pool) + { ++ /* remove this pool from the owner (glusterfs_ctx_t) */ ++ LOCK (&pool->ctx->lock); ++ { ++ list_del (&pool->owner); ++ } ++ UNLOCK (&pool->ctx->lock); ++ ++ /* free this pool, but keep the mem_pool_shared */ + GF_FREE (pool); + + /* +diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h +index 057d957..0ebb63b 100644 +--- a/libglusterfs/src/mem-pool.h ++++ b/libglusterfs/src/mem-pool.h +@@ -16,6 +16,7 @@ + #include "atomic.h" + #include "logging.h" + #include "mem-types.h" ++#include "glusterfs.h" /* for glusterfs_ctx_t */ + #include + #include + #include +@@ -207,11 +208,15 @@ out: + /* kind of 'header' for the actual mem_pool_shared structure, this might make + * it possible to dump some more details in a statedump */ + struct mem_pool { ++ /* object size, without pooled_obj_hdr_t */ + unsigned long sizeof_type; + unsigned long count; + char *name; + +- struct mem_pool_shared *pool; ++ struct list_head owner; /* glusterfs_ctx_t->mempool_list */ ++ glusterfs_ctx_t *ctx; /* take ctx->lock when updating owner */ ++ ++ struct mem_pool_shared *pool; /* the initial pool that was returned */ + }; + + typedef struct pooled_obj_hdr { +@@ -276,9 +281,14 @@ void mem_pools_init_late (void); /* start the pool_sweeper thread */ + void mem_pools_fini (void); /* cleanup memory pools */ + + struct mem_pool * +-mem_pool_new_fn (unsigned long sizeof_type, unsigned long count, char *name); ++mem_pool_new_fn (glusterfs_ctx_t *ctx, unsigned long sizeof_type, unsigned long ++ count, char *name); ++ ++#define mem_pool_new(type, count) (mem_pool_new_fn (THIS->ctx, \ ++ sizeof(type), count, #type)) + +-#define mem_pool_new(type,count) mem_pool_new_fn (sizeof(type), count, #type) ++#define mem_pool_new_ctx(ctx, type, count) (mem_pool_new_fn (ctx, \ ++ sizeof(type), count, #type)) + + void mem_put (void *ptr); + void *mem_get (struct mem_pool *pool); +diff --git a/libglusterfs/src/rbthash.c b/libglusterfs/src/rbthash.c +index 52d8a15..06fc7ee 100644 +--- a/libglusterfs/src/rbthash.c ++++ b/libglusterfs/src/rbthash.c +@@ -83,7 +83,7 @@ err: + */ + + rbthash_table_t * +-rbthash_table_init (int buckets, rbt_hasher_t hfunc, ++rbthash_table_init (glusterfs_ctx_t *ctx, int buckets, rbt_hasher_t hfunc, + rbt_data_destroyer_t dfunc, + unsigned long expected_entries, + struct mem_pool *entrypool) +@@ -123,7 +123,8 @@ rbthash_table_init (int buckets, rbt_hasher_t hfunc, + + if (expected_entries) { + newtab->entrypool = +- mem_pool_new (rbthash_entry_t, expected_entries); ++ mem_pool_new_ctx (ctx, rbthash_entry_t, ++ expected_entries); + if (!newtab->entrypool) { + goto free_buckets; + } +diff --git a/libglusterfs/src/rbthash.h b/libglusterfs/src/rbthash.h +index b093ce9..949b88a 100644 +--- a/libglusterfs/src/rbthash.h ++++ b/libglusterfs/src/rbthash.h +@@ -52,7 +52,7 @@ typedef struct rbthash_table { + } rbthash_table_t; + + extern rbthash_table_t * +-rbthash_table_init (int buckets, rbt_hasher_t hfunc, ++rbthash_table_init (glusterfs_ctx_t *ctx, int buckets, rbt_hasher_t hfunc, + rbt_data_destroyer_t dfunc, unsigned long expected_entries, + struct mem_pool *entrypool); + +diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c +index a4635f3..4aad014 100644 +--- a/libglusterfs/src/statedump.c ++++ b/libglusterfs/src/statedump.c +@@ -377,11 +377,11 @@ gf_proc_dump_mem_info_to_dict (dict_t *dict) + void + gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx) + { +-#if defined(OLD_MEM_POOLS) + struct mem_pool *pool = NULL; + + gf_proc_dump_add_section ("mempool"); + ++#if defined(OLD_MEM_POOLS) + list_for_each_entry (pool, &ctx->mempool_list, global_list) { + gf_proc_dump_write ("-----", "-----"); + gf_proc_dump_write ("pool-name", "%s", pool->name); +@@ -396,6 +396,20 @@ gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx) + gf_proc_dump_write ("cur-stdalloc", "%d", pool->curr_stdalloc); + gf_proc_dump_write ("max-stdalloc", "%d", pool->max_stdalloc); + } ++#else ++ LOCK (&ctx->lock); ++ { ++ list_for_each_entry (pool, &ctx->mempool_list, owner) { ++ gf_proc_dump_write ("-----", "-----"); ++ gf_proc_dump_write ("pool-name", "%s", pool->name); ++ gf_proc_dump_write ("sizeof-type", "%lu", pool->sizeof_type); ++ gf_proc_dump_write ("padded-sizeof", "%d", 1 << pool->pool->power_of_two); ++ gf_proc_dump_write ("shared-pool", "%p", pool->pool); ++ } ++ } ++ UNLOCK (&ctx->lock); ++ ++ /* TODO: details of (struct mem_pool_shared) pool->pool */ + #endif + } + +diff --git a/xlators/cluster/ec/src/ec-method.c b/xlators/cluster/ec/src/ec-method.c +index e0dd8e7..a2dd2bd 100644 +--- a/xlators/cluster/ec/src/ec-method.c ++++ b/xlators/cluster/ec/src/ec-method.c +@@ -310,7 +310,7 @@ ec_method_init(xlator_t *xl, ec_matrix_list_t *list, uint32_t columns, + INIT_LIST_HEAD(&list->lru); + int32_t err; + +- list->pool = mem_pool_new_fn(sizeof(ec_matrix_t) + ++ list->pool = mem_pool_new_fn(xl->ctx, sizeof(ec_matrix_t) + + sizeof(ec_matrix_row_t) * columns + + sizeof(uint32_t) * columns * columns, + 128, "ec_matrix_t"); +diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c +index 040d316..b053eb3 100644 +--- a/xlators/nfs/server/src/nfs3.c ++++ b/xlators/nfs/server/src/nfs3.c +@@ -5786,7 +5786,8 @@ nfs3_init_state (xlator_t *nfsx) + + localpool = nfs->memfactor * GF_NFS_CONCURRENT_OPS_MULT; + gf_msg_trace (GF_NFS3, 0, "local pool: %d", localpool); +- nfs3->localpool = mem_pool_new (nfs3_call_state_t, localpool); ++ nfs3->localpool = mem_pool_new_ctx (nfsx->ctx, nfs3_call_state_t, ++ localpool); + if (!nfs3->localpool) { + gf_msg (GF_NFS3, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY, + "local mempool creation failed"); +diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c +index de44ad2..d7b3b37 100644 +--- a/xlators/performance/io-cache/src/io-cache.c ++++ b/xlators/performance/io-cache/src/io-cache.c +@@ -1146,7 +1146,7 @@ ioc_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, + if (!ioc_inode->cache.page_table) { + ioc_inode->cache.page_table + = rbthash_table_init +- (IOC_PAGE_TABLE_BUCKET_COUNT, ++ (this->ctx, IOC_PAGE_TABLE_BUCKET_COUNT, + ioc_hashfn, NULL, 0, + table->mem_pool); + +-- +1.8.3.1 + diff --git a/0493-mem-pool-count-allocations-done-per-user-pool.patch b/0493-mem-pool-count-allocations-done-per-user-pool.patch new file mode 100644 index 0000000..39d4784 --- /dev/null +++ b/0493-mem-pool-count-allocations-done-per-user-pool.patch @@ -0,0 +1,96 @@ +From bb668d69815209bd7f7f4669142191d4b48bcde8 Mon Sep 17 00:00:00 2001 +From: Mohit Agrawal +Date: Tue, 18 Dec 2018 19:41:42 +0530 +Subject: [PATCH 493/493] mem-pool: count allocations done per user-pool + +Count the active allocations per 'struct mem_pool'. These are the +objects that the calling component allocated and free'd in the memory +pool for this specific type. Having this count in the statedump will +make it easy to find memory leaks. + +> Updates: #307 +> Change-Id: I797fabab86f104e49338c00e449a7d0b0d270004 +> Signed-off-by: Niels de Vos +> Reviewed-on: https://review.gluster.org/18074 +> Smoke: Gluster Build System +> CentOS-regression: Gluster Build System +> Reviewed-by: Jeff Darcy + +Change-Id: I2e4375fd59f11288f41a36cad131d794bff19fbb +BUG: 1648893 +Signed-off-by: Mohit Agrawal +Reviewed-on: https://code.engineering.redhat.com/gerrit/158961 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + libglusterfs/src/mem-pool.c | 4 ++++ + libglusterfs/src/mem-pool.h | 3 ++- + libglusterfs/src/statedump.c | 4 ++++ + 3 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c +index 999a83f..d82a371 100644 +--- a/libglusterfs/src/mem-pool.c ++++ b/libglusterfs/src/mem-pool.c +@@ -711,6 +711,7 @@ mem_pool_new_fn (glusterfs_ctx_t *ctx, unsigned long sizeof_type, + new->count = count; + new->name = name; + new->pool = pool; ++ GF_ATOMIC_INIT (new->active, 0); + INIT_LIST_HEAD (&new->owner); + + LOCK (&ctx->lock); +@@ -864,6 +865,8 @@ mem_get (struct mem_pool *mem_pool) + retval->pool_list = pool_list; + retval->power_of_two = mem_pool->pool->power_of_two; + ++ GF_ATOMIC_INC (mem_pool->active); ++ + return retval + 1; + #endif /* GF_DISABLE_MEMPOOL */ + } +@@ -894,6 +897,7 @@ mem_put (void *ptr) + pt_pool = &pool_list->pools[hdr->power_of_two-POOL_SMALLEST]; + + hdr->magic = GF_MEM_INVALID_MAGIC; ++ GF_ATOMIC_DEC (hdr->pool->active); + + (void) pthread_spin_lock (&pool_list->lock); + if (!pool_list->poison) { +diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h +index 0ebb63b..aa1d045 100644 +--- a/libglusterfs/src/mem-pool.h ++++ b/libglusterfs/src/mem-pool.h +@@ -210,8 +210,9 @@ out: + struct mem_pool { + /* object size, without pooled_obj_hdr_t */ + unsigned long sizeof_type; +- unsigned long count; ++ unsigned long count; /* requested pool size (unused) */ + char *name; ++ gf_atomic_t active; /* current allocations */ + + struct list_head owner; /* glusterfs_ctx_t->mempool_list */ + glusterfs_ctx_t *ctx; /* take ctx->lock when updating owner */ +diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c +index 4aad014..a04c535 100644 +--- a/libglusterfs/src/statedump.c ++++ b/libglusterfs/src/statedump.c +@@ -400,10 +400,14 @@ gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx) + LOCK (&ctx->lock); + { + list_for_each_entry (pool, &ctx->mempool_list, owner) { ++ int64_t active = GF_ATOMIC_GET (pool->active); ++ + gf_proc_dump_write ("-----", "-----"); + gf_proc_dump_write ("pool-name", "%s", pool->name); ++ gf_proc_dump_write ("active-count", "%"GF_PRI_ATOMIC, active); + gf_proc_dump_write ("sizeof-type", "%lu", pool->sizeof_type); + gf_proc_dump_write ("padded-sizeof", "%d", 1 << pool->pool->power_of_two); ++ gf_proc_dump_write ("size", "%lu", (1 << pool->pool->power_of_two) * active); + gf_proc_dump_write ("shared-pool", "%p", pool->pool); + } + } +-- +1.8.3.1 + diff --git a/glusterfs.spec b/glusterfs.spec index 87d0f19..fa7c69d 100644 --- a/glusterfs.spec +++ b/glusterfs.spec @@ -192,7 +192,7 @@ Release: 0.1%{?prereltag:.%{prereltag}}%{?dist} %else Name: glusterfs Version: 3.12.2 -Release: 32%{?dist} +Release: 33%{?dist} %endif License: GPLv2 or LGPLv3+ Group: System Environment/Base @@ -720,6 +720,44 @@ Patch0452: 0452-glusterd-make-max-bricks-per-process-default-value-t.patch Patch0453: 0453-server-Resolve-memory-leak-path-in-server_init.patch Patch0454: 0454-glusterd-set-cluster.max-bricks-per-process-to-250.patch Patch0455: 0455-glusterd-fix-get_mux_limit_per_process-to-read-defau.patch +Patch0456: 0456-Update-rfc.sh-to-rhgs-3.4.3.patch +Patch0457: 0457-cluster-dht-sync-brick-root-perms-on-add-brick.patch +Patch0458: 0458-glusterd-fix-crash.patch +Patch0459: 0459-glfsheal-add-a-nolog-flag.patch +Patch0460: 0460-cli-add-a-warning-confirmation-message-in-peer-detac.patch +Patch0461: 0461-mount-fuse-Add-support-for-multi-threaded-fuse-reade.patch +Patch0462: 0462-posix-Do-not-log-ENXIO-errors-for-seek-fop.patch +Patch0463: 0463-build-glusterfs.spec-.in-firewalld-file-doesn-t-use-.patch +Patch0464: 0464-build-exclude-packaging-crypt.so.patch +Patch0465: 0465-build-add-missing-explicit-package-dependencies.patch +Patch0466: 0466-extras-Add-group-distributed-virt-for-single-brick-o.patch +Patch0467: 0467-glusterd-glusterd-to-regenerate-volfiles-when-GD_OP_.patch +Patch0468: 0468-core-move-invalid-port-logs-to-DEBUG-log-level.patch +Patch0469: 0469-nfs-set-ctx-for-every-inode-looked-up-nfs3_fh_resolv.patch +Patch0470: 0470-dht-fix-use-after-free-in-dht_rmdir_readdirp_cbk.patch +Patch0471: 0471-glusterd-migrating-profile-commands-to-mgmt_v3-frame.patch +Patch0472: 0472-glusterd-introduce-a-new-op-version-for-rhgs-3.4.3.patch +Patch0473: 0473-rpc-bump-up-server.event-threads.patch +Patch0474: 0474-afr-open_ftruncate_cbk-should-read-fd-from-local-con.patch +Patch0475: 0475-glusterd-perform-store-operation-in-cleanup-lock.patch +Patch0476: 0476-afr-add-checks-for-allowing-lookups.patch +Patch0477: 0477-glusterd-perform-rcu_read_lock-unlock-under-cleanup_.patch +Patch0478: 0478-libglusterfs-fix-memory-corruption-caused-by-per-thr.patch +Patch0479: 0479-ganesha-ha-ensure-pacemaker-is-enabled-after-setup.patch +Patch0480: 0480-geo-rep-Make-slave-volume-read-only-by-default.patch +Patch0481: 0481-extras-hooks-Do-not-blindly-remove-volume-share-from.patch +Patch0482: 0482-extras-hooks-General-improvements-to-S30samba-start..patch +Patch0483: 0483-Do-not-blindly-add-volume-share-section-to-smb.conf.patch +Patch0484: 0484-extras-New-group-volume-set-command-for-Samba-integr.patch +Patch0485: 0485-cluster-ec-Prevent-volume-create-without-redundant-b.patch +Patch0486: 0486-performance-rda-Fixed-dict_t-memory-leak.patch +Patch0487: 0487-mem-pool-add-tracking-of-mem_pool-that-requested-the.patch +Patch0488: 0488-cluster-afr-Allow-lookup-on-root-if-it-is-from-ADD_R.patch +Patch0489: 0489-cluster-afr-Do-not-update-read_subvol-in-inode_ctx-a.patch +Patch0490: 0490-glusterd-migrating-rebalance-commands-to-mgmt_v3-fra.patch +Patch0491: 0491-glusterd-tag-rebalance-mgmt_v3-command-to-op-version.patch +Patch0492: 0492-mem-pool-track-glusterfs_ctx_t-in-struct-mem_pool.patch +Patch0493: 0493-mem-pool-count-allocations-done-per-user-pool.patch %description GlusterFS is a distributed file-system capable of scaling to several @@ -739,6 +777,7 @@ Summary: GlusterFS api library Group: System Environment/Daemons Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description api GlusterFS is a distributed file-system capable of scaling to several @@ -757,6 +796,7 @@ Group: Development/Libraries Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}-devel%{?_isa} = %{version}-%{release} Requires: libacl-devel +Requires: %{name}-api%{?_isa} = %{version}-%{release} %description api-devel GlusterFS is a distributed file-system capable of scaling to several @@ -793,6 +833,8 @@ Requires: %{name}%{?_isa} = %{version}-%{release} %if ( 0%{!?_without_extra_xlators:1} ) Requires: %{name}-extra-xlators = %{version}-%{release} %endif +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-server%{?_isa} = %{version}-%{release} %description devel GlusterFS is a distributed file-system capable of scaling to several @@ -842,6 +884,7 @@ Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release} Obsoletes: %{name}-client < %{version}-%{release} Provides: %{name}-client = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description fuse GlusterFS is a distributed file-system capable of scaling to several @@ -911,6 +954,7 @@ BuildRequires: python-ctypes Requires: python2-gluster = %{version}-%{release} Requires: rsync Requires: util-linux +Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description geo-replication GlusterFS is a distributed file-system capable of scaling to several @@ -983,6 +1027,7 @@ BuildRequires: libibverbs-devel BuildRequires: librdmacm-devel >= 1.0.15 %endif Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description rdma GlusterFS is a distributed file-system capable of scaling to several @@ -1113,6 +1158,7 @@ This package provides the glusterfs server daemon. %package client-xlators Summary: GlusterFS client-side translators Group: Applications/File +Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description client-xlators GlusterFS is a distributed file-system capable of scaling to several @@ -1675,7 +1721,7 @@ exit 0 %exclude %{_tmpfilesdir}/gluster.conf %endif %if ( 0%{?_with_firewalld:1} ) -%exclude /usr/lib/firewalld/services/glusterfs.xml +%exclude %{_prefix}/lib/firewalld/services/glusterfs.xml %endif %endif %doc ChangeLog COPYING-GPLV2 COPYING-LGPLV3 INSTALL README.md THANKS @@ -1705,8 +1751,8 @@ exit 0 %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug/trace.so %if ( ! ( 0%{?rhel} && 0%{?rhel} < 6 ) ) # RHEL-5 based distributions have a too old openssl -%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption - %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption/crypt.so +%exclude %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption +%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption/crypt.so %endif %dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/access-control.so @@ -2021,7 +2067,9 @@ exit 0 %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/metadata-cache %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/gluster-block %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/db-workload + %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/distributed-virt %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/nl-cache + %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/samba %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glusterfind %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glusterfind/.keys %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glustershd @@ -2668,6 +2716,12 @@ fi %endif %changelog +* Tue Dec 18 2018 Milind Changire - 3.12.2-33 +- fixes bugs bz#1350745 bz#1362129 bz#1541568 bz#1597252 bz#1599220 + bz#1633177 bz#1637564 bz#1639476 bz#1639568 bz#1643370 bz#1645480 bz#1648296 + bz#1648893 bz#1651040 bz#1651460 bz#1652466 bz#1652537 bz#1653224 bz#1653613 + bz#1654103 bz#1654161 bz#1655385 bz#1655578 bz#1656357 bz#1659439 + * Fri Dec 07 2018 Milind Changire - 3.12.2-32 - fixes bugs bz#1656924