autobuild v3.12.2-19

Resolves: bz#1459709 bz#1610743 bz#1618221 bz#1619627 bz#1622649
Resolves: bz#1623749 bz#1623874 bz#1624444 bz#1625622 bz#1626780
Resolves: bz#1627098 bz#1627617 bz#1627639 bz#1630688
Signed-off-by: Sunil Kumar Acharya <sheggodu@redhat.com>
This commit is contained in:
Sunil Kumar Acharya 2018-09-21 23:36:36 -04:00
parent 1ad23d07c6
commit be071b020b
24 changed files with 3342 additions and 1 deletions

View File

@ -0,0 +1,27 @@
From 84e7997bdf977f7d2dbce2f1f7c57c4ccb1190ba Mon Sep 17 00:00:00 2001
From: Milind Changire <mchangir@redhat.com>
Date: Wed, 5 Sep 2018 10:38:20 +0530
Subject: [PATCH 363/385] Update rfc.sh to rhgs-3.4.1
Change-Id: I16da34310701c5db74664cdd2b2fa67534b662ab
Signed-off-by: Milind Changire <mchangir@redhat.com>
---
rfc.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rfc.sh b/rfc.sh
index 356242e..8c4b5ac 100755
--- a/rfc.sh
+++ b/rfc.sh
@@ -17,7 +17,7 @@ done
shift $((OPTIND-1))
-branch="rhgs-3.4.0";
+branch="rhgs-3.4.1";
set_hooks_commit_msg()
{
--
1.8.3.1

View File

@ -0,0 +1,126 @@
From eba2217ac06dab658526991e93e018b91c92d7b5 Mon Sep 17 00:00:00 2001
From: Kotresh HR <khiremat@redhat.com>
Date: Tue, 19 Dec 2017 00:05:05 -0500
Subject: [PATCH 364/385] fips: Replace md5sum usage to enable fips support
md5sum is not fips compliant. Using xxhash64 instead of
md5sum for socket file generation in glusterd and
changelog to enable fips support.
NOTE: md5sum is 128 bit hash. xxhash used is 64 bit.
Backport of:
> Patch: https://review.gluster.org/19048
> Updates: #230
> Change-Id: I1bf2ea05905b9151cd29fa951f903685ab0dc84c
> Signed-off-by: Kotresh HR <khiremat@redhat.com>
BUG: 1459709
Change-Id: I1bf2ea05905b9151cd29fa951f903685ab0dc84c
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/149770
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
libglusterfs/src/common-utils.c | 11 -----------
libglusterfs/src/common-utils.h | 1 -
xlators/features/changelog/src/changelog-misc.h | 20 ++++++++++----------
xlators/mgmt/glusterd/src/glusterd-utils.c | 8 +++++---
4 files changed, 15 insertions(+), 25 deletions(-)
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index fd2f004..f632e78 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -75,17 +75,6 @@ typedef int32_t (*rw_op_t)(int32_t fd, char *buf, int32_t size);
typedef int32_t (*rwv_op_t)(int32_t fd, const struct iovec *buf, int32_t size);
void
-md5_wrapper(const unsigned char *data, size_t len, char *md5)
-{
- unsigned short i = 0;
- unsigned short lim = MD5_DIGEST_LENGTH*2+1;
- unsigned char scratch[MD5_DIGEST_LENGTH] = {0,};
- MD5(data, len, scratch);
- for (; i < MD5_DIGEST_LENGTH; i++)
- snprintf(md5 + i * 2, lim-i*2, "%02x", scratch[i]);
-}
-
-void
gf_xxh64_wrapper(const unsigned char *data, size_t len, unsigned long long seed,
char *xxh64)
{
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index 0131070..da943f4 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -835,7 +835,6 @@ gf_ports_reserved (char *blocked_port, unsigned char *ports, uint32_t ceiling);
int gf_get_hostname_from_ip (char *client_ip, char **hostname);
gf_boolean_t gf_is_local_addr (char *hostname);
gf_boolean_t gf_is_same_address (char *host1, char *host2);
-void md5_wrapper(const unsigned char *data, size_t len, char *md5);
void gf_xxh64_wrapper(const unsigned char *data, size_t len,
unsigned long long seed, char *xxh64);
int gf_set_timestamp (const char *src, const char* dest);
diff --git a/xlators/features/changelog/src/changelog-misc.h b/xlators/features/changelog/src/changelog-misc.h
index 94d6c50..93af201 100644
--- a/xlators/features/changelog/src/changelog-misc.h
+++ b/xlators/features/changelog/src/changelog-misc.h
@@ -36,24 +36,24 @@
"GlusterFS Changelog | version: v%d.%d | encoding : %d\n"
#define CHANGELOG_MAKE_SOCKET_PATH(brick_path, sockpath, len) do { \
- char md5_sum[MD5_DIGEST_LENGTH*2+1] = {0,}; \
- md5_wrapper((unsigned char *) brick_path, \
- strlen(brick_path), \
- md5_sum); \
+ char xxh64[GF_XXH64_DIGEST_LENGTH*2+1] = {0,}; \
+ gf_xxh64_wrapper ((unsigned char *)brick_path, \
+ strlen(brick_path), \
+ GF_XXHSUM64_DEFAULT_SEED, xxh64); \
(void) snprintf (sockpath, len, \
- CHANGELOG_UNIX_SOCK, md5_sum); \
+ CHANGELOG_UNIX_SOCK, xxh64); \
} while (0)
#define CHANGELOG_MAKE_TMP_SOCKET_PATH(brick_path, sockpath, len) do { \
unsigned long pid = 0; \
- char md5_sum[MD5_DIGEST_LENGTH*2+1] = {0,}; \
+ char xxh64[GF_XXH64_DIGEST_LENGTH*2+1] = {0,}; \
pid = (unsigned long) getpid (); \
- md5_wrapper((unsigned char *) brick_path, \
- strlen(brick_path), \
- md5_sum); \
+ gf_xxh64_wrapper ((unsigned char *)brick_path, \
+ strlen(brick_path), \
+ GF_XXHSUM64_DEFAULT_SEED, xxh64); \
(void) snprintf (sockpath, \
len, CHANGELOG_TMP_UNIX_SOCK, \
- md5_sum, pid); \
+ xxh64, pid); \
} while (0)
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 01345cd..4fd8575 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -1852,10 +1852,12 @@ out:
void
glusterd_set_socket_filepath (char *sock_filepath, char *sockpath, size_t len)
{
- char md5_sum[MD5_DIGEST_LENGTH*2+1] = {0,};
+ char xxh64[GF_XXH64_DIGEST_LENGTH*2+1] = {0,};
- md5_wrapper ((unsigned char *) sock_filepath, strlen(sock_filepath), md5_sum);
- snprintf (sockpath, len, "%s/%s.socket", GLUSTERD_SOCK_DIR, md5_sum);
+ gf_xxh64_wrapper ((unsigned char *)sock_filepath,
+ strlen(sock_filepath),
+ GF_XXHSUM64_DEFAULT_SEED, xxh64);
+ snprintf (sockpath, len, "%s/%s.socket", GLUSTERD_SOCK_DIR, xxh64);
}
void
--
1.8.3.1

View File

@ -0,0 +1,208 @@
From d8e094d1bdd2dff5e8f81c0786ca62f6d6dc45ee Mon Sep 17 00:00:00 2001
From: Atin Mukherjee <amukherj@redhat.com>
Date: Tue, 31 Jul 2018 12:33:49 +0530
Subject: [PATCH 365/385] glusterd: ignore importing volume which is undergoing
a delete operation
Problem explanation:
Assuming in a 3 nodes cluster, if N1 originates a delete operation and
while N1's commit phase completes, either glusterd service of N2 or N3
gets disconnected from N1 (before completing the commit phase), N1 will
attempt to end up importing the volume which is in-flight for a delete
in other nodes as a fresh resulting into an incorrect configuration
state.
Fix:
Mark a volume as stage deleted once a volume delete operation passes
it's staging phase and reset this flag during unlock phase. Now during
this intermediate phase if the same volume gets imported to other peers,
it shouldn't considered to be recreated.
An automated .t is quite tough to implement with the current infra.
Test Case:
1. Keep creating and deleting volumes in a loop on a 3 node cluster
2. Simulate n/w failure between the peers (ifdown followed by ifup)
3. Check if output of 'gluster v list | wc -l' is same across all 3
nodes during 1 & 2.
>upstream patch : https://review.gluster.org/#/c/glusterfs/+/20592
>Change-Id: Ifdd5dc39699120258d7fdd42fe2deb9de25c6246
>Fixes: bz#1605077
>Signed-off-by: Atin Mukherjee <amukherj@redhat.com>
Change-Id: Ifdd5dc39699120258d7fdd42fe2deb9de25c6246
BUG: 1618221
Signed-off-by: Atin Mukherjee <amukherj@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/149872
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
xlators/mgmt/glusterd/src/glusterd-locks.c | 13 +++++++++--
xlators/mgmt/glusterd/src/glusterd-utils.c | 30 ++++++++++++++++++++++---
xlators/mgmt/glusterd/src/glusterd-utils.h | 2 +-
xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 2 +-
xlators/mgmt/glusterd/src/glusterd.h | 3 +++
5 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/xlators/mgmt/glusterd/src/glusterd-locks.c b/xlators/mgmt/glusterd/src/glusterd-locks.c
index 831be20..f4e0225 100644
--- a/xlators/mgmt/glusterd/src/glusterd-locks.c
+++ b/xlators/mgmt/glusterd/src/glusterd-locks.c
@@ -790,6 +790,7 @@ glusterd_mgmt_v3_unlock (const char *name, uuid_t uuid, char *type)
int32_t ret = -1;
gf_boolean_t is_valid = _gf_true;
glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
glusterd_mgmt_v3_lock_timer *mgmt_lock_timer = NULL;
uuid_t owner = {0};
xlator_t *this = NULL;
@@ -888,8 +889,7 @@ glusterd_mgmt_v3_unlock (const char *name, uuid_t uuid, char *type)
"Lock for %s %s successfully released",
type, name);
- ret = 0;
- /* Release owner refernce which was held during lock */
+ /* Release owner reference which was held during lock */
if (mgmt_lock_timer->timer) {
ret = -1;
mgmt_lock_timer_xl = mgmt_lock_timer->xl;
@@ -906,6 +906,15 @@ glusterd_mgmt_v3_unlock (const char *name, uuid_t uuid, char *type)
dict_del (priv->mgmt_v3_lock_timer, key_dup);
mgmt_lock_timer->timer = NULL;
}
+ ret = glusterd_volinfo_find (name, &volinfo);
+ if (volinfo && volinfo->stage_deleted) {
+ /* this indicates a volume still exists and the volume delete
+ * operation has failed in some of the phases, need to ensure
+ * stage_deleted flag is set back to false
+ */
+ volinfo->stage_deleted = _gf_false;
+ }
+ ret = 0;
out:
gf_msg_trace (this->name, 0, "Returning %d", ret);
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 4fd8575..7f52602 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -1699,7 +1699,7 @@ glusterd_volinfo_find_by_volume_id (uuid_t volume_id, glusterd_volinfo_t **volin
}
int32_t
-glusterd_volinfo_find (char *volname, glusterd_volinfo_t **volinfo)
+glusterd_volinfo_find (const char *volname, glusterd_volinfo_t **volinfo)
{
glusterd_volinfo_t *tmp_volinfo = NULL;
int32_t ret = -1;
@@ -2952,6 +2952,11 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
if (ret)
goto out;
+ snprintf (key, sizeof (key), "%s%d.stage_deleted", prefix, count);
+ ret = dict_set_uint32 (dict, key, (uint32_t)volinfo->stage_deleted);
+ if (ret)
+ goto out;
+
/* tiering related variables */
memset (key, 0, sizeof (key));
@@ -3355,6 +3360,7 @@ glusterd_compare_friend_volume (dict_t *peer_data, int32_t count,
uint32_t cksum = 0;
uint32_t quota_cksum = 0;
uint32_t quota_version = 0;
+ uint32_t stage_deleted = 0;
int32_t version = 0;
xlator_t *this = NULL;
@@ -3370,9 +3376,15 @@ glusterd_compare_friend_volume (dict_t *peer_data, int32_t count,
goto out;
ret = glusterd_volinfo_find (volname, &volinfo);
-
if (ret) {
- *status = GLUSTERD_VOL_COMP_UPDATE_REQ;
+ snprintf (key, sizeof (key), "volume%d.stage_deleted", count);
+ ret = dict_get_uint32 (peer_data, key, &stage_deleted);
+ /* stage_deleted = 1 means the volume is still in the process of
+ * deleting a volume, so we shouldn't be trying to create a
+ * fresh volume here which would lead to a stale entry
+ */
+ if (stage_deleted == 0)
+ *status = GLUSTERD_VOL_COMP_UPDATE_REQ;
ret = 0;
goto out;
}
@@ -3929,6 +3941,7 @@ glusterd_import_volinfo (dict_t *peer_data, int count,
char *rebalance_id_str = NULL;
int op_version = 0;
int client_op_version = 0;
+ uint32_t stage_deleted = 0;
GF_ASSERT (peer_data);
GF_ASSERT (volinfo);
@@ -3941,6 +3954,17 @@ glusterd_import_volinfo (dict_t *peer_data, int count,
goto out;
}
+ snprintf (key, sizeof (key), "%s%d.stage_deleted", prefix, count);
+ ret = dict_get_uint32 (peer_data, key, &stage_deleted);
+ /* stage_deleted = 1 means the volume is still in the process of
+ * deleting a volume, so we shouldn't be trying to create a
+ * fresh volume here which would lead to a stale entry
+ */
+ if (stage_deleted) {
+ ret = 0;
+ goto out;
+ }
+
ret = glusterd_volinfo_new (&new_volinfo);
if (ret)
goto out;
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 4835728..ffcc636 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -159,7 +159,7 @@ glusterd_brickinfo_new_from_brick (char *brick,
char **op_errstr);
int32_t
-glusterd_volinfo_find (char *volname, glusterd_volinfo_t **volinfo);
+glusterd_volinfo_find (const char *volname, glusterd_volinfo_t **volinfo);
int
glusterd_volinfo_find_by_volume_id (uuid_t volume_id, glusterd_volinfo_t **volinfo);
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
index 8bb0b6d..94e07cb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
@@ -1828,7 +1828,7 @@ glusterd_op_stage_delete_volume (dict_t *dict, char **op_errstr)
snprintf (msg, sizeof(msg), "Some of the peers are down");
goto out;
}
-
+ volinfo->stage_deleted = _gf_true;
ret = 0;
out:
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 4ec609f..d4f4f7e 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -475,6 +475,9 @@ struct glusterd_volinfo_ {
glusterd_snapdsvc_t snapd;
glusterd_tierdsvc_t tierd;
int32_t quota_xattr_version;
+ gf_boolean_t stage_deleted; /* volume has passed staging
+ * for delete operation
+ */
};
typedef enum gd_snap_status_ {
--
1.8.3.1

View File

@ -0,0 +1,79 @@
From d67fddc4e6439f6aadd76da1a2058ffb7a4940d4 Mon Sep 17 00:00:00 2001
From: Atin Mukherjee <amukherj@redhat.com>
Date: Fri, 31 Aug 2018 20:42:21 +0530
Subject: [PATCH 366/385] glusterd: fail volume stop operation if brick detach
fails
While sending a detach request for a brick in brick multiplexing mode,
in any situation if the brick isn't connected, glusterd will fail to
detach the brick but due to the missing error code handling, glusterd
will mark the volume as stopped.
Fix is to handle the return code of send_attach_req in
glusterd_volume_stop_glusterfs ()
>upstream patch : https://review.gluster.org/#/c/glusterfs/+/21055/
>Change-Id: I886202969c96eec3620f74cd7027652d6287f4be
>Fixes: bz#1624440
>Signed-off-by: Atin Mukherjee <amukherj@redhat.com>
Change-Id: I886202969c96eec3620f74cd7027652d6287f4be
BUG: 1624444
Signed-off-by: Atin Mukherjee <amukherj@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/149873
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
xlators/mgmt/glusterd/src/glusterd-utils.c | 31 +++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 7f52602..3db3a15 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -2496,19 +2496,32 @@ glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo,
* an actual signal instead.
*/
if (is_brick_mx_enabled ()) {
- gf_msg_debug (this->name, 0, "About to send detach "
- "request for brick %s:%s",
- brickinfo->hostname, brickinfo->path);
-
- (void) send_attach_req (this, brickinfo->rpc,
- brickinfo->path, NULL, NULL,
- GLUSTERD_BRICK_TERMINATE);
+ ret = send_attach_req (this, brickinfo->rpc,
+ brickinfo->path, NULL, NULL,
+ GLUSTERD_BRICK_TERMINATE);
+ if (ret && brickinfo->status == GF_BRICK_STARTED) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_BRICK_STOP_FAIL, "Failed to send"
+ " detach request for brick %s",
+ brickinfo->path);
+ goto out;
+ }
+ gf_log (this->name, GF_LOG_INFO, "Detach request for "
+ "brick %s:%s is sent successfully",
+ brickinfo->hostname, brickinfo->path);
} else {
gf_msg_debug (this->name, 0, "About to stop glusterfsd"
" for brick %s:%s", brickinfo->hostname,
brickinfo->path);
- (void) glusterd_brick_terminate (volinfo, brickinfo,
- NULL, 0, &op_errstr);
+ ret = glusterd_brick_terminate (volinfo, brickinfo,
+ NULL, 0, &op_errstr);
+ if (ret && brickinfo->status == GF_BRICK_STARTED) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ GD_MSG_BRICK_STOP_FAIL, "Failed to kill"
+ " the brick %s", brickinfo->path);
+ goto out;
+ }
+
if (op_errstr) {
GF_FREE (op_errstr);
}
--
1.8.3.1

View File

@ -0,0 +1,202 @@
From b2a0656b409cf867073c961fa4103bc59966a059 Mon Sep 17 00:00:00 2001
From: Ashish Pandey <aspandey@redhat.com>
Date: Mon, 3 Sep 2018 14:01:23 +0530
Subject: [PATCH 367/385] cluster/ec: Improve logging for some critical error
messages
>Change-Id: I037e52a3467467b81a1ba5416317870864060d4d
>updates: bz#1615703
>Signed-off-by: Ashish Pandey <aspandey@redhat.com>
upstream patch: https://review.gluster.org/#/c/glusterfs/+/21061/
BUG: 1625622
Change-Id: I037e52a3467467b81a1ba5416317870864060d4d
Signed-off-by: Ashish Pandey <aspandey@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/149671
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
xlators/cluster/ec/src/ec-common.c | 66 ++++++++++++++++++++++++++++++--------
xlators/cluster/ec/src/ec-data.c | 1 +
xlators/cluster/ec/src/ec-types.h | 2 ++
3 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c
index b74bce0..6d0eb62 100644
--- a/xlators/cluster/ec/src/ec-common.c
+++ b/xlators/cluster/ec/src/ec-common.c
@@ -587,6 +587,42 @@ ec_internal_op (ec_fop_data_t *fop)
return _gf_false;
}
+char *
+ec_msg_str (ec_fop_data_t *fop)
+{
+ loc_t *loc1 = NULL;
+ loc_t *loc2 = NULL;
+ char gfid1[64] = {0};
+ char gfid2[64] = {0};
+
+ if (fop->errstr)
+ return fop->errstr;
+
+ if (!fop->use_fd) {
+ loc1 = &fop->loc[0];
+ loc2 = &fop->loc[1];
+
+ if (fop->id == GF_FOP_RENAME) {
+ gf_asprintf(&fop->errstr,
+ "FOP : '%s' failed on '%s' and '%s' with gfids "
+ "%s and %s respectively", ec_fop_name (fop->id),
+ loc1->path, loc2->path,
+ uuid_utoa_r (loc1->gfid, gfid1),
+ uuid_utoa_r (loc2->gfid, gfid2));
+ } else {
+ gf_asprintf(&fop->errstr,
+ "FOP : '%s' failed on '%s' with gfid %s",
+ ec_fop_name (fop->id),
+ loc1->path, uuid_utoa_r (loc1->gfid, gfid1));
+ }
+ } else {
+ gf_asprintf(&fop->errstr, "FOP : '%s' failed on gfid %s",
+ ec_fop_name (fop->id),
+ uuid_utoa_r (fop->fd->inode->gfid, gfid1));
+ }
+ return fop->errstr;
+}
+
int32_t ec_child_select(ec_fop_data_t * fop)
{
ec_t * ec = fop->xl->private;
@@ -607,9 +643,8 @@ int32_t ec_child_select(ec_fop_data_t * fop)
gf_msg (fop->xl->name, GF_LOG_WARNING, 0,
EC_MSG_OP_EXEC_UNAVAIL,
"Executing operation with "
- "some subvolumes unavailable "
- "(%lX)", fop->mask & ~ec->xl_up);
-
+ "some subvolumes unavailable. (%lX). %s ",
+ fop->mask & ~ec->xl_up, ec_msg_str(fop));
fop->mask &= ec->xl_up;
}
@@ -650,8 +685,8 @@ int32_t ec_child_select(ec_fop_data_t * fop)
EC_MSG_CHILDS_INSUFFICIENT,
"Insufficient available children "
"for this request (have %d, need "
- "%d)", num, fop->minimum);
-
+ "%d). %s",
+ num, fop->minimum, ec_msg_str(fop));
return 0;
}
@@ -1122,7 +1157,6 @@ ec_prepare_update_cbk (call_frame_t *frame, void *cookie,
gf_boolean_t release = _gf_false;
uint64_t provided_flags = 0;
uint64_t dirty[EC_VERSION_SIZE] = {0, 0};
-
lock = parent_link->lock;
parent = parent_link->fop;
ctx = lock->ctx;
@@ -1139,11 +1173,11 @@ ec_prepare_update_cbk (call_frame_t *frame, void *cookie,
list_add_tail(&link->fop->cbk_list, &list);
}
}
-
if (op_ret < 0) {
gf_msg (this->name, GF_LOG_WARNING, op_errno,
EC_MSG_SIZE_VERS_GET_FAIL,
- "Failed to get size and version");
+ "Failed to get size and version : %s",
+ ec_msg_str(fop));
goto unlock;
}
@@ -1155,7 +1189,8 @@ ec_prepare_update_cbk (call_frame_t *frame, void *cookie,
if (op_errno != 0) {
gf_msg (this->name, GF_LOG_ERROR, op_errno,
EC_MSG_VER_XATTR_GET_FAIL,
- "Unable to get version xattr");
+ "Unable to get version xattr. %s",
+ ec_msg_str(fop));
goto unlock;
}
ctx->post_version[0] += ctx->pre_version[0];
@@ -1171,7 +1206,8 @@ ec_prepare_update_cbk (call_frame_t *frame, void *cookie,
if (lock->loc.inode->ia_type == IA_IFREG) {
gf_msg (this->name, GF_LOG_ERROR, op_errno,
EC_MSG_SIZE_XATTR_GET_FAIL,
- "Unable to get size xattr");
+ "Unable to get size xattr. %s",
+ ec_msg_str(fop));
goto unlock;
}
} else {
@@ -1187,7 +1223,8 @@ ec_prepare_update_cbk (call_frame_t *frame, void *cookie,
(op_errno != ENODATA)) {
gf_msg (this->name, GF_LOG_ERROR, op_errno,
EC_MSG_CONFIG_XATTR_GET_FAIL,
- "Unable to get config xattr");
+ "Unable to get config xattr. %s",
+ ec_msg_str(fop));
goto unlock;
}
@@ -2168,7 +2205,8 @@ int32_t ec_update_size_version_done(call_frame_t * frame, void * cookie,
if (op_ret < 0) {
gf_msg(fop->xl->name, fop_log_level (fop->id, op_errno), op_errno,
EC_MSG_SIZE_VERS_UPDATE_FAIL,
- "Failed to update version and size");
+ "Failed to update version and size. %s",
+ ec_msg_str(fop));
} else {
fop->parent->good &= fop->good;
@@ -2213,7 +2251,6 @@ ec_update_size_version(ec_lock_link_t *link, uint64_t *version,
ec_inode_t *ctx;
dict_t *dict = NULL;
uintptr_t update_on = 0;
-
int32_t err = -ENOMEM;
fop = link->fop;
@@ -2294,7 +2331,8 @@ out:
ec_fop_set_error(fop, -err);
gf_msg (fop->xl->name, GF_LOG_ERROR, -err, EC_MSG_SIZE_VERS_UPDATE_FAIL,
- "Unable to update version and size");
+ "Unable to update version and size. %s",
+ ec_msg_str(fop));
if (lock->unlock_now) {
ec_unlock_lock(fop->data);
diff --git a/xlators/cluster/ec/src/ec-data.c b/xlators/cluster/ec/src/ec-data.c
index 54c708a..b3b72d5 100644
--- a/xlators/cluster/ec/src/ec-data.c
+++ b/xlators/cluster/ec/src/ec-data.c
@@ -286,6 +286,7 @@ void ec_fop_data_release(ec_fop_data_t * fop)
GF_FREE(fop->str[1]);
loc_wipe(&fop->loc[0]);
loc_wipe(&fop->loc[1]);
+ GF_FREE(fop->errstr);
ec_resume_parent(fop, fop->error);
diff --git a/xlators/cluster/ec/src/ec-types.h b/xlators/cluster/ec/src/ec-types.h
index f6e2cd9..9176dde 100644
--- a/xlators/cluster/ec/src/ec-types.h
+++ b/xlators/cluster/ec/src/ec-types.h
@@ -347,6 +347,8 @@ struct _ec_fop_data {
struct iovec *vector;
struct iobref *buffers;
gf_seek_what_t seek;
+ char *errstr; /*String of fop name, path and gfid
+ to be used in gf_msg. */
};
struct _ec_cbk_data {
--
1.8.3.1

View File

@ -0,0 +1,67 @@
From 3a392704f61915217f4f8210e1dd94901d6938bb Mon Sep 17 00:00:00 2001
From: Raghavendra G <rgowdapp@redhat.com>
Date: Tue, 11 Sep 2018 10:31:27 +0530
Subject: [PATCH 368/385] mount/fuse: convert ENOENT to ESTALE in
open(dir)_resume
This patch is continuation of commit
fb4b914ce84bc83a5f418719c5ba7c25689a9251.
<snip>
mount/fuse: never fail open(dir) with ENOENT
open(dir) being an operation on inode should never fail with
ENOENT. If gfid is not present, the appropriate error is
ESTALE. This will enable kernel to retry open after a revalidate
lookup.
</snip>
Earlier commit failed to fix codepath where error response is sent
back on gfid resolution failures in fuse_open(dir)_resume. Current
patch completes that work
>Change-Id: Ia07e3cece404811703c8cfbac9b402ca5fe98c1e
>Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
>updates: bz#1627620
Change-Id: Ia07e3cece404811703c8cfbac9b402ca5fe98c1e
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
BUG: 1627617
upstream patch: https://review.gluster.org/#/c/glusterfs/+/21146/
Reviewed-on: https://code.engineering.redhat.com/gerrit/150109
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
xlators/mount/fuse/src/fuse-bridge.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index b767ea4..85cee73 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -2235,6 +2235,10 @@ fuse_open_resume (fuse_state_t *state)
"%"PRIu64": OPEN %s resolution failed",
state->finh->unique, uuid_utoa (state->resolve.gfid));
+ /* facilitate retry from VFS */
+ if (state->resolve.op_errno == ENOENT)
+ state->resolve.op_errno = ESTALE;
+
send_fuse_err (state->this, state->finh,
state->resolve.op_errno);
free_fuse_state (state);
@@ -2687,6 +2691,11 @@ fuse_opendir_resume (fuse_state_t *state)
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": OPENDIR (%s) resolution failed",
state->finh->unique, uuid_utoa (state->resolve.gfid));
+
+ /* facilitate retry from VFS */
+ if (state->resolve.op_errno == ENOENT)
+ state->resolve.op_errno = ESTALE;
+
send_fuse_err (state->this, state->finh,
state->resolve.op_errno);
free_fuse_state (state);
--
1.8.3.1

View File

@ -0,0 +1,100 @@
From 62fe36178cab588b658b44808cc954a57a1fc452 Mon Sep 17 00:00:00 2001
From: Kotresh HR <khiremat@redhat.com>
Date: Fri, 10 Aug 2018 08:14:14 -0400
Subject: [PATCH 369/385] geo-rep: Fix deadlock during worker start
Analysis:
Monitor process spawns monitor threads (one per brick).
Each monitor thread, forks worker and agent processes.
Each monitor thread, while intializing, updates the
monitor status file. It is synchronized using flock.
The race is that, some thread can fork worker while
other thread opened the status file resulting in
holding the reference of fd in worker process.
Cause:
flock gets unlocked either by specifically unlocking it
or by closing all duplicate fds referring to the file.
The code was relying on fd close, hence a reference
in worker/agent process by fork could cause the deadlock.
Fix:
1. flock is unlocked specifically.
2. Also made sure to update status file in approriate places so that
the reference is not leaked to worker/agent process.
With this fix, both the deadlock and possible fd
leaks is solved.
Upstream Patch : https://review.gluster.org/#/c/glusterfs/+/20704/
>fixes: bz#1614799
>Signed-off-by: Kotresh HR <khiremat@redhat.com>
Change-Id: I0d1ce93072dab07d0dbcc7e779287368cd9f093d
BUG: 1623749
Signed-off-by: Sunny Kumar <sunkumar@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/149760
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
geo-replication/syncdaemon/gsyncdstatus.py | 1 +
geo-replication/syncdaemon/monitor.py | 17 ++++++++++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/geo-replication/syncdaemon/gsyncdstatus.py b/geo-replication/syncdaemon/gsyncdstatus.py
index 909c669..67493ca 100644
--- a/geo-replication/syncdaemon/gsyncdstatus.py
+++ b/geo-replication/syncdaemon/gsyncdstatus.py
@@ -99,6 +99,7 @@ class LockedOpen(object):
return f
def __exit__(self, _exc_type, _exc_value, _traceback):
+ fcntl.flock(self.fileobj, fcntl.LOCK_UN)
self.fileobj.close()
diff --git a/geo-replication/syncdaemon/monitor.py b/geo-replication/syncdaemon/monitor.py
index 9245572..3451fe4 100644
--- a/geo-replication/syncdaemon/monitor.py
+++ b/geo-replication/syncdaemon/monitor.py
@@ -144,9 +144,6 @@ class Monitor(object):
"%s::%s" % (slave_host,
slave_vol))
- set_monitor_status(gconf.state_file, self.ST_STARTED)
- self.status[w[0]['dir']].set_worker_status(self.ST_INIT)
-
ret = 0
def nwait(p, o=0):
@@ -196,6 +193,7 @@ class Monitor(object):
# Spawn the worker and agent in lock to avoid fd leak
self.lock.acquire()
+ self.status[w[0]['dir']].set_worker_status(self.ST_INIT)
logging.info(lf('starting gsyncd worker',
brick=w[0]['dir'],
slave_node=remote_host))
@@ -375,6 +373,19 @@ class Monitor(object):
t = Thread(target=wmon, args=[wx])
t.start()
ta.append(t)
+
+ # monitor status was being updated in each monitor thread. It
+ # should not be done as it can cause deadlock for a worker start.
+ # set_monitor_status uses flock to synchronize multple instances
+ # updating the file. Since each monitor thread forks worker and
+ # agent, these processes can hold the reference to fd of status
+ # file causing deadlock to workers which starts later as flock
+ # will not be release until all references to same fd is closed.
+ # It will also cause fd leaks.
+
+ self.lock.acquire()
+ set_monitor_status(gconf.get("state-file"), self.ST_STARTED)
+ self.lock.release()
for t in ta:
t.join()
--
1.8.3.1

View File

@ -0,0 +1,460 @@
From f005377a54f01edc046aa668c8ab924a3ddf52bb Mon Sep 17 00:00:00 2001
From: Kotresh HR <khiremat@redhat.com>
Date: Tue, 21 Aug 2018 06:09:44 -0400
Subject: [PATCH 370/385] libgfchangelog: Fix changelog history API
Problem:
If requested start time and end time doesn't fall into
first HTIME file, then history API fails even though
continuous changelogs are avaiable for the requested range
in other HTIME files. This is induced by changelog disable
and enable which creates fresh HTIME index file.
Cause and Analysis:
Each HTIME index file represents the availability of
continuous changelogs. If changelog is disabled and enabled,
a new HTIME index file is created represents non availability
of continuous changelogs. So as long as the requested start
and end falls into single HTIME index file and not across,
history API should succeed.
But History API checks for the changelogs only in first
HTIME index file and errors out if not available.
Fix:
Check in all HTIME index files for availability of continuous
changelogs for requested change.
Upstream Patch : https://review.gluster.org/#/c/glusterfs/+/21016/
>fixes: bz#1622549
>Signed-off-by: Kotresh HR <khiremat@redhat.com>
Change-Id: I80eeceb5afbd1b89f86a9dc4c320e161907d3559
BUG: 1627639
Signed-off-by: Sunny Kumar <sunkumar@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/149768
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
tests/basic/changelog/changelog-history.t | 86 +++++++++++++++
tests/utils/changelog/changelog.h | 120 +++++++++++++++++++++
tests/utils/changelog/get-history.c | 73 +++++++++++++
.../changelog/lib/src/gf-history-changelog.c | 59 ++++++++--
4 files changed, 331 insertions(+), 7 deletions(-)
create mode 100644 tests/basic/changelog/changelog-history.t
create mode 100644 tests/utils/changelog/changelog.h
create mode 100644 tests/utils/changelog/get-history.c
diff --git a/tests/basic/changelog/changelog-history.t b/tests/basic/changelog/changelog-history.t
new file mode 100644
index 0000000..3ce4098
--- /dev/null
+++ b/tests/basic/changelog/changelog-history.t
@@ -0,0 +1,86 @@
+#!/bin/bash
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+. $(dirname $0)/../../env.rc
+
+cleanup;
+
+HISTORY_BIN_PATH=$(dirname $0)/../../utils/changelog
+build_tester $HISTORY_BIN_PATH/get-history.c -lgfchangelog
+
+time_before_enable1=$(date '+%s')
+CHANGELOG_PATH_0="$B0/${V0}0/.glusterfs/changelogs"
+ROLLOVER_TIME=2
+
+TEST glusterd
+TEST pidof glusterd
+
+sleep 3
+time_before_enable2=$(date '+%s')
+
+sleep 3
+TEST $CLI volume create $V0 $H0:$B0/${V0}0
+TEST $CLI volume set $V0 changelog.changelog on
+TEST $CLI volume set $V0 changelog.rollover-time $ROLLOVER_TIME
+TEST $CLI volume start $V0
+
+sleep 3
+time_after_enable1=$(date '+%s')
+
+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0;
+touch $M0/file{1..10}
+
+sleep 3
+time_after_enable2=$(date '+%s')
+
+let time_future=time_after_enable2+600
+
+#Fails as start falls before changelog enable
+EXPECT "-3" $HISTORY_BIN_PATH/get-history $time_before_enable1 $time_before_enable2
+
+#Fails as start falls before changelog enable
+EXPECT "-3" $HISTORY_BIN_PATH/get-history $time_before_enable2 $time_after_enable1
+
+#Passes as start and end falls in same htime file
+EXPECT "0" $HISTORY_BIN_PATH/get-history $time_after_enable1 $time_after_enable2
+
+#Passes, gives the changelogs till continuous changelogs are available
+# but returns 1
+EXPECT "1" $HISTORY_BIN_PATH/get-history $time_after_enable2 $time_future
+
+#Disable and enable changelog
+TEST $CLI volume set $V0 changelog.changelog off
+sleep 6
+time_between_htime=$(date '+%s')
+sleep 6
+TEST $CLI volume set $V0 changelog.changelog on
+
+sleep 6
+touch $M0/test{1..10}
+time_in_sec_htime1=$(date '+%s')
+
+sleep 6
+touch $M0/test1{1..10}
+time_in_sec_htime2=$(date '+%s')
+
+sleep 3
+TEST $CLI volume set $V0 changelog.changelog off
+sleep 3
+time_after_disable=$(date '+%s')
+
+#Passes, gives the changelogs till continuous changelogs are available
+# but returns 1
+EXPECT "1" $HISTORY_BIN_PATH/get-history $time_after_enable1 $time_in_sec_htime2
+
+#Fails as start falls between htime files
+EXPECT "-3" $HISTORY_BIN_PATH/get-history $time_between_htime $time_in_sec_htime1
+
+#Passes as start and end falls in same htime file
+EXPECT "0" $HISTORY_BIN_PATH/get-history $time_in_sec_htime1 $time_in_sec_htime2
+
+#Passes, gives the changelogs till continuous changelogs are available
+EXPECT "0" $HISTORY_BIN_PATH/get-history $time_in_sec_htime2 $time_after_disable
+
+TEST rm $HISTORY_BIN_PATH/get-history
+
+cleanup;
diff --git a/tests/utils/changelog/changelog.h b/tests/utils/changelog/changelog.h
new file mode 100644
index 0000000..14094cf
--- /dev/null
+++ b/tests/utils/changelog/changelog.h
@@ -0,0 +1,120 @@
+/*
+ Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _GF_CHANGELOG_H
+#define _GF_CHANGELOG_H
+
+struct gf_brick_spec;
+
+/**
+ * Max bit shiter for event selection
+ */
+#define CHANGELOG_EV_SELECTION_RANGE 5
+
+#define CHANGELOG_OP_TYPE_JOURNAL (1<<0)
+#define CHANGELOG_OP_TYPE_OPEN (1<<1)
+#define CHANGELOG_OP_TYPE_CREATE (1<<2)
+#define CHANGELOG_OP_TYPE_RELEASE (1<<3)
+#define CHANGELOG_OP_TYPE_BR_RELEASE (1<<4) /* logical release (last close()),
+ sent by bitrot stub */
+#define CHANGELOG_OP_TYPE_MAX (1<<CHANGELOG_EV_SELECTION_RANGE)
+
+
+struct ev_open {
+ unsigned char gfid[16];
+ int32_t flags;
+};
+
+struct ev_creat {
+ unsigned char gfid[16];
+ int32_t flags;
+};
+
+struct ev_release {
+ unsigned char gfid[16];
+};
+
+struct ev_release_br {
+ unsigned long version;
+ unsigned char gfid[16];
+ int32_t sign_info;
+};
+
+struct ev_changelog {
+ char path[PATH_MAX];
+};
+
+typedef struct changelog_event {
+ unsigned int ev_type;
+
+ union {
+ struct ev_open open;
+ struct ev_creat create;
+ struct ev_release release;
+ struct ev_changelog journal;
+ struct ev_release_br releasebr;
+ } u;
+} changelog_event_t;
+
+#define CHANGELOG_EV_SIZE (sizeof (changelog_event_t))
+
+/**
+ * event callback, connected & disconnection defs
+ */
+typedef void (CALLBACK) (void *, char *,
+ void *, changelog_event_t *);
+typedef void *(INIT) (void *, struct gf_brick_spec *);
+typedef void (FINI) (void *, char *, void *);
+typedef void (CONNECT) (void *, char *, void *);
+typedef void (DISCONNECT) (void *, char *, void *);
+
+struct gf_brick_spec {
+ char *brick_path;
+ unsigned int filter;
+
+ INIT *init;
+ FINI *fini;
+ CALLBACK *callback;
+ CONNECT *connected;
+ DISCONNECT *disconnected;
+
+ void *ptr;
+};
+
+/* API set */
+
+int
+gf_changelog_register (char *brick_path, char *scratch_dir,
+ char *log_file, int log_levl, int max_reconnects);
+ssize_t
+gf_changelog_scan ();
+
+int
+gf_changelog_start_fresh ();
+
+ssize_t
+gf_changelog_next_change (char *bufptr, size_t maxlen);
+
+int
+gf_changelog_done (char *file);
+
+/* newer flexible API */
+int
+gf_changelog_init (void *xl);
+
+int
+gf_changelog_register_generic (struct gf_brick_spec *bricks, int count,
+ int ordered, char *logfile, int lvl, void *xl);
+
+int
+gf_history_changelog (char *changelog_dir, unsigned long start,
+ unsigned long end, int n_parallel,
+ unsigned long *actual_end);
+#endif
diff --git a/tests/utils/changelog/get-history.c b/tests/utils/changelog/get-history.c
new file mode 100644
index 0000000..29dc609
--- /dev/null
+++ b/tests/utils/changelog/get-history.c
@@ -0,0 +1,73 @@
+/*
+ Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+/**
+ * get set of new changes every 10 seconds (just print the file names)
+ *
+ * Compile it using:
+ * gcc -o gethistory `pkg-config --cflags libgfchangelog` get-history.c \
+ * `pkg-config --libs libgfchangelog`
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/un.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include "changelog.h"
+
+int
+main (int argc, char **argv)
+{
+ int ret = 0;
+ unsigned long end_ts = 0;
+ int start = 0;
+ int end = 0;
+
+ ret = gf_changelog_init (NULL);
+ if (ret) {
+ printf ("-1");
+ fflush(stdout);
+ return -1;
+ }
+
+ ret = gf_changelog_register ("/d/backends/patchy0",
+ "/tmp/scratch_v1",
+ "/var/log/glusterfs/changes.log",
+ 9, 5);
+ if (ret) {
+ printf ("-2");
+ fflush(stdout);
+ return -1;
+ }
+
+ start = atoi(argv[1]);
+ end = atoi(argv[2]);
+
+ ret = gf_history_changelog ("/d/backends/patchy0/.glusterfs/changelogs",
+ start, end, 3, &end_ts);
+ if (ret < 0) {
+ printf ("-3");
+ fflush(stdout);
+ return -1;
+ } else if (ret == 1) {
+ printf ("1");
+ fflush(stdout);
+ return 0;
+ }
+
+out:
+ printf ("0");
+ fflush(stdout);
+ return 0;
+}
diff --git a/xlators/features/changelog/lib/src/gf-history-changelog.c b/xlators/features/changelog/lib/src/gf-history-changelog.c
index 4355396..c1a7070 100644
--- a/xlators/features/changelog/lib/src/gf-history-changelog.c
+++ b/xlators/features/changelog/lib/src/gf-history-changelog.c
@@ -772,6 +772,15 @@ gf_changelog_extract_min_max (const char *dname, const char *htime_dir,
return ret;
}
+/* gf_history_changelog returns actual_end and spawns threads to
+ * parse historical changelogs. The return values are as follows.
+ * 0 : On success
+ * 1 : Successful, but partial historical changelogs available,
+ * end time falls into different htime file or future time
+ * -2 : Error, requested historical changelog not available, not
+ * even partial
+ * -1 : On any error
+ */
int
gf_history_changelog (char* changelog_dir, unsigned long start,
unsigned long end, int n_parallel,
@@ -799,6 +808,7 @@ gf_history_changelog (char* changelog_dir, unsigned long start,
pthread_t consume_th = 0;
char htime_dir[PATH_MAX] = {0,};
char buffer[PATH_MAX] = {0,};
+ gf_boolean_t partial_history = _gf_false;
pthread_attr_t attr;
@@ -828,6 +838,11 @@ gf_history_changelog (char* changelog_dir, unsigned long start,
goto out;
}
+ gf_smsg (this->name, GF_LOG_INFO, 0,
+ CHANGELOG_LIB_MSG_TOTAL_LOG_INFO,
+ "Requesting historical changelogs",
+ "start=%lu", start, "end=%lu", end, NULL);
+
/* basic sanity check */
if (start > end || n_parallel <= 0) {
gf_msg (this->name, GF_LOG_ERROR, errno,
@@ -860,8 +875,14 @@ gf_history_changelog (char* changelog_dir, unsigned long start,
entry = sys_readdir (dirp, scratch);
- if (!entry || errno != 0)
+ if (!entry || errno != 0) {
+ gf_smsg (this->name, GF_LOG_ERROR, errno,
+ CHANGELOG_LIB_MSG_HIST_FAILED,
+ "Requested changelog range is not availbale",
+ "start=%lu", start, "end=%lu", end, NULL);
+ ret = -2;
break;
+ }
ret = gf_changelog_extract_min_max (entry->d_name, htime_dir,
&fd, &total_changelog,
@@ -906,6 +927,23 @@ gf_history_changelog (char* changelog_dir, unsigned long start,
end2 = (end <= max_ts) ? end : max_ts;
+ /* Check if end falls out of same HTIME file. The end
+ * falling to a different htime file or changelog
+ * disable-enable is detected only after 20 seconds.
+ * This is required because, applications generally
+ * asks historical changelogs till current time and
+ * it is possible changelog is not rolled over yet.
+ * So, buffer time of default rollover time plus 5
+ * seconds is subtracted. If the application requests
+ * the end time with in half a minute of changelog
+ * disable, it's not detected as changelog disable and
+ * it's application's responsibility to retry after
+ * 20 seconds before confirming it as partial history.
+ */
+ if ((end - 20) > max_ts) {
+ partial_history = _gf_true;
+ }
+
/**
* search @end2 in htime file returning it's index (@to)
*/
@@ -972,12 +1010,15 @@ gf_history_changelog (char* changelog_dir, unsigned long start,
goto out;
} else {/* end of range check */
- gf_msg (this->name, GF_LOG_ERROR, errno,
- CHANGELOG_LIB_MSG_HIST_FAILED, "Requested changelog "
- "range is not available. START - %lu CHLOG_MIN - %lu "
- "CHLOG_MAX - %lu", start, min_ts, max_ts);
- ret = -2;
- goto out;
+ gf_smsg (this->name, GF_LOG_ERROR, errno,
+ CHANGELOG_LIB_MSG_HIST_FAILED,
+ "Requested changelog range is not "
+ "available. Retrying next HTIME",
+ "start=%lu", start,
+ "end=%lu", end,
+ "chlog_min=%lu", min_ts,
+ "chlog_max=%lu", max_ts,
+ NULL);
}
} /* end of readdir() */
@@ -1000,5 +1041,9 @@ out:
hist_jnl->hist_done = 1;
*actual_end = ts2;
+ if (partial_history) {
+ ret = 1;
+ }
+
return ret;
}
--
1.8.3.1

View File

@ -0,0 +1,88 @@
From c1d83132c4b2d49eb922fb7fe42952856aeff83d Mon Sep 17 00:00:00 2001
From: Raghavendra G <rgowdapp@redhat.com>
Date: Sat, 8 Sep 2018 19:53:07 +0530
Subject: [PATCH 371/385] performance/write-behind: remove the request from wip
queue in wb_fulfill_request
The bug is very similar to bz 1379655 and the fix too very similar to
commit a8b2a981881221925bb5edfe7bb65b25ad855c04.
Before this patch, a request is removed from wip queue only when ref
count of request hits 0. Though, wb_fulfill_request does an unref,
it need not be the last unref and hence the request may survive in
wip queue till the last unref. Let,
T1: the time at which wb_fulfill_request is invoked
T2: the time at which last unref is done on request
Let's consider a case of T2 > T1. In the time window between T1 and
T2, any other request (waiter) conflicting with request in liability
queue (blocker - basically a write which has been lied) is blocked
from winding. If T2 happens to be when wb_do_unwinds is invoked, no
further processing of request list happens and "waiter" would get
blocked forever. An example imaginary sequence of events is given
below:
1. A write request w1 is picked up for winding in __wb_pick_winds
and w1 is moved to wip queue. Let's call this
invocation of wb_process_queue by wb_writev as PQ1. Note w1 is not
unwound.
2. A dependent write (w2) hits write-behind and is unwound followed by
a flush (f1) request. Since the liability queue
of inode is not empty, w2 and f1 are not picked for unwinding. Let's call
the invocation of wb_process_queue by wb_flush as PQ2. Note that
invocation of wb_process_queue by w2 doesn't wind w2 instead
unwinds it after which we hit PQ2
3. PQ2 continues and picks w1 for fulfilling and invokes
wb_fulfill. As part of successful wb_fulfill_cbk,
wb_fulfill_request (w1) is invoked. But, w1 is not freed (and hence
not removed from wip queue) as w1 is not unwound _yet_ and a
ref remains (PQ1 has not invoked wb_do_unwinds _yet_).
4. wb_fulfill_cbk (triggered by PQ2) invokes a wb_process_queue (let's
say PQ3). w2 is not picked up for winding in PQ3 as w1 is still in wip
queue. At this time, PQ2 and PQ3 are complete.
5. PQ1 continues, unwinds w1 and does last unref on w1 and w1 is freed
(and removed from wip queue). Since PQ1 didn't invoke
wb_fulfill on any other write requests, there won't be any future
codepaths that would invoke wb_process_queue and w2 is stuck
forever. This will prevent f2 too and hence close syscall is hung
With this fix, w1 is removed from liability queue in step 3 above and
PQ3 winds w2 in step 4 (as there are no requests conflicting with w2
in liability queue during execution of PQ3). Once w2 is complete, f1
is resumed.
>Change-Id: Ia972fad0858dc4abccdc1227cb4d880f85b3b89b
>Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
>Fixes: bz#1626787
Change-Id: Ia972fad0858dc4abccdc1227cb4d880f85b3b89b
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
BUG: 1626780
upstream patch: https://review.gluster.org/21123
Reviewed-on: https://code.engineering.redhat.com/gerrit/149775
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
xlators/performance/write-behind/src/write-behind.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c
index ca1cb63..478985a 100644
--- a/xlators/performance/write-behind/src/write-behind.c
+++ b/xlators/performance/write-behind/src/write-behind.c
@@ -725,6 +725,7 @@ __wb_fulfill_request (wb_request_t *req)
*/
}
+ list_del_init (&req->wip);
__wb_request_unref (req);
}
--
1.8.3.1

View File

@ -0,0 +1,48 @@
From 9e95bd4e3b2e64880a3522520b05d23cf29b3d91 Mon Sep 17 00:00:00 2001
From: Amar Tumballi <amarts@redhat.com>
Date: Mon, 10 Sep 2018 09:28:28 +0530
Subject: [PATCH 372/385] Revert "posix: disable block and character files"
This reverts commit d542543faf4eca04737ddfe215e8988a700caf42.
BUG: 1622649
Change-Id: Ib51b798df25ff606e6bdef72aba679a1d97f98d1
Signed-off-by: Amar Tumballi <amarts@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/149666
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
xlators/storage/posix/src/posix.c | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 5088469..e0165f8 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -1453,23 +1453,6 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
}
- if (((mode & S_IFMT) == S_IFBLK) || ((mode & S_IFMT) == S_IFCHR)) {
- /* Man page 'man 2 mknod':
- EPERM mode requested creation of something other than
- a regular file, FIFO (named pipe), or UNIX domain socket,
- and the caller is not privileged (Linux: does not have the
- CAP_MKNOD capability); also returned if the filesystem
- containing pathname does not support the type of node
- requested.
- */
- op_ret = -1;
- op_errno = EPERM;
- gf_msg (this->name, GF_LOG_ERROR, op_errno, P_MSG_MKNOD_FAILED,
- "%s: mknod failed as Block and Character devices "
- "are not supported on GlusterFS", real_path);
- goto out;
- }
-
op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
if (op_ret == -1) {
op_errno = errno;
--
1.8.3.1

View File

@ -0,0 +1,95 @@
From 3d81f70f181793c6b1fd6b53523158fd663b8c74 Mon Sep 17 00:00:00 2001
From: Amar Tumballi <amarts@redhat.com>
Date: Wed, 5 Sep 2018 19:03:08 +0530
Subject: [PATCH 373/385] posix: disable open/read/write on special files
In the file system, the responsibility w.r.to the block and char device
files is related to only support for 'creating' them (using mknod(2)).
Once the device files are created, the read/write syscalls for the specific
devices are handled by the device driver registered for the specific major
number, and depending on the minor number, it knows where to read from.
Hence, we are at risk of reading contents from devices which are handled
by the host kernel on server nodes.
By disabling open/read/write on the device file, we would be safe with
the bypass one can achieve from client side (using gfapi)
Upstream Fix
Upstream Patch: https://review.gluster.org/#/c/glusterfs/+/21069/
> Change-Id: I48c776b0af1cbd2a5240862826d3d8918601e47f
> BUG: 1625648
BUG: 1622649
Change-Id: I1135e89270fac05ccfb8a3faa9fdffb58eb51b15
Signed-off-by: Amar Tumballi <amarts@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/149667
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
xlators/storage/posix/src/posix.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index e0165f8..efbf804 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -3336,6 +3336,17 @@ posix_open (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
+ if (loc->inode &&
+ ((loc->inode->ia_type == IA_IFBLK) ||
+ (loc->inode->ia_type == IA_IFCHR))) {
+ gf_msg (this->name, GF_LOG_ERROR, EINVAL,
+ P_MSG_INVALID_ARGUMENT,
+ "open received on a block/char file (%s)",
+ uuid_utoa (loc->inode->gfid));
+ op_errno = EINVAL;
+ goto out;
+ }
+
if (flags & O_CREAT)
DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out);
@@ -3428,6 +3439,17 @@ posix_readv (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
+ if (fd->inode &&
+ ((fd->inode->ia_type == IA_IFBLK) ||
+ (fd->inode->ia_type == IA_IFCHR))) {
+ gf_msg (this->name, GF_LOG_ERROR, EINVAL,
+ P_MSG_INVALID_ARGUMENT,
+ "readv received on a block/char file (%s)",
+ uuid_utoa (fd->inode->gfid));
+ op_errno = EINVAL;
+ goto out;
+ }
+
ret = posix_fd_ctx_get (fd, this, &pfd, &op_errno);
if (ret < 0) {
gf_msg (this->name, GF_LOG_WARNING, op_errno, P_MSG_PFD_NULL,
@@ -3674,6 +3696,18 @@ posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
+
+ if (fd->inode &&
+ ((fd->inode->ia_type == IA_IFBLK) ||
+ (fd->inode->ia_type == IA_IFCHR))) {
+ gf_msg (this->name, GF_LOG_ERROR, EINVAL,
+ P_MSG_INVALID_ARGUMENT,
+ "writev received on a block/char file (%s)",
+ uuid_utoa (fd->inode->gfid));
+ op_errno = EINVAL;
+ goto out;
+ }
+
DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out);
ret = posix_fd_ctx_get (fd, this, &pfd, &op_errno);
--
1.8.3.1

View File

@ -0,0 +1,64 @@
From 74aaa257df25b70711bf962642ab2f8b3d063634 Mon Sep 17 00:00:00 2001
From: Xavi Hernandez <xhernandez@redhat.com>
Date: Thu, 13 Sep 2018 15:44:15 +0200
Subject: [PATCH 374/385] socket: set 42 as default tpc-user-timeout
> Upstream: https://review.gluster.org/21170
> BUG: 1628605
> Change-Id: Ib8ad7c4ac6aac725b01a78f8c3d10cf4063d2ee6
The 'tcp-user-timeout' option is define in the 'socket' module, but it's
configured in 'protocol/server' and 'protocol/client', which are the
parents of the 'socket' module.
However, current options management logic only takes into consideration
default values specified in the 'socket' module itself, ignoring values
defined in the owner xlator.
This patch simply sets the default value of tcp-user-timeout in the
'socket' module so that server and client use the expected value.
Change-Id: Ib8ad7c4ac6aac725b01a78f8c3d10cf4063d2ee6
BUG: 1623874
Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150699
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
rpc/rpc-transport/socket/src/socket.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c
index b98efdc..243d49c 100644
--- a/rpc/rpc-transport/socket/src/socket.c
+++ b/rpc/rpc-transport/socket/src/socket.c
@@ -3854,7 +3854,7 @@ reconfigure (rpc_transport_t *this, dict_t *options)
int ret = 0;
uint32_t backlog = 0;
uint64_t windowsize = 0;
- uint32_t timeout = 0;
+ uint32_t timeout = 42;
int keepaliveidle = GF_KEEPALIVE_TIME;
int keepaliveintvl = GF_KEEPALIVE_INTERVAL;
int keepalivecnt = GF_KEEPALIVE_COUNT;
@@ -4083,7 +4083,7 @@ socket_init (rpc_transport_t *this)
gf_boolean_t tmp_bool = 0;
uint64_t windowsize = GF_DEFAULT_SOCKET_WINDOW_SIZE;
char *optstr = NULL;
- uint32_t timeout = 0;
+ uint32_t timeout = 42;
int keepaliveidle = GF_KEEPALIVE_TIME;
int keepaliveintvl = GF_KEEPALIVE_INTERVAL;
int keepalivecnt = GF_KEEPALIVE_COUNT;
@@ -4623,7 +4623,7 @@ struct volume_options options[] = {
},
{ .key = {"transport.tcp-user-timeout"},
.type = GF_OPTION_TYPE_INT,
- .default_value = "0"
+ .default_value = "42"
},
{ .key = {"transport.socket.nodelay"},
.type = GF_OPTION_TYPE_BOOL,
--
1.8.3.1

View File

@ -0,0 +1,40 @@
From b83b8efcf0673233bd28cddac4d62a639784a5c0 Mon Sep 17 00:00:00 2001
From: Krutika Dhananjay <kdhananj@redhat.com>
Date: Wed, 19 Sep 2018 15:49:27 +0530
Subject: [PATCH 375/385] extras: Add new options to group "virt"
> Upstream: https://review.gluster.org/21222
> BUG: 1630798
> Change-Id: I231db309de0e37c79cd44f5666da4cd776fefa04
In some of the recent performance tests on gluster-as-vm-image-store
use-case, it has been observed that sometimes the lone fuse thread can
hit near-100% CPU utilization and become a performance bottleneck.
Enabling client-io-threads (in addition to bumping up epoll threads on
server and client side) has shown to be helpful in getting around this
bottleneck and pushing more IOPs.
Change-Id: I231db309de0e37c79cd44f5666da4cd776fefa04
BUG: 1619627
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150696
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
extras/group-virt.example | 3 +++
1 file changed, 3 insertions(+)
diff --git a/extras/group-virt.example b/extras/group-virt.example
index 7e34b72..c2ce89d 100644
--- a/extras/group-virt.example
+++ b/extras/group-virt.example
@@ -13,3 +13,6 @@ cluster.shd-wait-qlength=10000
features.shard=on
user.cifs=off
cluster.choose-local=off
+client.event-threads=4
+server.event-threads=4
+performance.client-io-threads=on
--
1.8.3.1

View File

@ -0,0 +1,193 @@
From f0e9776dd915c70bd9acb4e9624e8e2fd91ae7b7 Mon Sep 17 00:00:00 2001
From: Kotresh HR <khiremat@redhat.com>
Date: Tue, 19 Dec 2017 07:21:07 -0500
Subject: [PATCH 376/385] rchecksum/fips: Replace MD5 usage to enable fips
support
rchecksum uses MD5 which is not fips compliant. Hence
using sha256 for the same.
Backport of:
> Patch: https://review.gluster.org/19052
> Updates: #230
> Change-Id: I7fad016fcc2a9900395d0da919cf5ba996ec5278
> Signed-off-by: Kotresh HR <khiremat@redhat.com>
BUG: 1459709
Change-Id: I7fad016fcc2a9900395d0da919cf5ba996ec5278
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/149771
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
libglusterfs/src/checksum.c | 8 +++++---
libglusterfs/src/default-args.c | 2 +-
xlators/cluster/afr/src/afr-self-heal-common.c | 2 +-
xlators/cluster/afr/src/afr-self-heal-data.c | 4 ++--
xlators/cluster/afr/src/afr.h | 2 +-
xlators/mgmt/glusterd/src/glusterd-utils.c | 2 +-
xlators/protocol/server/src/server-common.c | 2 +-
xlators/storage/bd/src/bd.c | 4 +---
xlators/storage/posix/src/posix.c | 3 +--
9 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/libglusterfs/src/checksum.c b/libglusterfs/src/checksum.c
index 5fac133..a7f9877 100644
--- a/libglusterfs/src/checksum.c
+++ b/libglusterfs/src/checksum.c
@@ -8,9 +8,10 @@
cases as published by the Free Software Foundation.
*/
-#include <openssl/md5.h>
+#include <openssl/sha.h>
#include <zlib.h>
#include <stdint.h>
+#include <string.h>
/*
* The "weak" checksum required for the rsync algorithm.
@@ -30,7 +31,8 @@ gf_rsync_weak_checksum (unsigned char *buf, size_t len)
* The "strong" checksum required for the rsync algorithm.
*/
void
-gf_rsync_strong_checksum (unsigned char *data, size_t len, unsigned char *md5)
+gf_rsync_strong_checksum (unsigned char *data, size_t len,
+ unsigned char *sha256_md)
{
- MD5 (data, len, md5);
+ SHA256((const unsigned char *)data, len, sha256_md);
}
diff --git a/libglusterfs/src/default-args.c b/libglusterfs/src/default-args.c
index f40de2d..3ccf52a 100644
--- a/libglusterfs/src/default-args.c
+++ b/libglusterfs/src/default-args.c
@@ -1140,7 +1140,7 @@ args_rchecksum_cbk_store (default_args_cbk_t *args,
args->weak_checksum =
weak_checksum;
args->strong_checksum =
- memdup (strong_checksum, MD5_DIGEST_LENGTH);
+ memdup (strong_checksum, SHA256_DIGEST_LENGTH);
}
if (xdata)
args->xdata = dict_ref (xdata);
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index 50989d6..2989b9e 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -665,7 +665,7 @@ afr_reply_copy (struct afr_reply *dst, struct afr_reply *src)
if (dst->xdata)
dict_unref (dst->xdata);
dst->xdata = xdata;
- memcpy (dst->checksum, src->checksum, MD5_DIGEST_LENGTH);
+ memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH);
}
void
diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c
index 3ef7376..dd44deb 100644
--- a/xlators/cluster/afr/src/afr-self-heal-data.c
+++ b/xlators/cluster/afr/src/afr-self-heal-data.c
@@ -42,7 +42,7 @@ __checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
replies[i].buf_has_zeroes = dict_get_str_boolean (xdata,
"buf-has-zeroes", _gf_false);
if (strong)
- memcpy (local->replies[i].checksum, strong, MD5_DIGEST_LENGTH);
+ memcpy (local->replies[i].checksum, strong, SHA256_DIGEST_LENGTH);
syncbarrier_wake (&local->barrier);
return 0;
@@ -92,7 +92,7 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (local->replies[i].valid) {
if (memcmp (local->replies[source].checksum,
local->replies[i].checksum,
- MD5_DIGEST_LENGTH)) {
+ SHA256_DIGEST_LENGTH)) {
checksum_match = _gf_false;
break;
}
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index 35928a9..7cb6f00 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -271,7 +271,7 @@ struct afr_reply {
struct iatt preparent2;
struct iatt postparent2;
/* For rchecksum */
- uint8_t checksum[MD5_DIGEST_LENGTH];
+ uint8_t checksum[SHA256_DIGEST_LENGTH];
gf_boolean_t buf_has_zeroes;
/* For lookup */
int8_t need_heal;
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 3db3a15..2a176be 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -1873,7 +1873,7 @@ glusterd_set_brick_socket_filepath (glusterd_volinfo_t *volinfo,
char sock_filepath[PATH_MAX] = {0,};
expected_file_len = strlen (GLUSTERD_SOCK_DIR) + strlen ("/") +
- MD5_DIGEST_LENGTH*2 + strlen (".socket") + 1;
+ SHA256_DIGEST_LENGTH*2 + strlen (".socket") + 1;
GF_ASSERT (len >= expected_file_len);
this = THIS;
GF_ASSERT (this);
diff --git a/xlators/protocol/server/src/server-common.c b/xlators/protocol/server/src/server-common.c
index ce33089..9c38706 100644
--- a/xlators/protocol/server/src/server-common.c
+++ b/xlators/protocol/server/src/server-common.c
@@ -298,7 +298,7 @@ server_post_rchecksum (gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum,
rsp->weak_checksum = weak_checksum;
rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum;
- rsp->strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH;
+ rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH;
}
diff --git a/xlators/storage/bd/src/bd.c b/xlators/storage/bd/src/bd.c
index af3ac84..64b34d9 100644
--- a/xlators/storage/bd/src/bd.c
+++ b/xlators/storage/bd/src/bd.c
@@ -2148,7 +2148,7 @@ bd_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
char *buf = NULL;
int32_t weak_checksum = 0;
bd_fd_t *bd_fd = NULL;
- unsigned char strong_checksum[MD5_DIGEST_LENGTH] = {0};
+ unsigned char strong_checksum[SHA256_DIGEST_LENGTH] = {0};
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -2162,8 +2162,6 @@ bd_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
return 0;
}
- memset (strong_checksum, 0, MD5_DIGEST_LENGTH);
-
alloc_buf = page_aligned_alloc (len, &buf);
if (!alloc_buf) {
op_errno = ENOMEM;
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index efbf804..4e13465 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -7000,7 +7000,7 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
ssize_t bytes_read = 0;
int32_t weak_checksum = 0;
int32_t zerofillcheck = 0;
- unsigned char strong_checksum[MD5_DIGEST_LENGTH] = {0};
+ unsigned char strong_checksum[SHA256_DIGEST_LENGTH] = {0};
struct posix_private *priv = NULL;
dict_t *rsp_xdata = NULL;
gf_boolean_t buf_has_zeroes = _gf_false;
@@ -7010,7 +7010,6 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (fd, out);
priv = this->private;
- memset (strong_checksum, 0, MD5_DIGEST_LENGTH);
alloc_buf = _page_aligned_alloc (len, &buf);
if (!alloc_buf) {
--
1.8.3.1

View File

@ -0,0 +1,122 @@
From a75391899459f6123721631613c5d044fc4795af Mon Sep 17 00:00:00 2001
From: Kotresh HR <khiremat@redhat.com>
Date: Wed, 20 Dec 2017 15:24:11 +0530
Subject: [PATCH 377/385] fips/geo-rep: Replace MD5 with SHA256
MD5 is not fips compliant. Hence replacing
with SHA256.
NOTE:
The hash is used to form the ctl_path for the ssh connection.
The length of ctl_path for ssh connection should not be > 108.
ssh fails with ctl_path too long if it is so. But when rsync
is piped to ssh, it is not taking > 90. rsync is failing with
error number 12. Hence using first 32 bytes of hash. Hash
collision doesn't matter as only one sock file is created
per directory.
Backport of:
> Patch: https://review.gluster.org/19061
> Updates: #230
> Change-Id: I58aeb32a80b5422f6ac0188cf33fbecccbf08ae7
> Signed-off-by: Kotresh HR <khiremat@redhat.com>
BUG: 1459709
Change-Id: I58aeb32a80b5422f6ac0188cf33fbecccbf08ae7
Signed-off-by: Kotresh HR <khiremat@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/149772
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Aravinda Vishwanathapura Krishna Murthy <avishwan@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
geo-replication/syncdaemon/master.py | 4 ++--
geo-replication/syncdaemon/syncdutils.py | 26 ++++++++++++++++----------
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py
index 6de2c77..cd135df 100644
--- a/geo-replication/syncdaemon/master.py
+++ b/geo-replication/syncdaemon/master.py
@@ -23,7 +23,7 @@ from threading import Condition, Lock
from datetime import datetime
from gconf import gconf
from syncdutils import Thread, GsyncdError, boolify, escape_space_newline
-from syncdutils import unescape_space_newline, gauxpfx, md5hex, selfkill
+from syncdutils import unescape_space_newline, gauxpfx, escape1, selfkill
from syncdutils import lstat, errno_wrap, FreeObject, lf, matching_disk_gfid
from syncdutils import NoStimeAvailable, PartialHistoryAvailable
@@ -771,7 +771,7 @@ class GMasterChangelogMixin(GMasterCommon):
selfkill()
def setup_working_dir(self):
- workdir = os.path.join(gconf.working_dir, md5hex(gconf.local_path))
+ workdir = os.path.join(gconf.working_dir, escape1(gconf.local_path))
logging.debug('changelog working dir %s' % workdir)
return workdir
diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py
index d798356..3218192 100644
--- a/geo-replication/syncdaemon/syncdutils.py
+++ b/geo-replication/syncdaemon/syncdutils.py
@@ -60,11 +60,7 @@ try:
except ImportError:
import urllib
-try:
- from hashlib import md5 as md5
-except ImportError:
- # py 2.4
- from md5 import new as md5
+from hashlib import sha256 as sha256
# auxiliary gfid based access prefix
_CL_AUX_GFID_PFX = ".gfid/"
@@ -97,6 +93,8 @@ def escape(s):
to turn whatever data to creatable representation"""
return urllib.quote_plus(s)
+def escape1(s):
+ return s.replace("/", "-").strip("-")
def unescape(s):
"""inverse of .escape"""
@@ -175,13 +173,21 @@ def setup_ssh_ctl(ctld, remote_addr, resource_url):
gconf.ssh_ctl_dir = ctld
content = "SLAVE_HOST=%s\nSLAVE_RESOURCE_URL=%s" % (remote_addr,
resource_url)
- content_md5 = md5hex(content)
+ content_sha256 = sha256hex(content)
+ """
+ The length of ctl_path for ssh connection should not be > 108.
+ ssh fails with ctl_path too long if it is so. But when rsync
+ is piped to ssh, it is not taking > 90. Hence using first 32
+ bytes of hash. Hash collision doesn't matter as only one sock
+ file is created per directory.
+ """
+ content_sha256 = content_sha256[:32]
fname = os.path.join(gconf.ssh_ctl_dir,
- "%s.mft" % content_md5)
+ "%s.mft" % content_sha256)
create_manifest(fname, content)
ssh_ctl_path = os.path.join(gconf.ssh_ctl_dir,
- "%s.sock" % content_md5)
+ "%s.sock" % content_sha256)
gconf.ssh_ctl_args = ["-oControlMaster=auto", "-S", ssh_ctl_path]
@@ -536,8 +542,8 @@ def gauxpfx():
return _CL_AUX_GFID_PFX
-def md5hex(s):
- return md5(s).hexdigest()
+def sha256hex(s):
+ return sha256(s).hexdigest()
def selfkill(sig=SIGTERM):
--
1.8.3.1

View File

@ -0,0 +1,302 @@
From 8c3c6a779b9d1b20c7b413caa25381ab07a08a87 Mon Sep 17 00:00:00 2001
From: Ravishankar N <ravishankar@redhat.com>
Date: Wed, 19 Sep 2018 15:20:27 +0530
Subject: [PATCH 378/385] posix/afr: handle backward compatibility for
rchecksum fop
Patch on upstream master: https://review.gluster.org/#/c/glusterfs/+/19538/
Added a volume option 'fips-mode-rchecksum' tied to op version 4.
If not set, rchecksum fop will use MD5 instead of SHA256.
Change-Id: I720777c0ab36985774e6bb877689fe45b64eb777
BUG: 1459709
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150479
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
libglusterfs/src/checksum.c | 7 +++++
libglusterfs/src/checksum.h | 2 ++
libglusterfs/src/globals.h | 2 ++
xlators/cluster/afr/src/afr-self-heal-common.c | 8 ++++-
xlators/cluster/afr/src/afr-self-heal-data.c | 29 +++++++++++++-----
xlators/cluster/afr/src/afr.h | 1 +
xlators/mgmt/glusterd/src/glusterd-volume-set.c | 6 ++++
xlators/protocol/server/src/server-common.c | 2 +-
xlators/storage/posix/src/posix.c | 39 +++++++++++++++++++++++--
xlators/storage/posix/src/posix.h | 2 ++
10 files changed, 85 insertions(+), 13 deletions(-)
diff --git a/libglusterfs/src/checksum.c b/libglusterfs/src/checksum.c
index a7f9877..561ca04 100644
--- a/libglusterfs/src/checksum.c
+++ b/libglusterfs/src/checksum.c
@@ -8,6 +8,7 @@
cases as published by the Free Software Foundation.
*/
+#include <openssl/md5.h>
#include <openssl/sha.h>
#include <zlib.h>
#include <stdint.h>
@@ -36,3 +37,9 @@ gf_rsync_strong_checksum (unsigned char *data, size_t len,
{
SHA256((const unsigned char *)data, len, sha256_md);
}
+
+void
+gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5)
+{
+ MD5 (data, len, md5);
+}
diff --git a/libglusterfs/src/checksum.h b/libglusterfs/src/checksum.h
index bf7eeed..677a59a 100644
--- a/libglusterfs/src/checksum.h
+++ b/libglusterfs/src/checksum.h
@@ -17,4 +17,6 @@ gf_rsync_weak_checksum (unsigned char *buf, size_t len);
void
gf_rsync_strong_checksum (unsigned char *buf, size_t len, unsigned char *sum);
+void
+gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5);
#endif /* __CHECKSUM_H__ */
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
index 39d9716..e810ea7 100644
--- a/libglusterfs/src/globals.h
+++ b/libglusterfs/src/globals.h
@@ -109,6 +109,8 @@
#define GD_OP_VERSION_3_13_2 31302 /* Op-version for GlusterFS 3.13.2 */
+#define GD_OP_VERSION_4_0_0 40000 /* Op-version for GlusterFS 4.0.0 */
+
/* Downstream only change */
#define GD_OP_VERSION_3_11_2 31102 /* Op-version for RHGS 3.3.1-async */
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index 2989b9e..7e6a691 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -665,7 +665,13 @@ afr_reply_copy (struct afr_reply *dst, struct afr_reply *src)
if (dst->xdata)
dict_unref (dst->xdata);
dst->xdata = xdata;
- memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH);
+ if (xdata && dict_get_str_boolean (xdata, "fips-mode-rchecksum",
+ _gf_false) == _gf_true) {
+ memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH);
+ } else {
+ memcpy (dst->checksum, src->checksum, MD5_DIGEST_LENGTH);
+ }
+ dst->fips_mode_rchecksum = src->fips_mode_rchecksum;
}
void
diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c
index dd44deb..556a8f9 100644
--- a/xlators/cluster/afr/src/afr-self-heal-data.c
+++ b/xlators/cluster/afr/src/afr-self-heal-data.c
@@ -38,11 +38,21 @@ __checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
replies[i].valid = 1;
replies[i].op_ret = op_ret;
replies[i].op_errno = op_errno;
- if (xdata)
+ if (xdata) {
replies[i].buf_has_zeroes = dict_get_str_boolean (xdata,
"buf-has-zeroes", _gf_false);
- if (strong)
- memcpy (local->replies[i].checksum, strong, SHA256_DIGEST_LENGTH);
+ replies[i].fips_mode_rchecksum = dict_get_str_boolean (xdata,
+ "fips-mode-rchecksum", _gf_false);
+ }
+ if (strong) {
+ if (replies[i].fips_mode_rchecksum) {
+ memcpy (local->replies[i].checksum, strong,
+ SHA256_DIGEST_LENGTH);
+ } else {
+ memcpy (local->replies[i].checksum, strong,
+ MD5_DIGEST_LENGTH);
+ }
+ }
syncbarrier_wake (&local->barrier);
return 0;
@@ -58,11 +68,13 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd,
afr_local_t *local = NULL;
unsigned char *wind_subvols = NULL;
gf_boolean_t checksum_match = _gf_true;
+ struct afr_reply *replies = NULL;
dict_t *xdata = NULL;
int i = 0;
priv = this->private;
local = frame->local;
+ replies = local->replies;
xdata = dict_new();
if (!xdata)
@@ -83,16 +95,17 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (xdata)
dict_unref (xdata);
- if (!local->replies[source].valid || local->replies[source].op_ret != 0)
+ if (!replies[source].valid || replies[source].op_ret != 0)
return _gf_false;
for (i = 0; i < priv->child_count; i++) {
if (i == source)
continue;
- if (local->replies[i].valid) {
- if (memcmp (local->replies[source].checksum,
- local->replies[i].checksum,
- SHA256_DIGEST_LENGTH)) {
+ if (replies[i].valid) {
+ if (memcmp (replies[source].checksum,
+ replies[i].checksum,
+ replies[source].fips_mode_rchecksum ?
+ SHA256_DIGEST_LENGTH : MD5_DIGEST_LENGTH)) {
checksum_match = _gf_false;
break;
}
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index 7cb6f00..76ad292 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -273,6 +273,7 @@ struct afr_reply {
/* For rchecksum */
uint8_t checksum[SHA256_DIGEST_LENGTH];
gf_boolean_t buf_has_zeroes;
+ gf_boolean_t fips_mode_rchecksum;
/* For lookup */
int8_t need_heal;
};
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 474587a..0ff512d 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -2868,6 +2868,12 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.voltype = "storage/posix",
.op_version = GD_OP_VERSION_3_13_0,
},
+ { .option = "fips-mode-rchecksum",
+ .key = "storage.fips-mode-rchecksum",
+ .type = NO_DOC,
+ .voltype = "storage/posix",
+ .op_version = GD_OP_VERSION_4_0_0,
+ },
{ .key = "storage.bd-aio",
.voltype = "storage/bd",
.op_version = GD_OP_VERSION_RHS_3_0
diff --git a/xlators/protocol/server/src/server-common.c b/xlators/protocol/server/src/server-common.c
index 9c38706..ce33089 100644
--- a/xlators/protocol/server/src/server-common.c
+++ b/xlators/protocol/server/src/server-common.c
@@ -298,7 +298,7 @@ server_post_rchecksum (gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum,
rsp->weak_checksum = weak_checksum;
rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum;
- rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH;
+ rsp->strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH;
}
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 4e13465..1d3f1ee 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -7000,7 +7000,9 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
ssize_t bytes_read = 0;
int32_t weak_checksum = 0;
int32_t zerofillcheck = 0;
+ unsigned char md5_checksum[MD5_DIGEST_LENGTH] = {0};
unsigned char strong_checksum[SHA256_DIGEST_LENGTH] = {0};
+ unsigned char *checksum = NULL;
struct posix_private *priv = NULL;
dict_t *rsp_xdata = NULL;
gf_boolean_t buf_has_zeroes = _gf_false;
@@ -7069,13 +7071,31 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
}
}
weak_checksum = gf_rsync_weak_checksum ((unsigned char *) buf, (size_t) ret);
- gf_rsync_strong_checksum ((unsigned char *) buf, (size_t) bytes_read,
- (unsigned char *) strong_checksum);
+ if (priv->fips_mode_rchecksum) {
+ ret = dict_set_int32 (rsp_xdata, "fips-mode-rchecksum", 1);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_WARNING, -ret,
+ P_MSG_DICT_SET_FAILED, "%s: Failed to set "
+ "dictionary value for key: %s",
+ uuid_utoa (fd->inode->gfid),
+ "fips-mode-rchecksum");
+ goto out;
+ }
+ checksum = strong_checksum;
+ gf_rsync_strong_checksum ((unsigned char *)buf,
+ (size_t) bytes_read,
+ (unsigned char *)checksum);
+ } else {
+ checksum = md5_checksum;
+ gf_rsync_md5_checksum ((unsigned char *)buf,
+ (size_t) bytes_read,
+ (unsigned char *)checksum);
+ }
op_ret = 0;
out:
STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno,
- weak_checksum, strong_checksum, rsp_xdata);
+ weak_checksum, checksum, rsp_xdata);
if (rsp_xdata)
dict_unref (rsp_xdata);
GF_FREE (alloc_buf);
@@ -7295,6 +7315,9 @@ reconfigure (xlator_t *this, dict_t *options)
GF_OPTION_RECONF ("shared-brick-count", priv->shared_brick_count,
options, int32, out);
+ GF_OPTION_RECONF ("fips-mode-rchecksum", priv->fips_mode_rchecksum,
+ options, bool, out);
+
ret = 0;
out:
return ret;
@@ -7953,6 +7976,9 @@ init (xlator_t *this)
GF_OPTION_INIT ("batch-fsync-delay-usec", _private->batch_fsync_delay_usec,
uint32, out);
+
+ GF_OPTION_INIT ("fips-mode-rchecksum", _private->fips_mode_rchecksum,
+ bool, out);
out:
return ret;
}
@@ -8182,5 +8208,12 @@ struct volume_options options[] = {
" Useful for displaying the proper usable size through statvfs() "
"call (df command)",
},
+ {
+ .key = {"fips-mode-rchecksum"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "If enabled, posix_rchecksum uses the FIPS compliant"
+ "SHA256 checksum. MD5 otherwise."
+ },
{ .key = {NULL} }
};
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index eaf4d0d..bda4172 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -227,6 +227,8 @@ struct posix_private {
/* Option to handle the cases of multiple bricks exported from
same backend. Very much usable in brick-splitting feature. */
int32_t shared_brick_count;
+
+ gf_boolean_t fips_mode_rchecksum;
};
typedef struct {
--
1.8.3.1

View File

@ -0,0 +1,54 @@
From 715d2215da855089245ae7b8c3af719e488a2908 Mon Sep 17 00:00:00 2001
From: Ravishankar N <ravishankar@redhat.com>
Date: Thu, 20 Sep 2018 22:01:05 +0530
Subject: [PATCH 379/385] glusterd: change op-version of fips-mode-rchecksum
..to GD_OP_VERSION_3_13_3 since GD_OP_VERSION_4_0_0 is not present in
rhgs-3.4.1
Label: DOWNSTREAM ONLY
Change-Id: I759272748177d174b15123faffc2305f7a5ec58f
BUG: 1459709
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150714
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
libglusterfs/src/globals.h | 2 +-
xlators/mgmt/glusterd/src/glusterd-volume-set.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
index e810ea7..213f3ce 100644
--- a/libglusterfs/src/globals.h
+++ b/libglusterfs/src/globals.h
@@ -109,10 +109,10 @@
#define GD_OP_VERSION_3_13_2 31302 /* Op-version for GlusterFS 3.13.2 */
-#define GD_OP_VERSION_4_0_0 40000 /* Op-version for GlusterFS 4.0.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*/
#include "xlator.h"
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 0ff512d..5a697cf 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -2872,7 +2872,7 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.key = "storage.fips-mode-rchecksum",
.type = NO_DOC,
.voltype = "storage/posix",
- .op_version = GD_OP_VERSION_4_0_0,
+ .op_version = GD_OP_VERSION_3_13_3,
},
{ .key = "storage.bd-aio",
.voltype = "storage/bd",
--
1.8.3.1

View File

@ -0,0 +1,73 @@
From 8f270fceed4c03ab4405ae65e7e9ce7fce9e008c Mon Sep 17 00:00:00 2001
From: Pranith Kumar K <pkarampu@redhat.com>
Date: Thu, 6 Sep 2018 15:09:42 +0530
Subject: [PATCH 380/385] cluster/afr: Batch writes in same lock even when
multiple fds are open
Problem:
When eager-lock is disabled because of multiple-fds opened and app
writes come on conflicting regions, the number of locks grows very
fast leading to all the CPU being spent just in locking and unlocking
by traversing huge queues in locks xlator for granting locks.
Fix:
Reduce the number of locks in transit by bundling the writes in the
same lock and disable delayed piggy-pack when we learn that multiple
fds are open on the file. This will reduce the size of queues in the
locks xlator. This also reduces the number of network calls like
inodelk/fxattrop.
Please note that this problem can still happen if eager-lock is
disabled as the writes will not be bundled in the same lock.
Upstream-patch: https://review.gluster.org/c/glusterfs/+/21107
BUG: 1630688
Change-Id: I8fd1cf229aed54ce5abd4e6226351a039924dd91
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150700
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
xlators/cluster/afr/src/afr-transaction.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
index 3f55070..85b00a8 100644
--- a/xlators/cluster/afr/src/afr-transaction.c
+++ b/xlators/cluster/afr/src/afr-transaction.c
@@ -2241,9 +2241,6 @@ __need_previous_lock_unlocked (afr_local_t *local)
{
afr_lock_t *lock = NULL;
- if (!local->transaction.eager_lock_on)
- return _gf_true;
-
lock = &local->inode_ctx->lock[local->transaction.type];
if (!lock->acquired)
return _gf_false;
@@ -2260,10 +2257,8 @@ __afr_eager_lock_handle (afr_local_t *local, gf_boolean_t *take_lock,
afr_local_t *owner_local = NULL;
xlator_t *this = local->transaction.frame->this;
- if (local->fd && !afr_are_multiple_fds_opened (local, this)) {
- local->transaction.eager_lock_on = _gf_true;
- afr_set_lk_owner (local->transaction.frame, this, local->inode);
- }
+ local->transaction.eager_lock_on = _gf_true;
+ afr_set_lk_owner (local->transaction.frame, this, local->inode);
lock = &local->inode_ctx->lock[local->transaction.type];
if (__need_previous_lock_unlocked (local)) {
@@ -2282,8 +2277,6 @@ __afr_eager_lock_handle (afr_local_t *local, gf_boolean_t *take_lock,
lock->delay_timer = NULL;
}
}
- if (!local->transaction.eager_lock_on)
- goto out;
}
if (lock->release) {
--
1.8.3.1

View File

@ -0,0 +1,204 @@
From edc4297530eeb4107477a607042edeb2ce2ccca8 Mon Sep 17 00:00:00 2001
From: Pranith Kumar K <pkarampu@redhat.com>
Date: Tue, 18 Sep 2018 12:15:57 +0530
Subject: [PATCH 381/385] cluster/afr: Make data eager-lock decision based on
number of locks
For both Virt and block workloads the file is opened multiple times
leading to dynamically setting eager-lock to off for the workload.
Instead of depending on the number-of-open-fds, if we change the
logic to depend on number of inodelks, then it will give better
performance than the earlier logic. When there is an eager-lock
and number of inodelks is more than 1 we know that there is a
conflicting lock, so depend on that information to decide whether
to keep the current transaction go through delayed-post-op or not.
Locks xlator doesn't have implementation to query number of locks in
fxattrop in releases older than 3.10 so to keep things backward
compatible in 3.12, data transactions will use new logic where as
fxattrop transactions will use old logic. I am planning to send one
more patch which makes metadata domain locks also depend on
inodelk-count
Profile info for a dd of 500MB to a file with another fd opened
on the file using exec 250>filename
Without this patch:
0.14 67.41 us 16.72 us 3870.82 us 892 FINODELK
0.59 279.87 us 95.71 us 2085.89 us 898 FXATTROP
3.46 366.43 us 81.75 us 6952.79 us 4000 WRITE
95.79 148733.99 us 50568.12 us 919127.86 us 273 FSYNC
With this patch:
0.00 51.01 us 38.07 us 80.16 us 4 FINODELK
0.00 235.43 us 235.43 us 235.43 us 1 TRUNCATE
0.00 125.07 us 56.80 us 193.33 us 2 GETXATTR
0.00 135.86 us 62.13 us 209.59 us 2 INODELK
0.00 197.88 us 155.39 us 253.90 us 4 FXATTROP
0.00 450.59 us 394.28 us 506.89 us 2 XATTROP
0.00 56.96 us 19.06 us 406.59 us 23 FLUSH
37.81 273648.93 us 48.43 us 6017657.05 us 44 LOOKUP
62.18 4951.86 us 93.80 us 1143154.75 us 3999 WRITE
postgresql benchmark performance changed from ~1130 TPS to ~2300TPS
randio fio job inside Ovirt based VM went from ~600IOPs to ~2000IOPS
Upstream-Patch: https://review.gluster.org/c/glusterfs/+/21210
BUG: 1630688
Change-Id: If7f7388d2f08cf7f17ca517a4ea222560661dc36
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150701
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Karthik Subrahmanya <ksubrahm@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
xlators/cluster/afr/src/afr-inode-write.c | 26 ++++++++++++++++++++++++--
xlators/cluster/afr/src/afr-transaction.c | 27 +++++++++++++++++++--------
xlators/cluster/afr/src/afr.h | 8 ++++++++
3 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c
index 9e6ba35..8b1dcfd 100644
--- a/xlators/cluster/afr/src/afr-inode-write.c
+++ b/xlators/cluster/afr/src/afr-inode-write.c
@@ -300,6 +300,7 @@ afr_inode_write_fill (call_frame_t *frame, xlator_t *this, int child_index,
afr_local_t *local = frame->local;
uint32_t open_fd_count = 0;
uint32_t write_is_append = 0;
+ int32_t num_inodelks = 0;
LOCK (&frame->lock);
{
@@ -318,10 +319,19 @@ afr_inode_write_fill (call_frame_t *frame, xlator_t *this, int child_index,
&open_fd_count);
if (ret < 0)
goto unlock;
- if (open_fd_count > local->open_fd_count) {
+ if (open_fd_count > local->open_fd_count) {
local->open_fd_count = open_fd_count;
local->update_open_fd_count = _gf_true;
- }
+ }
+
+ ret = dict_get_int32(xdata, GLUSTERFS_INODELK_COUNT,
+ &num_inodelks);
+ if (ret < 0)
+ goto unlock;
+ if (num_inodelks > local->num_inodelks) {
+ local->num_inodelks = num_inodelks;
+ local->update_num_inodelks = _gf_true;
+ }
}
unlock:
UNLOCK (&frame->lock);
@@ -331,6 +341,7 @@ void
afr_process_post_writev (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
+ afr_lock_t *lock = NULL;
local = frame->local;
@@ -349,6 +360,11 @@ afr_process_post_writev (call_frame_t *frame, xlator_t *this)
if (local->update_open_fd_count)
local->inode_ctx->open_fd_count = local->open_fd_count;
+ if (local->update_num_inodelks &&
+ local->transaction.type == AFR_DATA_TRANSACTION) {
+ lock = &local->inode_ctx->lock[local->transaction.type];
+ lock->num_inodelks = local->num_inodelks;
+ }
}
@@ -534,6 +550,12 @@ afr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
goto out;
}
+ if (dict_set_str(local->xdata_req, GLUSTERFS_INODELK_DOM_COUNT,
+ this->name)) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
if (dict_set_uint32 (local->xdata_req, GLUSTERFS_WRITE_IS_APPEND, 4)) {
op_errno = ENOMEM;
goto out;
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
index 85b00a8..0a67a83 100644
--- a/xlators/cluster/afr/src/afr-transaction.c
+++ b/xlators/cluster/afr/src/afr-transaction.c
@@ -1858,17 +1858,28 @@ afr_internal_lock_finish (call_frame_t *frame, xlator_t *this)
}
gf_boolean_t
-afr_are_multiple_fds_opened (afr_local_t *local, xlator_t *this)
+afr_are_conflicting_ops_waiting(afr_local_t *local, xlator_t *this)
{
+ afr_lock_t *lock = NULL;
+ lock = &local->inode_ctx->lock[local->transaction.type];
+
/* Lets say mount1 has eager-lock(full-lock) and after the eager-lock
- * is taken mount2 opened the same file, it won't be able to
- * perform any data operations until mount1 releases eager-lock.
- * To avoid such scenario do not enable eager-lock for this transaction
- * if open-fd-count is > 1
+ * is taken mount2 opened the same file, it won't be able to perform
+ * any {meta,}data operations until mount1 releases eager-lock. To
+ * avoid such scenario do not enable eager-lock for this transaction if
+ * open-fd-count is > 1 for metadata transactions and if
+ * num-inodelks > 1 for data transactions
*/
- if (local->inode_ctx->open_fd_count > 1)
- return _gf_true;
+ if (local->transaction.type == AFR_METADATA_TRANSACTION) {
+ if (local->inode_ctx->open_fd_count > 1) {
+ return _gf_true;
+ }
+ } else if (local->transaction.type == AFR_DATA_TRANSACTION) {
+ if (lock->num_inodelks > 1) {
+ return _gf_true;
+ }
+ }
return _gf_false;
}
@@ -1890,7 +1901,7 @@ afr_is_delayed_changelog_post_op_needed (call_frame_t *frame, xlator_t *this,
goto out;
}
- if (afr_are_multiple_fds_opened (local, this)) {
+ if (afr_are_conflicting_ops_waiting(local, this)) {
lock->release = _gf_true;
goto out;
}
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index 76ad292..afe4a73 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -302,6 +302,12 @@ typedef enum {
} afr_fop_lock_state_t;
typedef struct _afr_inode_lock_t {
+ /* @num_inodelks:
+ Number of inodelks queried from the server, as queried through
+ xdata in FOPs. Currently, used to decide if eager-locking must be
+ temporarily disabled.
+ */
+ int32_t num_inodelks;
unsigned int event_generation;
gf_boolean_t release;
gf_boolean_t acquired;
@@ -354,6 +360,8 @@ typedef struct _afr_local {
uint32_t open_fd_count;
gf_boolean_t update_open_fd_count;
+ int32_t num_inodelks;
+ gf_boolean_t update_num_inodelks;
gf_lkowner_t saved_lk_owner;
--
1.8.3.1

View File

@ -0,0 +1,60 @@
From 0ac638b415be75c51716e8439f2a6459fd5b999b Mon Sep 17 00:00:00 2001
From: Csaba Henk <csaba@redhat.com>
Date: Thu, 3 May 2018 13:35:04 +0200
Subject: [PATCH 382/385] mount,fuse: make fuse dumping available as mount
option
Upsteam-patch: https://review.gluster.org/#/c/glusterfs/+/19955/
BUG: 1627098
Change-Id: I4dd4d0e607f89650ebb74b893b911b554472826d
Signed-off-by: Csaba Henk <csaba@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150711
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
doc/mount.glusterfs.8 | 3 +++
xlators/mount/fuse/utils/mount.glusterfs.in | 7 +++++++
2 files changed, 10 insertions(+)
diff --git a/doc/mount.glusterfs.8 b/doc/mount.glusterfs.8
index e16bbec..95aad02 100644
--- a/doc/mount.glusterfs.8
+++ b/doc/mount.glusterfs.8
@@ -128,6 +128,9 @@ disable root squashing for the trusted client [default: off]
\fBroot\-squash=\fRBOOL
enable root squashing for the trusted client [default: on]
.TP
+\fBdump\-fuse=\fRPATH
+Dump fuse traffic to PATH
+.TP
\fBuse\-readdirp=\fRBOOL
Use readdirp() mode in fuse kernel module [default: on]
.PP
diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in
index 36b60ff..b39bb98 100755
--- a/xlators/mount/fuse/utils/mount.glusterfs.in
+++ b/xlators/mount/fuse/utils/mount.glusterfs.in
@@ -261,6 +261,10 @@ start_glusterfs ()
cmd_line=$(echo "$cmd_line --xlator-option=$xlator_option");
fi
+ if [ -n "$dump_fuse" ]; then
+ cmd_line=$(echo "$cmd_line --dump-fuse=$dump_fuse");
+ fi
+
# if trasnport type is specified, we have to append it to
# volume name, so that it fetches the right client vol file
@@ -486,6 +490,9 @@ with_options()
"use-readdirp")
use_readdirp=$value
;;
+ "dump-fuse")
+ dump_fuse=$value
+ ;;
"event-history")
event_history=$value
;;
--
1.8.3.1

View File

@ -0,0 +1,33 @@
From 18e3135fba208022430206f366f6705476c66304 Mon Sep 17 00:00:00 2001
From: Ravishankar N <ravishankar@redhat.com>
Date: Fri, 21 Sep 2018 15:47:48 +0530
Subject: [PATCH 383/385] glusterd: bump up GD_OP_VERSION_MAX
...to GD_OP_VERSION_3_13_3 for rhgs-3.4 batch update 1.
Change-Id: I2329cd931ff3a1daea008b03f20f93eb4bb374be
BUG: 1459709
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150724
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
---
libglusterfs/src/globals.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
index 213f3ce..8e218cb 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_2 /* MAX VERSION is the maximum
+#define GD_OP_VERSION_MAX GD_OP_VERSION_3_13_3 /* MAX VERSION is the maximum
count in VME table, should
keep changing with
introduction of newer
--
1.8.3.1

View File

@ -0,0 +1,356 @@
From adc074704603822bed91e2714d93501e926c05a3 Mon Sep 17 00:00:00 2001
From: Raghavendra Bhat <raghavendra@redhat.com>
Date: Fri, 21 Sep 2018 11:25:08 -0400
Subject: [PATCH 384/385] features/uss: Use xxh64 to generate gfid instead of
md5sum
* This is to ensure FIPS support
* Also changed the signature of svs_uuid_generate to
get xlator argument
* Added xxh64 wrapper functions in common-utils to
generate gfid using xxh64
- Those wrapper functions can be used by other xlators
as well to generate gfids using xxh64. But as of now
snapview-server is going to be the only consumer.
backport of following 2 patches from upstream:
https://review.gluster.org/#/c/glusterfs/+/21122/
https://review.gluster.org/#/c/glusterfs/+/20983/
Change-Id: I35047cd1911d7a6ebe036d699d57fbdcd364ec8f
BUG: 1459709
Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150759
Reviewed-by: Rafi Kavungal Chundattu Parambil <rkavunga@redhat.com>
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
libglusterfs/src/common-utils.c | 172 +++++++++++++++++++++
libglusterfs/src/common-utils.h | 1 +
libglusterfs/src/libglusterfs-messages.h | 11 +-
.../snapview-server/src/snapview-server-helpers.c | 38 +++--
.../features/snapview-server/src/snapview-server.c | 15 +-
.../features/snapview-server/src/snapview-server.h | 5 +-
6 files changed, 227 insertions(+), 15 deletions(-)
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index f632e78..54ef875 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -91,6 +91,178 @@ gf_xxh64_wrapper(const unsigned char *data, size_t len, unsigned long long seed,
snprintf(xxh64 + i * 2, lim-i*2, "%02x", p[i]);
}
+/**
+ * This function takes following arguments
+ * @this: xlator
+ * @gfid: The gfid which has to be filled
+ * @hash: the 8 byte hash which has to be filled inside the gfid
+ * @index: the array element of the uuid_t structure (which is
+ * a array of unsigned char) from where the 8 bytes of
+ * the hash has to be filled. Since uuid_t contains 16
+ * char elements in the array, each byte of the hash has
+ * to be filled in one array element.
+ *
+ * This function is called twice for 2 hashes (of 8 byte each) to
+ * be filled in the gfid.
+ *
+ * The for loop in this function actually is doing these 2 things
+ * for each hash
+ *
+ * 1) One of the hashes
+ * tmp[0] = (hash_2 >> 56) & 0xff;
+ * tmp[1] = (hash_2 >> 48) & 0xff;
+ * tmp[2] = (hash_2 >> 40) & 0xff;
+ * tmp[3] = (hash_2 >> 32) & 0xff;
+ * tmp[4] = (hash_2 >> 24) & 0xff;
+ * tmp[5] = (hash_2 >> 16) & 0xff;
+ * tmp[6] = (hash_2 >> 8) & 0xff;
+ * tmp[7] = (hash_2) & 0xff;
+ *
+ * 2) The other hash:
+ * tmp[8] = (hash_1 >> 56) & 0xff;
+ * tmp[9] = (hash_1 >> 48) & 0xff;
+ * tmp[10] = (hash_1 >> 40) & 0xff;
+ * tmp[11] = (hash_1 >> 32) & 0xff;
+ * tmp[12] = (hash_1 >> 24) & 0xff;
+ * tmp[13] = (hash_1 >> 16) & 0xff;
+ * tmp[14] = (hash_1 >> 8) & 0xff;
+ * tmp[15] = (hash_1) & 0xff;
+ **/
+static int
+gf_gfid_from_xxh64 (xlator_t *this, uuid_t gfid, GF_XXH64_hash_t hash,
+ unsigned short index)
+{
+ int ret = -1;
+ int i = -1;
+
+ if ((index != 0) && (index != 8)) {
+ gf_msg_callingfn ("gfid-from-xxh64", GF_LOG_WARNING, 0,
+ LG_MSG_INDEX_NOT_FOUND,
+ "index can only be either 0 or 8, as this"
+ "function's purpose is to encode a 8 byte "
+ "hash inside the gfid (index: %d)",
+ index);
+ goto out;
+ }
+
+ for (i = 0; i < sizeof(hash); i++) {
+ /*
+ * As of now the below statement is equivalent of this.
+ * gfid[index+i] = (hash >> (64 - (8 * (i+1)))) & 0xff;
+ */
+ gfid[index + i] = (hash >> ((sizeof(hash) * 8) - (8 * (i + 1)))) &
+ (0xff);
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+/**
+ * This function does the same thing as gf_xxh64_wrapper. But gf_xxh64_wrapper
+ * does not return anything and in this xlator there is a need for both the
+ * actual hash and the canonicalized form of the hash.
+ *
+ * To summarize:
+ * - XXH64_hash_t is needed as return because, those bytes which contain the
+ * hash can be used for different purposes as needed. One example is
+ * to have those bytes copied into the uuid_t structure to be used as gfid
+ * - xxh64 string is needed because, it can be used as the key for generating
+ * the next hash (and any other purpose which might require canonical form
+ * of the hash).
+ **/
+GF_XXH64_hash_t
+gf_xxh64_hash_wrapper (const unsigned char *data, size_t const len,
+ unsigned long long const seed, char *xxh64)
+{
+ unsigned short i = 0;
+ const unsigned short lim = GF_XXH64_DIGEST_LENGTH * 2 + 1;
+ GF_XXH64_hash_t hash = 0;
+ GF_XXH64_canonical_t c_hash = {{0,},};
+ const uint8_t *p = (const uint8_t *)&c_hash;
+
+ hash = GF_XXH64 (data, len, seed);
+ GF_XXH64_canonicalFromHash (&c_hash, hash);
+
+ for (i = 0; i < GF_XXH64_DIGEST_LENGTH; i++)
+ snprintf (xxh64 + i * 2, lim - i * 2, "%02x", p[i]);
+
+ return hash;
+}
+
+/**
+ * This is the algorithm followed for generating new gfid
+ * 1) generate xxh64 hash using snapname and original gfid of the object
+ * 2) Using the canonicalized form of above hash as the key, generate
+ * another hash
+ * 3) Combine both of the 8 byte hashes to generate a 16 byte uuid_t type
+ * 4) Use the above uuid as the gfid
+ *
+ * Each byte of the hash is stored separately in different elements of the
+ * character array represented by uuid_t
+ * Ex: tmp[0] = (hash_2 >> 56) & 0xFF
+ * This saves the most significant byte of hash_2 in tmp[0]
+ * tmp[1] = (hash_2 >> 48) & 0xFF
+ * This saves next most significant byte of hash_2 in tmp[1]
+ * .
+ * .
+ * So on.
+ * tmp[0] - tmp[7] holds the contents of hash_2
+ * tmp[8] - tmp[15] hold the conents of hash_1
+ *
+ * The hash generated (i.e. of type XXH64_hash_t) is 8 bytes long. And for
+ * gfid 16 byte uuid is needed. Hecne the 2 hashes are combined to form
+ * one 16 byte entity.
+ **/
+int
+gf_gfid_generate_from_xxh64(uuid_t gfid, char *key)
+{
+ char xxh64_1[GF_XXH64_DIGEST_LENGTH * 2 + 1] = {0,};
+ char xxh64_2[GF_XXH64_DIGEST_LENGTH * 2 + 1] = {0};
+ GF_XXH64_hash_t hash_1 = 0;
+ GF_XXH64_hash_t hash_2 = 0;
+ int ret = -1;
+ xlator_t *this = THIS;
+
+ hash_1 = gf_xxh64_hash_wrapper ((unsigned char *)key, strlen (key),
+ GF_XXHSUM64_DEFAULT_SEED, xxh64_1);
+
+ hash_2 = gf_xxh64_hash_wrapper ((unsigned char *)xxh64_1, strlen (xxh64_1),
+ GF_XXHSUM64_DEFAULT_SEED, xxh64_2);
+
+ /* hash_2 is saved in 1st 8 elements of uuid_t char array */
+ if (gf_gfid_from_xxh64 (this, gfid, hash_2, 0)) {
+ gf_msg_callingfn (this->name, GF_LOG_WARNING, 0,
+ LG_MSG_XXH64_TO_GFID_FAILED,
+ "failed to encode the hash %llx into the 1st"
+ "half of gfid",
+ hash_2);
+ goto out;
+ }
+
+ /* hash_1 is saved in the remaining 8 elements of uuid_t */
+ if (gf_gfid_from_xxh64 (this, gfid, hash_1, 8)) {
+ gf_msg_callingfn (this->name, GF_LOG_WARNING, 0,
+ LG_MSG_XXH64_TO_GFID_FAILED,
+ "failed to encode the hash %llx into the 2nd"
+ "half of gfid",
+ hash_1);
+ goto out;
+ }
+
+ gf_msg_debug (this->name, 0,
+ "gfid generated is %s (hash1: %llx) "
+ "hash2: %llx, xxh64_1: %s xxh64_2: %s",
+ uuid_utoa (gfid), hash_1, hash_2, xxh64_1, xxh64_2);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
/* works similar to mkdir(1) -p.
*/
int
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index da943f4..e64dea3 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -837,6 +837,7 @@ gf_boolean_t gf_is_local_addr (char *hostname);
gf_boolean_t gf_is_same_address (char *host1, char *host2);
void gf_xxh64_wrapper(const unsigned char *data, size_t len,
unsigned long long seed, char *xxh64);
+int gf_gfid_generate_from_xxh64(uuid_t gfid, char *key);
int gf_set_timestamp (const char *src, const char* dest);
int gf_thread_create (pthread_t *thread, const pthread_attr_t *attr,
diff --git a/libglusterfs/src/libglusterfs-messages.h b/libglusterfs/src/libglusterfs-messages.h
index dd65701..9e35897 100644
--- a/libglusterfs/src/libglusterfs-messages.h
+++ b/libglusterfs/src/libglusterfs-messages.h
@@ -37,7 +37,7 @@
#define GLFS_LG_BASE GLFS_MSGID_COMP_LIBGLUSTERFS
-#define GLFS_LG_NUM_MESSAGES 211
+#define GLFS_LG_NUM_MESSAGES 212
#define GLFS_LG_MSGID_END (GLFS_LG_BASE + GLFS_LG_NUM_MESSAGES + 1)
/* Messaged with message IDs */
@@ -1809,6 +1809,15 @@
* @recommendedaction
*
*/
+
+#define LG_MSG_XXH64_TO_GFID_FAILED (GLFS_LG_BASE + 212)
+
+/*!
+ * @messageid
+ * @diagnosis
+ * @recommendedaction
+ *
+ */
/*------------*/
#define glfs_msg_end_lg GLFS_LG_MSGID_END, "Invalid: End of messages"
diff --git a/xlators/features/snapview-server/src/snapview-server-helpers.c b/xlators/features/snapview-server/src/snapview-server-helpers.c
index 6f305db..2ad74ef 100644
--- a/xlators/features/snapview-server/src/snapview-server-helpers.c
+++ b/xlators/features/snapview-server/src/snapview-server-helpers.c
@@ -329,18 +329,38 @@ out:
return svs_fd;
}
-void
-svs_uuid_generate (uuid_t gfid, char *snapname, uuid_t origin_gfid)
+int
+svs_uuid_generate (xlator_t *this, uuid_t gfid, char *snapname,
+ uuid_t origin_gfid)
{
- unsigned char md5_sum[MD5_DIGEST_LENGTH] = {0};
- char ino_string[NAME_MAX + 32] = "";
+ char ino_string[NAME_MAX + 32] = "";
+ uuid_t tmp = {0,};
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, snapname, out);
+
+ (void)snprintf (ino_string, sizeof (ino_string), "%s%s", snapname,
+ uuid_utoa (origin_gfid));
+
+ if (gf_gfid_generate_from_xxh64 (tmp, ino_string)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to generate "
+ "gfid for object with actual gfid of %s "
+ "(snapname: %s, key: %s)",
+ uuid_utoa (origin_gfid), snapname, ino_string);
+ goto out;
+ }
+
+ gf_uuid_copy (gfid, tmp);
- GF_ASSERT (snapname);
+ ret = 0;
+
+ gf_log (this->name, GF_LOG_DEBUG, "gfid generated is %s ",
+ uuid_utoa(gfid));
- (void) snprintf (ino_string, sizeof (ino_string), "%s%s",
- snapname, uuid_utoa(origin_gfid));
- MD5((unsigned char *)ino_string, strlen(ino_string), md5_sum);
- gf_uuid_copy (gfid, md5_sum);
+out:
+ return ret;
}
void
diff --git a/xlators/features/snapview-server/src/snapview-server.c b/xlators/features/snapview-server/src/snapview-server.c
index 22b0e1c..7068c5a 100644
--- a/xlators/features/snapview-server/src/snapview-server.c
+++ b/xlators/features/snapview-server/src/snapview-server.c
@@ -330,9 +330,18 @@ svs_lookup_entry (xlator_t *this, loc_t *loc, struct iatt *buf,
}
if (gf_uuid_is_null (loc->gfid) &&
- gf_uuid_is_null (loc->inode->gfid))
- svs_uuid_generate (gfid, parent_ctx->snapname, object->gfid);
- else {
+ gf_uuid_is_null (loc->inode->gfid)) {
+ if (svs_uuid_generate (this, gfid, parent_ctx->snapname,
+ object->gfid)) {
+ /*
+ * should op_errno be something else such as
+ * EINVAL or ESTALE?
+ */
+ op_ret = -1;
+ *op_errno = EIO;
+ goto out;
+ }
+ } else {
if (!gf_uuid_is_null (loc->inode->gfid))
gf_uuid_copy (gfid, loc->inode->gfid);
else
diff --git a/xlators/features/snapview-server/src/snapview-server.h b/xlators/features/snapview-server/src/snapview-server.h
index a12319f..73524a5 100644
--- a/xlators/features/snapview-server/src/snapview-server.h
+++ b/xlators/features/snapview-server/src/snapview-server.h
@@ -204,8 +204,9 @@ __svs_fd_ctx_get_or_new (xlator_t *this, fd_t *fd);
svs_fd_t *
svs_fd_ctx_get_or_new (xlator_t *this, fd_t *fd);
-void
-svs_uuid_generate (uuid_t gfid, char *snapname, uuid_t origin_gfid);
+int
+svs_uuid_generate (xlator_t *this, uuid_t gfid, char *snapname,
+ uuid_t origin_gfid);
void
svs_fill_ino_from_gfid (struct iatt *buf);
--
1.8.3.1

View File

@ -0,0 +1,312 @@
From 43124cc2d3ddb1b3262e254326d8461cdf1f894d Mon Sep 17 00:00:00 2001
From: Ravishankar N <ravishankar@redhat.com>
Date: Fri, 21 Sep 2018 18:23:34 +0530
Subject: [PATCH 385/385] afr: fix incorrect reporting of directory split-brain
Patch on master: https://review.gluster.org/#/c/glusterfs/+/21135/
Problem:
When a directory has dirty xattrs due to failed post-ops or when
replace/reset brick is performed, AFR does a conservative merge as
expected, but heal-info reports it as split-brain because there are no
clear sources.
Fix:
Modify pending flag to contain information about pending heals and
split-brains. For directories, if spit-brain flag is not set,just show
them as needing heal and not being in split-brain.
Change-Id: I21460bb5375297e421a14efb9ef0f9cea46f7e7c
BUG: 1610743
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150742
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
tests/afr.rc | 2 +-
.../bugs/replicate/bug-1626994-info-split-brain.t | 62 ++++++++++++++++++++++
xlators/cluster/afr/src/afr-common.c | 14 ++---
xlators/cluster/afr/src/afr-self-heal-common.c | 6 ++-
xlators/cluster/afr/src/afr-self-heal-data.c | 2 +-
xlators/cluster/afr/src/afr-self-heal-entry.c | 2 +-
xlators/cluster/afr/src/afr-self-heal-metadata.c | 3 +-
xlators/cluster/afr/src/afr-self-heal.h | 8 +--
xlators/cluster/afr/src/afr.h | 3 ++
9 files changed, 85 insertions(+), 17 deletions(-)
create mode 100644 tests/bugs/replicate/bug-1626994-info-split-brain.t
diff --git a/tests/afr.rc b/tests/afr.rc
index bdf4075..1fd0310 100644
--- a/tests/afr.rc
+++ b/tests/afr.rc
@@ -2,7 +2,7 @@
function create_brick_xattrop_entry {
local xattrop_dir=$(afr_get_index_path $1)
- local base_entry=`ls $xattrop_dir`
+ local base_entry=`ls $xattrop_dir|grep xattrop`
local gfid_str
local params=`echo "$@" | cut -d' ' -f2-`
echo $params
diff --git a/tests/bugs/replicate/bug-1626994-info-split-brain.t b/tests/bugs/replicate/bug-1626994-info-split-brain.t
new file mode 100644
index 0000000..86bfecb
--- /dev/null
+++ b/tests/bugs/replicate/bug-1626994-info-split-brain.t
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+. $(dirname $0)/../../afr.rc
+
+cleanup;
+
+# Test to check dirs having dirty xattr do not show up in info split-brain.
+
+TEST glusterd;
+TEST pidof glusterd;
+TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2};
+TEST $CLI volume set $V0 self-heal-daemon off
+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
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" brick_up_status $V0 $H0 $B0/${V0}2
+TEST $GFS --volfile-id=/$V0 --volfile-server=$H0 $M0
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 2
+
+# Create base entry in indices/xattrop
+echo "Data" > $M0/FILE
+rm -f $M0/FILE
+EXPECT "1" count_index_entries $B0/${V0}0
+EXPECT "1" count_index_entries $B0/${V0}1
+EXPECT "1" count_index_entries $B0/${V0}2
+
+TEST mkdir $M0/dirty_dir
+TEST mkdir $M0/pending_dir
+
+# Set dirty xattrs on all bricks to simulate the case where entry transaction
+# succeeded only the pre-op phase.
+TEST setfattr -n trusted.afr.dirty -v 0x000000000000000000000001 $B0/${V0}0/dirty_dir
+TEST setfattr -n trusted.afr.dirty -v 0x000000000000000000000001 $B0/${V0}1/dirty_dir
+TEST setfattr -n trusted.afr.dirty -v 0x000000000000000000000001 $B0/${V0}2/dirty_dir
+create_brick_xattrop_entry $B0/${V0}0 dirty_dir
+# Should not show up as split-brain.
+EXPECT "0" afr_get_split_brain_count $V0
+
+# replace/reset brick case where the new brick has dirty and the other 2 bricks
+# blame it should not be reported as split-brain.
+TEST setfattr -n trusted.afr.$V0-client-2 -v 0x000000000000000000000001 $B0/${V0}0
+TEST setfattr -n trusted.afr.$V0-client-2 -v 0x000000000000000000000001 $B0/${V0}1
+TEST setfattr -n trusted.afr.dirty -v 0x000000000000000000000001 $B0/${V0}2
+create_brick_xattrop_entry $B0/${V0}0 "/"
+# Should not show up as split-brain.
+EXPECT "0" afr_get_split_brain_count $V0
+
+# Set pending xattrs on all bricks blaming each other to simulate the case of
+# entry split-brain.
+TEST setfattr -n trusted.afr.$V0-client-1 -v 0x000000000000000000000001 $B0/${V0}0/pending_dir
+TEST setfattr -n trusted.afr.$V0-client-2 -v 0x000000000000000000000001 $B0/${V0}1/pending_dir
+TEST setfattr -n trusted.afr.$V0-client-0 -v 0x000000000000000000000001 $B0/${V0}2/pending_dir
+create_brick_xattrop_entry $B0/${V0}0 pending_dir
+# Should show up as split-brain.
+EXPECT "1" afr_get_split_brain_count $V0
+
+cleanup;
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index a85549b..bded6a2 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -5472,7 +5472,7 @@ out:
int
afr_selfheal_locked_metadata_inspect (call_frame_t *frame, xlator_t *this,
inode_t *inode, gf_boolean_t *msh,
- gf_boolean_t *pending)
+ unsigned char *pending)
{
int ret = -1;
unsigned char *locked_on = NULL;
@@ -5521,7 +5521,7 @@ out:
int
afr_selfheal_locked_data_inspect (call_frame_t *frame, xlator_t *this,
fd_t *fd, gf_boolean_t *dsh,
- gf_boolean_t *pflag)
+ unsigned char *pflag)
{
int ret = -1;
unsigned char *data_lock = NULL;
@@ -5568,7 +5568,7 @@ out:
int
afr_selfheal_locked_entry_inspect (call_frame_t *frame, xlator_t *this,
inode_t *inode,
- gf_boolean_t *esh, gf_boolean_t *pflag)
+ gf_boolean_t *esh, unsigned char *pflag)
{
int ret = -1;
int source = -1;
@@ -5619,7 +5619,7 @@ afr_selfheal_locked_entry_inspect (call_frame_t *frame, xlator_t *this,
sinks, healed_sinks,
locked_replies,
&source, pflag);
- if ((ret == 0) && source < 0)
+ if ((ret == 0) && (*pflag & PFLAG_SBRAIN))
ret = -EIO;
*esh = afr_decide_heal_info (priv, sources, ret);
}
@@ -5642,7 +5642,7 @@ afr_selfheal_locked_inspect (call_frame_t *frame, xlator_t *this, uuid_t gfid,
gf_boolean_t *entry_selfheal,
gf_boolean_t *data_selfheal,
gf_boolean_t *metadata_selfheal,
- gf_boolean_t *pending)
+ unsigned char *pending)
{
int ret = -1;
@@ -5730,7 +5730,7 @@ afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc)
gf_boolean_t data_selfheal = _gf_false;
gf_boolean_t metadata_selfheal = _gf_false;
gf_boolean_t entry_selfheal = _gf_false;
- gf_boolean_t pending = _gf_false;
+ unsigned char pending = 0;
dict_t *dict = NULL;
int ret = -1;
int op_errno = 0;
@@ -5750,7 +5750,7 @@ afr_get_heal_info (call_frame_t *frame, xlator_t *this, loc_t *loc)
goto out;
}
- if (pending) {
+ if (pending & PFLAG_PENDING) {
size = strlen ("-pending") + 1;
gf_asprintf (&substr, "-pending");
if (!substr)
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index 7e6a691..d04f11d 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -1545,7 +1545,7 @@ afr_selfheal_find_direction (call_frame_t *frame, xlator_t *this,
afr_transaction_type type,
unsigned char *locked_on, unsigned char *sources,
unsigned char *sinks, uint64_t *witness,
- gf_boolean_t *pflag)
+ unsigned char *pflag)
{
afr_private_t *priv = NULL;
int i = 0;
@@ -1573,7 +1573,7 @@ afr_selfheal_find_direction (call_frame_t *frame, xlator_t *this,
for (i = 0; i < priv->child_count; i++) {
for (j = 0; j < priv->child_count; j++)
if (matrix[i][j])
- *pflag = _gf_true;
+ *pflag |= PFLAG_PENDING;
if (*pflag)
break;
}
@@ -1655,6 +1655,8 @@ afr_selfheal_find_direction (call_frame_t *frame, xlator_t *this,
if (locked_on[i])
sinks[i] = 1;
}
+ if (pflag)
+ *pflag |= PFLAG_SBRAIN;
}
/* One more class of witness similar to dirty in v2 is where no pending
diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c
index 556a8f9..d3deb8f 100644
--- a/xlators/cluster/afr/src/afr-self-heal-data.c
+++ b/xlators/cluster/afr/src/afr-self-heal-data.c
@@ -624,7 +624,7 @@ __afr_selfheal_data_prepare (call_frame_t *frame, xlator_t *this,
unsigned char *sources, unsigned char *sinks,
unsigned char *healed_sinks,
unsigned char *undid_pending,
- struct afr_reply *replies, gf_boolean_t *pflag)
+ struct afr_reply *replies, unsigned char *pflag)
{
int ret = -1;
int source = -1;
diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c
index f6d3a8a..9f597af 100644
--- a/xlators/cluster/afr/src/afr-self-heal-entry.c
+++ b/xlators/cluster/afr/src/afr-self-heal-entry.c
@@ -496,7 +496,7 @@ __afr_selfheal_entry_prepare (call_frame_t *frame, xlator_t *this,
unsigned char *sources, unsigned char *sinks,
unsigned char *healed_sinks,
struct afr_reply *replies, int *source_p,
- gf_boolean_t *pflag)
+ unsigned char *pflag)
{
int ret = -1;
int source = -1;
diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c
index 199f896..50f8888 100644
--- a/xlators/cluster/afr/src/afr-self-heal-metadata.c
+++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c
@@ -318,7 +318,8 @@ __afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this, inode_t *i
unsigned char *locked_on, unsigned char *sources,
unsigned char *sinks, unsigned char *healed_sinks,
unsigned char *undid_pending,
- struct afr_reply *replies, gf_boolean_t *pflag)
+ struct afr_reply *replies,
+ unsigned char *pflag)
{
int ret = -1;
int source = -1;
diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h
index cc99d9e..7e6fb42 100644
--- a/xlators/cluster/afr/src/afr-self-heal.h
+++ b/xlators/cluster/afr/src/afr-self-heal.h
@@ -172,7 +172,7 @@ afr_selfheal_find_direction (call_frame_t *frame, xlator_t *this,
afr_transaction_type type,
unsigned char *locked_on, unsigned char *sources,
unsigned char *sinks, uint64_t *witness,
- gf_boolean_t *flag);
+ unsigned char *flag);
int
afr_selfheal_fill_matrix (xlator_t *this, int **matrix, int subvol, int idx,
dict_t *xdata);
@@ -286,7 +286,7 @@ __afr_selfheal_data_prepare (call_frame_t *frame, xlator_t *this,
unsigned char *sources,
unsigned char *sinks, unsigned char *healed_sinks,
unsigned char *undid_pending,
- struct afr_reply *replies, gf_boolean_t *flag);
+ struct afr_reply *replies, unsigned char *flag);
int
__afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this,
@@ -296,7 +296,7 @@ __afr_selfheal_metadata_prepare (call_frame_t *frame, xlator_t *this,
unsigned char *healed_sinks,
unsigned char *undid_pending,
struct afr_reply *replies,
- gf_boolean_t *flag);
+ unsigned char *flag);
int
__afr_selfheal_entry_prepare (call_frame_t *frame, xlator_t *this,
inode_t *inode, unsigned char *locked_on,
@@ -304,7 +304,7 @@ __afr_selfheal_entry_prepare (call_frame_t *frame, xlator_t *this,
unsigned char *sinks,
unsigned char *healed_sinks,
struct afr_reply *replies, int *source_p,
- gf_boolean_t *flag);
+ unsigned char *flag);
int
afr_selfheal_unlocked_inspect (call_frame_t *frame, xlator_t *this,
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index afe4a73..2e6d995 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -36,6 +36,9 @@
#define ARBITER_BRICK_INDEX 2
+#define PFLAG_PENDING (1 << 0)
+#define PFLAG_SBRAIN (1 << 1)
+
typedef int (*afr_lock_cbk_t) (call_frame_t *frame, xlator_t *this);
typedef int (*afr_read_txn_wind_t) (call_frame_t *frame, xlator_t *this, int subvol);
--
1.8.3.1

View File

@ -192,7 +192,7 @@ Release: 0.1%{?prereltag:.%{prereltag}}%{?dist}
%else
Name: glusterfs
Version: 3.12.2
Release: 18%{?dist}
Release: 19%{?dist}
%endif
License: GPLv2 or LGPLv3+
Group: System Environment/Base
@ -627,6 +627,29 @@ Patch0359: 0359-storage-posix-Increment-trusted.pgfid-in-posix_mknod.patch
Patch0360: 0360-geo-rep-Make-automatic-gfid-conflict-resolution-opti.patch
Patch0361: 0361-ctr-skip-ctr-xlator-init-if-ctr-is-not-enabled.patch
Patch0362: 0362-glusterd-glusterd_brick_start-shouldn-t-cleanup-pidf.patch
Patch0363: 0363-Update-rfc.sh-to-rhgs-3.4.1.patch
Patch0364: 0364-fips-Replace-md5sum-usage-to-enable-fips-support.patch
Patch0365: 0365-glusterd-ignore-importing-volume-which-is-undergoing.patch
Patch0366: 0366-glusterd-fail-volume-stop-operation-if-brick-detach-.patch
Patch0367: 0367-cluster-ec-Improve-logging-for-some-critical-error-m.patch
Patch0368: 0368-mount-fuse-convert-ENOENT-to-ESTALE-in-open-dir-_res.patch
Patch0369: 0369-geo-rep-Fix-deadlock-during-worker-start.patch
Patch0370: 0370-libgfchangelog-Fix-changelog-history-API.patch
Patch0371: 0371-performance-write-behind-remove-the-request-from-wip.patch
Patch0372: 0372-Revert-posix-disable-block-and-character-files.patch
Patch0373: 0373-posix-disable-open-read-write-on-special-files.patch
Patch0374: 0374-socket-set-42-as-default-tpc-user-timeout.patch
Patch0375: 0375-extras-Add-new-options-to-group-virt.patch
Patch0376: 0376-rchecksum-fips-Replace-MD5-usage-to-enable-fips-supp.patch
Patch0377: 0377-fips-geo-rep-Replace-MD5-with-SHA256.patch
Patch0378: 0378-posix-afr-handle-backward-compatibility-for-rchecksu.patch
Patch0379: 0379-glusterd-change-op-version-of-fips-mode-rchecksum.patch
Patch0380: 0380-cluster-afr-Batch-writes-in-same-lock-even-when-mult.patch
Patch0381: 0381-cluster-afr-Make-data-eager-lock-decision-based-on-n.patch
Patch0382: 0382-mount-fuse-make-fuse-dumping-available-as-mount-opti.patch
Patch0383: 0383-glusterd-bump-up-GD_OP_VERSION_MAX.patch
Patch0384: 0384-features-uss-Use-xxh64-to-generate-gfid-instead-of-m.patch
Patch0385: 0385-afr-fix-incorrect-reporting-of-directory-split-brain.patch
%description
GlusterFS is a distributed file-system capable of scaling to several
@ -2575,6 +2598,11 @@ fi
%endif
%changelog
* Sat Sep 22 2018 Sunil Kumar Acharya <sheggodu@redhat.com> - 3.12.2-19
- fixes bugs bz#1459709 bz#1610743 bz#1618221 bz#1619627 bz#1622649
bz#1623749 bz#1623874 bz#1624444 bz#1625622 bz#1626780 bz#1627098 bz#1627617
bz#1627639 bz#1630688
* Mon Aug 27 2018 Milind Changire <mchangir@redhat.com> - 3.12.2-18
- fixes bugs bz#1524336 bz#1622029 bz#1622452