diff --git a/0337-fuse-Set-limit-on-invalidate-queue-size.patch b/0337-fuse-Set-limit-on-invalidate-queue-size.patch new file mode 100644 index 0000000..b18ef4f --- /dev/null +++ b/0337-fuse-Set-limit-on-invalidate-queue-size.patch @@ -0,0 +1,455 @@ +From ddb0038de77a4269fa7eed1bb217bfb6bed1b7ba Mon Sep 17 00:00:00 2001 +From: N Balachandran +Date: Fri, 9 Aug 2019 14:34:22 +0530 +Subject: [PATCH 337/344] fuse: Set limit on invalidate queue size + +If the glusterfs fuse client process is unable to +process the invalidate requests quickly enough, the +number of such requests quickly grows large enough +to use a significant amount of memory. +We are now introducing another option to set an upper +limit on these to prevent runaway memory usage. + +> Upstream https://review.gluster.org/23187 +> Change-Id: Iddfff1ee2de1466223e6717f7abd4b28ed947788 +> Fixes: bz#1732717 +> Signed-off-by: N Balachandran + +BUG: 1763208 +Change-Id: I666cdf6c70999a0f0bc79969e8df0a9dde93b6e4 +Signed-off-by: Csaba Henk +Reviewed-on: https://code.engineering.redhat.com/gerrit/187529 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + doc/mount.glusterfs.8 | 5 +++ + glusterfsd/src/glusterfsd.c | 21 ++++++++++ + glusterfsd/src/glusterfsd.h | 3 +- + libglusterfs/src/glusterfs/glusterfs.h | 1 + + libglusterfs/src/glusterfs/inode.h | 1 + + libglusterfs/src/inode.c | 31 +++++++++++---- + xlators/mount/fuse/src/fuse-bridge.c | 60 ++++++++++++++++++++++------- + xlators/mount/fuse/src/fuse-bridge.h | 3 +- + xlators/mount/fuse/utils/mount.glusterfs.in | 7 ++++ + 9 files changed, 108 insertions(+), 24 deletions(-) + +diff --git a/doc/mount.glusterfs.8 b/doc/mount.glusterfs.8 +index 286631b..b35b362 100644 +--- a/doc/mount.glusterfs.8 ++++ b/doc/mount.glusterfs.8 +@@ -126,6 +126,11 @@ Provide list of backup volfile servers in the following format [default: None] + Set fuse module's limit for number of inodes kept in LRU list to N [default: 131072] + .TP + .TP ++\fBinvalidate-limit=\fRN ++Suspend fuse invalidations implied by 'lru-limit' if number of outstanding ++invalidations reaches N ++.TP ++.TP + \fBbackground-qlen=\fRN + Set fuse module's background queue length to N [default: 64] + .TP +diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c +index 5b5e996..0856471 100644 +--- a/glusterfsd/src/glusterfsd.c ++++ b/glusterfsd/src/glusterfsd.c +@@ -212,6 +212,9 @@ static struct argp_option gf_options[] = { + {"lru-limit", ARGP_FUSE_LRU_LIMIT_KEY, "N", 0, + "Set fuse module's limit for number of inodes kept in LRU list to N " + "[default: 131072]"}, ++ {"invalidate-limit", ARGP_FUSE_INVALIDATE_LIMIT_KEY, "N", 0, ++ "Suspend inode invalidations implied by 'lru-limit' if the number of " ++ "outstanding invalidations reaches N"}, + {"background-qlen", ARGP_FUSE_BACKGROUND_QLEN_KEY, "N", 0, + "Set fuse module's background queue length to N " + "[default: 64]"}, +@@ -504,6 +507,16 @@ set_fuse_mount_options(glusterfs_ctx_t *ctx, dict_t *options) + } + } + ++ if (cmd_args->invalidate_limit >= 0) { ++ ret = dict_set_int32(options, "invalidate-limit", ++ cmd_args->invalidate_limit); ++ if (ret < 0) { ++ gf_msg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4, ++ "invalidate-limit"); ++ goto err; ++ } ++ } ++ + if (cmd_args->background_qlen) { + ret = dict_set_int32(options, "background-qlen", + cmd_args->background_qlen); +@@ -1283,6 +1296,14 @@ parse_opts(int key, char *arg, struct argp_state *state) + argp_failure(state, -1, 0, "unknown LRU limit option %s", arg); + break; + ++ case ARGP_FUSE_INVALIDATE_LIMIT_KEY: ++ if (!gf_string2int32(arg, &cmd_args->invalidate_limit)) ++ break; ++ ++ argp_failure(state, -1, 0, "unknown invalidate limit option %s", ++ arg); ++ break; ++ + case ARGP_FUSE_BACKGROUND_QLEN_KEY: + if (!gf_string2int(arg, &cmd_args->background_qlen)) + break; +diff --git a/glusterfsd/src/glusterfsd.h b/glusterfsd/src/glusterfsd.h +index fa55789..ee655f0 100644 +--- a/glusterfsd/src/glusterfsd.h ++++ b/glusterfsd/src/glusterfsd.h +@@ -111,7 +111,8 @@ enum argp_option_keys { + ARGP_FUSE_FLUSH_HANDLE_INTERRUPT_KEY = 189, + ARGP_FUSE_LRU_LIMIT_KEY = 190, + ARGP_FUSE_AUTO_INVAL_KEY = 191, +- ARGP_BRICK_MUX_KEY = 192 ++ ARGP_BRICK_MUX_KEY = 192, ++ ARGP_FUSE_INVALIDATE_LIMIT_KEY = 195, + }; + + struct _gfd_vol_top_priv { +diff --git a/libglusterfs/src/glusterfs/glusterfs.h b/libglusterfs/src/glusterfs/glusterfs.h +index 79c93ae..3b594c0 100644 +--- a/libglusterfs/src/glusterfs/glusterfs.h ++++ b/libglusterfs/src/glusterfs/glusterfs.h +@@ -541,6 +541,7 @@ struct _cmd_args { + int client_pid_set; + unsigned uid_map_root; + int32_t lru_limit; ++ int32_t invalidate_limit; + int background_qlen; + int congestion_threshold; + char *fuse_mountopts; +diff --git a/libglusterfs/src/glusterfs/inode.h b/libglusterfs/src/glusterfs/inode.h +index 52efdd8..4421c47 100644 +--- a/libglusterfs/src/glusterfs/inode.h ++++ b/libglusterfs/src/glusterfs/inode.h +@@ -107,6 +107,7 @@ struct _inode { + struct list_head list; /* active/lru/purge */ + + struct _inode_ctx *_ctx; /* replacement for dict_t *(inode->ctx) */ ++ bool in_invalidate_list; /* Set if inode is in table invalidate list */ + bool invalidate_sent; /* Set it if invalidator_fn is called for inode */ + }; + +diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c +index 96ddea5..5331e93 100644 +--- a/libglusterfs/src/inode.c ++++ b/libglusterfs/src/inode.c +@@ -558,8 +558,8 @@ __inode_unref(inode_t *inode, bool clear) + + this = THIS; + +- if (clear && inode->invalidate_sent) { +- inode->invalidate_sent = false; ++ if (clear && inode->in_invalidate_list) { ++ inode->in_invalidate_list = false; + inode->table->invalidate_size--; + __inode_activate(inode); + } +@@ -573,7 +573,7 @@ __inode_unref(inode_t *inode, bool clear) + inode->_ctx[index].ref--; + } + +- if (!inode->ref && !inode->invalidate_sent) { ++ if (!inode->ref && !inode->in_invalidate_list) { + inode->table->active_size--; + + nlookup = GF_ATOMIC_GET(inode->nlookup); +@@ -609,14 +609,14 @@ __inode_ref(inode_t *inode, bool is_invalidate) + return inode; + + if (!inode->ref) { +- if (inode->invalidate_sent) { +- inode->invalidate_sent = false; ++ if (inode->in_invalidate_list) { ++ inode->in_invalidate_list = false; + inode->table->invalidate_size--; + } else { + inode->table->lru_size--; + } + if (is_invalidate) { +- inode->invalidate_sent = true; ++ inode->in_invalidate_list = true; + inode->table->invalidate_size++; + list_move_tail(&inode->list, &inode->table->invalidate); + } else { +@@ -1609,6 +1609,7 @@ static int + inode_table_prune(inode_table_t *table) + { + int ret = 0; ++ int ret1 = 0; + struct list_head purge = { + 0, + }; +@@ -1647,6 +1648,10 @@ inode_table_prune(inode_table_t *table) + /* check for valid inode with 'nlookup' */ + nlookup = GF_ATOMIC_GET(entry->nlookup); + if (nlookup) { ++ if (entry->invalidate_sent) { ++ list_move_tail(&entry->list, &table->lru); ++ continue; ++ } + __inode_ref(entry, true); + tmp = entry; + break; +@@ -1668,9 +1673,19 @@ inode_table_prune(inode_table_t *table) + if (tmp) { + xlator_t *old_THIS = THIS; + THIS = table->invalidator_xl; +- table->invalidator_fn(table->invalidator_xl, tmp); ++ ret1 = table->invalidator_fn(table->invalidator_xl, tmp); + THIS = old_THIS; +- inode_unref(tmp); ++ pthread_mutex_lock(&table->lock); ++ { ++ if (!ret1) { ++ tmp->invalidate_sent = true; ++ __inode_unref(tmp, false); ++ } else { ++ /* Move this back to the lru list*/ ++ __inode_unref(tmp, true); ++ } ++ } ++ pthread_mutex_unlock(&table->lock); + } + + /* Just so that if purge list is handled too, then clear it off */ +diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c +index 1c946a2..8b2e7f0 100644 +--- a/xlators/mount/fuse/src/fuse-bridge.c ++++ b/xlators/mount/fuse/src/fuse-bridge.c +@@ -26,7 +26,7 @@ static int gf_fuse_xattr_enotsup_log; + void + fini(xlator_t *this_xl); + +-static void ++static int32_t + fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino); + + /* +@@ -312,7 +312,7 @@ send_fuse_data(xlator_t *this, fuse_in_header_t *finh, void *data, size_t size) + #define send_fuse_obj(this, finh, obj) \ + send_fuse_data(this, finh, obj, sizeof(*(obj))) + +-static void ++static int32_t + fuse_invalidate_entry(xlator_t *this, uint64_t fuse_ino) + { + #if FUSE_KERNEL_MINOR_VERSION >= 11 +@@ -328,17 +328,22 @@ fuse_invalidate_entry(xlator_t *this, uint64_t fuse_ino) + + priv = this->private; + if (!priv->reverse_fuse_thread_started) +- return; ++ return -1; ++ ++ if (priv->invalidate_limit && ++ (priv->invalidate_count >= priv->invalidate_limit)) { ++ return -1; ++ } + + inode = (inode_t *)(unsigned long)fuse_ino; + if (inode == NULL) +- return; ++ return -1; + + list_for_each_entry_safe(dentry, tmp, &inode->dentry_list, inode_list) + { + node = GF_CALLOC(1, sizeof(*node), gf_fuse_mt_invalidate_node_t); + if (node == NULL) +- break; ++ return -1; + + INIT_LIST_HEAD(&node->next); + +@@ -375,20 +380,21 @@ fuse_invalidate_entry(xlator_t *this, uint64_t fuse_ino) + pthread_mutex_lock(&priv->invalidate_mutex); + { + list_add_tail(&node->next, &priv->invalidate_list); ++ priv->invalidate_count++; + pthread_cond_signal(&priv->invalidate_cond); + } + pthread_mutex_unlock(&priv->invalidate_mutex); + } + + #endif +- return; ++ return 0; + } + + /* + * Send an inval inode notification to fuse. This causes an invalidation of the + * entire page cache mapping on the inode. + */ +-static void ++static int32_t + fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino) + { + #if FUSE_KERNEL_MINOR_VERSION >= 11 +@@ -401,15 +407,20 @@ fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino) + priv = this->private; + + if (!priv->reverse_fuse_thread_started) +- return; ++ return -1; ++ ++ if (priv->invalidate_limit && ++ (priv->invalidate_count >= priv->invalidate_limit)) { ++ return -1; ++ } + + inode = (inode_t *)(unsigned long)fuse_ino; + if (inode == NULL) +- return; ++ return -1; + + node = GF_CALLOC(1, sizeof(*node), gf_fuse_mt_invalidate_node_t); + if (node == NULL) +- return; ++ return -1; + + INIT_LIST_HEAD(&node->next); + +@@ -435,6 +446,7 @@ fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino) + pthread_mutex_lock(&priv->invalidate_mutex); + { + list_add_tail(&node->next, &priv->invalidate_list); ++ priv->invalidate_count++; + pthread_cond_signal(&priv->invalidate_cond); + } + pthread_mutex_unlock(&priv->invalidate_mutex); +@@ -443,7 +455,7 @@ fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino) + gf_log("glusterfs-fuse", GF_LOG_WARNING, + "fuse_invalidate_inode not implemented on this system"); + #endif +- return; ++ return 0; + } + + #if FUSE_KERNEL_MINOR_VERSION >= 11 +@@ -451,8 +463,9 @@ fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino) + static int32_t + fuse_inode_invalidate_fn(xlator_t *this, inode_t *inode) + { +- fuse_invalidate_entry(this, (uint64_t)(uintptr_t)inode); +- return 0; ++ int32_t ret = 0; ++ ret = fuse_invalidate_entry(this, (uint64_t)(uintptr_t)inode); ++ return ret; + } + #endif + +@@ -4003,7 +4016,9 @@ fuse_setxattr(xlator_t *this, fuse_in_header_t *finh, void *msg, + gf_log("fuse", GF_LOG_TRACE, "got request to invalidate %" PRIu64, + finh->nodeid); + #if FUSE_KERNEL_MINOR_VERSION >= 11 +- fuse_invalidate_entry(this, finh->nodeid); ++ ret = fuse_invalidate_entry(this, finh->nodeid); ++ if (ret) ++ op_errno = EBUSY; + #endif + goto done; + } +@@ -4812,6 +4827,7 @@ notify_kernel_loop(void *data) + fuse_invalidate_node_t, next); + + list_del_init(&node->next); ++ priv->invalidate_count--; + } + pthread_mutex_unlock(&priv->invalidate_mutex); + +@@ -4855,6 +4871,7 @@ notify_kernel_loop(void *data) + list_del_init(&node->next); + GF_FREE(node); + } ++ priv->invalidate_count = 0; + } + pthread_mutex_unlock(&priv->invalidate_mutex); + +@@ -6080,6 +6097,9 @@ fuse_priv_dump(xlator_t *this) + (int)private->timed_response_fuse_thread_started); + gf_proc_dump_write("reverse_thread_started", "%d", + (int)private->reverse_fuse_thread_started); ++ gf_proc_dump_write("invalidate_limit", "%u", private->invalidate_limit); ++ gf_proc_dump_write("invalidate_queue_length", "%" PRIu64, ++ private->invalidate_count); + gf_proc_dump_write("use_readdirp", "%d", private->use_readdirp); + + return 0; +@@ -6619,6 +6639,9 @@ init(xlator_t *this_xl) + + GF_OPTION_INIT("lru-limit", priv->lru_limit, uint32, cleanup_exit); + ++ GF_OPTION_INIT("invalidate-limit", priv->invalidate_limit, uint32, ++ cleanup_exit); ++ + GF_OPTION_INIT("event-history", priv->event_history, bool, cleanup_exit); + + GF_OPTION_INIT("thin-client", priv->thin_client, bool, cleanup_exit); +@@ -6955,6 +6978,15 @@ struct volume_options options[] = { + "reaching this limit (0 means 'unlimited')", + }, + { ++ .key = {"invalidate-limit"}, ++ .type = GF_OPTION_TYPE_INT, ++ .default_value = "0", ++ .min = 0, ++ .description = "suspend invalidations as of 'lru-limit' if the number " ++ "of outstanding invalidations reaches this limit " ++ "(0 means 'unlimited')", ++ }, ++ { + .key = {"auto-invalidation"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "true", +diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h +index 697bd88..2311582 100644 +--- a/xlators/mount/fuse/src/fuse-bridge.h ++++ b/xlators/mount/fuse/src/fuse-bridge.h +@@ -139,7 +139,7 @@ struct fuse_private { + pthread_cond_t invalidate_cond; + pthread_mutex_t invalidate_mutex; + gf_boolean_t reverse_fuse_thread_started; +- ++ uint64_t invalidate_count; + /* For communicating with separate mount thread. */ + int status_pipe[2]; + +@@ -191,6 +191,7 @@ struct fuse_private { + + /* LRU Limit, if not set, default is 128k for now */ + uint32_t lru_limit; ++ uint32_t invalidate_limit; + }; + typedef struct fuse_private fuse_private_t; + +diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in +index cbde42d..61d7422 100755 +--- a/xlators/mount/fuse/utils/mount.glusterfs.in ++++ b/xlators/mount/fuse/utils/mount.glusterfs.in +@@ -257,6 +257,10 @@ start_glusterfs () + cmd_line=$(echo "$cmd_line --lru-limit=$lru_limit"); + fi + ++ if [ -n "$invalidate_limit" ]; then ++ cmd_line=$(echo "$cmd_line --invalidate-limit=$invalidate_limit"); ++ fi ++ + if [ -n "$bg_qlen" ]; then + cmd_line=$(echo "$cmd_line --background-qlen=$bg_qlen"); + fi +@@ -505,6 +509,9 @@ with_options() + "lru-limit") + lru_limit=$value + ;; ++ "invalidate-limit") ++ invalidate_limit=$value ++ ;; + "background-qlen") + bg_qlen=$value + ;; +-- +1.8.3.1 + diff --git a/0338-glusterfs-fuse-Reduce-the-default-lru-limit-value.patch b/0338-glusterfs-fuse-Reduce-the-default-lru-limit-value.patch new file mode 100644 index 0000000..b108bd0 --- /dev/null +++ b/0338-glusterfs-fuse-Reduce-the-default-lru-limit-value.patch @@ -0,0 +1,83 @@ +From 6d2e12a53ef0bcbeea274c47537a0c707a3f7b1e Mon Sep 17 00:00:00 2001 +From: N Balachandran +Date: Fri, 20 Sep 2019 13:30:42 +0530 +Subject: [PATCH 338/344] glusterfs/fuse: Reduce the default lru-limit value + +The current lru-limit value still uses memory for +upto 128K inodes. +Reduce the default value of lru-limit to 64K. + +> Upstream https://review.gluster.org/23461 +> Change-Id: Ica2dd4f8f5fde45cb5180d8f02c3d86114ac52b3 +> Fixes: bz#1753880 +> Signed-off-by: N Balachandran +> Signed-off-by: Csaba Henk + +BUG: 1763208 +Change-Id: I04ab39b5278e702aacdceebfa5b63702b9f9703b +Signed-off-by: Csaba Henk +Reviewed-on: https://code.engineering.redhat.com/gerrit/187535 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + doc/mount.glusterfs.8 | 2 +- + glusterfsd/src/glusterfsd.c | 2 +- + xlators/mount/fuse/src/fuse-bridge.c | 2 +- + xlators/mount/fuse/src/fuse-bridge.h | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/doc/mount.glusterfs.8 b/doc/mount.glusterfs.8 +index b35b362..87a5669 100644 +--- a/doc/mount.glusterfs.8 ++++ b/doc/mount.glusterfs.8 +@@ -123,7 +123,7 @@ Provide list of backup volfile servers in the following format [default: None] + .TP + .TP + \fBlru-limit=\fRN +-Set fuse module's limit for number of inodes kept in LRU list to N [default: 131072] ++Set fuse module's limit for number of inodes kept in LRU list to N [default: 65536] + .TP + .TP + \fBinvalidate-limit=\fRN +diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c +index 0856471..974fb88 100644 +--- a/glusterfsd/src/glusterfsd.c ++++ b/glusterfsd/src/glusterfsd.c +@@ -211,7 +211,7 @@ static struct argp_option gf_options[] = { + "Resolve all auxiliary groups in fuse translator (max 32 otherwise)"}, + {"lru-limit", ARGP_FUSE_LRU_LIMIT_KEY, "N", 0, + "Set fuse module's limit for number of inodes kept in LRU list to N " +- "[default: 131072]"}, ++ "[default: 65536]"}, + {"invalidate-limit", ARGP_FUSE_INVALIDATE_LIMIT_KEY, "N", 0, + "Suspend inode invalidations implied by 'lru-limit' if the number of " + "outstanding invalidations reaches N"}, +diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c +index 8b2e7f0..ebe5c28 100644 +--- a/xlators/mount/fuse/src/fuse-bridge.c ++++ b/xlators/mount/fuse/src/fuse-bridge.c +@@ -6972,7 +6972,7 @@ struct volume_options options[] = { + { + .key = {"lru-limit"}, + .type = GF_OPTION_TYPE_INT, +- .default_value = "131072", ++ .default_value = "65536", + .min = 0, + .description = "makes glusterfs invalidate kernel inodes after " + "reaching this limit (0 means 'unlimited')", +diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h +index 2311582..cf4479c 100644 +--- a/xlators/mount/fuse/src/fuse-bridge.h ++++ b/xlators/mount/fuse/src/fuse-bridge.h +@@ -189,7 +189,7 @@ struct fuse_private { + gf_boolean_t flush_handle_interrupt; + gf_boolean_t fuse_auto_inval; + +- /* LRU Limit, if not set, default is 128k for now */ ++ /* LRU Limit, if not set, default is 64k for now */ + uint32_t lru_limit; + uint32_t invalidate_limit; + }; +-- +1.8.3.1 + diff --git a/0339-geo-rep-fix-integer-config-validation.patch b/0339-geo-rep-fix-integer-config-validation.patch new file mode 100644 index 0000000..45f3ede --- /dev/null +++ b/0339-geo-rep-fix-integer-config-validation.patch @@ -0,0 +1,93 @@ +From 8b5b3b247a00515d3188453c27b0ba749e93d325 Mon Sep 17 00:00:00 2001 +From: Aravinda VK +Date: Tue, 26 Mar 2019 13:20:13 +0530 +Subject: [PATCH 339/344] geo-rep: fix integer config validation + +ssh-port validation is mentioned as `validation=int` in template +`gsyncd.conf`, but not handled this during geo-rep config set. + +upstream patch: + https://review.gluster.org/#/c/glusterfs/+/22418/ +Backport of: + + >Fixes: bz#1692666 + >Change-Id: I3f19d9b471b0a3327e4d094dfbefcc58ed2c34f6 + >Signed-off-by: Aravinda VK + >Signed-off-by: Sunny Kumar + +BUG: 1782162 +Change-Id: I3f19d9b471b0a3327e4d094dfbefcc58ed2c34f6 +Signed-off-by: Sunny Kumar +Reviewed-on: https://code.engineering.redhat.com/gerrit/187533 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + geo-replication/syncdaemon/gsyncdconfig.py | 23 ++++++++++++++++++----- + tests/00-geo-rep/georep-basic-dr-rsync.t | 3 +++ + 2 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/geo-replication/syncdaemon/gsyncdconfig.py b/geo-replication/syncdaemon/gsyncdconfig.py +index f823311..8848071 100644 +--- a/geo-replication/syncdaemon/gsyncdconfig.py ++++ b/geo-replication/syncdaemon/gsyncdconfig.py +@@ -329,6 +329,9 @@ class Gconf(object): + if item["validation"] == "unixtime": + return validate_unixtime(value) + ++ if item["validation"] == "int": ++ return validate_int(value) ++ + return False + + def _is_config_changed(self): +@@ -381,6 +384,14 @@ def config_upgrade(config_file, ret): + config.write(configfile) + + ++def validate_int(value): ++ try: ++ _ = int(value) ++ return True ++ except ValueError: ++ return False ++ ++ + def validate_unixtime(value): + try: + y = datetime.fromtimestamp(int(value)).strftime("%Y") +@@ -393,11 +404,13 @@ def validate_unixtime(value): + + + def validate_minmax(value, minval, maxval): +- value = int(value) +- minval = int(minval) +- maxval = int(maxval) +- +- return value >= minval and value <= maxval ++ try: ++ value = int(value) ++ minval = int(minval) ++ maxval = int(maxval) ++ return value >= minval and value <= maxval ++ except ValueError: ++ return False + + + def validate_choice(value, allowed_values): +diff --git a/tests/00-geo-rep/georep-basic-dr-rsync.t b/tests/00-geo-rep/georep-basic-dr-rsync.t +index b432635..b6fbf18 100644 +--- a/tests/00-geo-rep/georep-basic-dr-rsync.t ++++ b/tests/00-geo-rep/georep-basic-dr-rsync.t +@@ -71,6 +71,9 @@ EXPECT_WITHIN $GEO_REP_TIMEOUT 4 check_status_num_rows "Created" + #Config gluster-command-dir + TEST $GEOREP_CLI $master $slave config gluster-command-dir ${GLUSTER_CMD_DIR} + ++#Config Set ssh-port to validate int validation ++TEST $GEOREP_CLI $master $slave config ssh-port 22 ++ + #Config gluster-command-dir + TEST $GEOREP_CLI $master $slave config slave-gluster-command-dir ${GLUSTER_CMD_DIR} + +-- +1.8.3.1 + diff --git a/0340-rpc-event_slot_alloc-converted-infinite-loop-after-r.patch b/0340-rpc-event_slot_alloc-converted-infinite-loop-after-r.patch new file mode 100644 index 0000000..54b2706 --- /dev/null +++ b/0340-rpc-event_slot_alloc-converted-infinite-loop-after-r.patch @@ -0,0 +1,46 @@ +From 0c996d6c40c625f8a0ee6be2c220c89aaf70c840 Mon Sep 17 00:00:00 2001 +From: Mohit Agrawal +Date: Tue, 10 Dec 2019 08:35:23 +0530 +Subject: [PATCH 340/344] rpc: event_slot_alloc converted infinite loop after + reach slot_used to 1024 + +Problem: In the commit faf5ac13c4ee00a05e9451bf8da3be2a9043bbf2 missed one + condition to come out from the loop so after reach the slot_used to + 1024 loop has become infinite loop + +Solution: Correct the code path to avoid the infinite loop + +> Change-Id: Ia02a109571f0d8cc9902c32db3e9b9282ee5c1db +> Fixes: bz#1781440 +> Credits: Xavi Hernandez +> Signed-off-by: Mohit Agrawal +> (Cherry picked from commit 8030f9c0f092170ceb50cedf59b9c330022825b7) +> (Reviewed on upstream link https://review.gluster.org/#/c/glusterfs/+/23843/) + +Change-Id: Ia02a109571f0d8cc9902c32db3e9b9282ee5c1db +BUG: 1781444 +Credits: Xavi Hernandez +Signed-off-by: Mohit Agrawal +Reviewed-on: https://code.engineering.redhat.com/gerrit/187460 +Tested-by: RHGS Build Bot +Reviewed-by: Xavi Hernandez Juan +--- + libglusterfs/src/event-epoll.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libglusterfs/src/event-epoll.c b/libglusterfs/src/event-epoll.c +index 65f5efd..5afb2f2 100644 +--- a/libglusterfs/src/event-epoll.c ++++ b/libglusterfs/src/event-epoll.c +@@ -92,7 +92,7 @@ retry: + while (i < EVENT_EPOLL_TABLES) { + switch (event_pool->slots_used[i]) { + case EVENT_EPOLL_SLOTS: +- continue; ++ break; + case 0: + if (!event_pool->ereg[i]) { + table = __event_newtable(event_pool, i); +-- +1.8.3.1 + diff --git a/0341-socket-fix-error-handling.patch b/0341-socket-fix-error-handling.patch new file mode 100644 index 0000000..0eb68d1 --- /dev/null +++ b/0341-socket-fix-error-handling.patch @@ -0,0 +1,742 @@ +From 2c99b7db00a6238fd43053dd672c8ce519d8fd27 Mon Sep 17 00:00:00 2001 +From: Xavi Hernandez +Date: Wed, 11 Dec 2019 18:21:14 +0100 +Subject: [PATCH 341/344] socket: fix error handling + +When __socket_proto_state_machine() detected a problem in the size of +the request or it couldn't allocate an iobuf of the requested size, it +returned -ENOMEM (-12). However the caller was expecting only -1 in +case of error. For this reason the error passes undetected initially, +adding back the socket to the epoll object. On further processing, +however, the error is finally detected and the connection terminated. +Meanwhile, another thread could receive a poll_in event from the same +connection, which could cause races with the connection destruction. +When this happened, the process crashed. + +To fix this, all error detection conditions have been hardened to be +more strict on what is valid and what not. Also, we don't return +-ENOMEM anymore. We always return -1 in case of error. + +An additional change has been done to prevent destruction of the +transport object while it may still be needed. + +Upstream patch: +> Change-Id: I6e59cd81cbf670f7adfdde942625d4e6c3fbc82d +> Upstream patch link: https://review.gluster.org/c/glusterfs/+/23861 +> Fixes: bz#1782495 +> Signed-off-by: Xavi Hernandez + +Change-Id: I6e59cd81cbf670f7adfdde942625d4e6c3fbc82d +BUG: 1779696 +Signed-off-by: Xavi Hernandez +Reviewed-on: https://code.engineering.redhat.com/gerrit/187689 +Tested-by: RHGS Build Bot +Reviewed-by: Raghavendra Gowdappa +--- + rpc/rpc-transport/socket/src/socket.c | 173 ++++++++++++++++++---------------- + 1 file changed, 90 insertions(+), 83 deletions(-) + +diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c +index bf2fa71..f54ca83 100644 +--- a/rpc/rpc-transport/socket/src/socket.c ++++ b/rpc/rpc-transport/socket/src/socket.c +@@ -173,7 +173,7 @@ ssl_setup_connection_params(rpc_transport_t *this); + \ + ret = __socket_readv(this, in->pending_vector, 1, &in->pending_vector, \ + &in->pending_count, &bytes_read); \ +- if (ret == -1) \ ++ if (ret < 0) \ + break; \ + __socket_proto_update_priv_after_read(priv, ret, bytes_read); \ + } +@@ -739,7 +739,7 @@ __socket_rwv(rpc_transport_t *this, struct iovec *vector, int count, + ret = sys_writev(sock, opvector, IOV_MIN(opcount)); + } + +- if (ret == 0 || (ret == -1 && errno == EAGAIN)) { ++ if ((ret == 0) || ((ret < 0) && (errno == EAGAIN))) { + /* done for now */ + break; + } else if (ret > 0) +@@ -754,7 +754,7 @@ __socket_rwv(rpc_transport_t *this, struct iovec *vector, int count, + errno = ENODATA; + ret = -1; + } +- if (ret == -1 && errno == EAGAIN) { ++ if ((ret < 0) && (errno == EAGAIN)) { + /* done for now */ + break; + } else if (ret > 0) +@@ -770,7 +770,7 @@ __socket_rwv(rpc_transport_t *this, struct iovec *vector, int count, + errno = ENOTCONN; + break; + } +- if (ret == -1) { ++ if (ret < 0) { + if (errno == EINTR) + continue; + +@@ -907,7 +907,7 @@ __socket_disconnect(rpc_transport_t *this) + gf_log(this->name, GF_LOG_TRACE, "disconnecting %p, sock=%d", this, + priv->sock); + +- if (priv->sock != -1) { ++ if (priv->sock >= 0) { + gf_log_callingfn(this->name, GF_LOG_TRACE, + "tearing down socket connection"); + ret = __socket_teardown_connection(this); +@@ -942,7 +942,7 @@ __socket_server_bind(rpc_transport_t *this) + + ret = setsockopt(priv->sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, + "setsockopt() for SO_REUSEADDR failed (%s)", strerror(errno)); + } +@@ -955,7 +955,7 @@ __socket_server_bind(rpc_transport_t *this) + if (reuse_check_sock >= 0) { + ret = connect(reuse_check_sock, SA(&unix_addr), + this->myinfo.sockaddr_len); +- if ((ret == -1) && (ECONNREFUSED == errno)) { ++ if ((ret != 0) && (ECONNREFUSED == errno)) { + sys_unlink(((struct sockaddr_un *)&unix_addr)->sun_path); + } + gf_log(this->name, GF_LOG_INFO, +@@ -967,7 +967,7 @@ __socket_server_bind(rpc_transport_t *this) + ret = bind(priv->sock, (struct sockaddr *)&this->myinfo.sockaddr, + this->myinfo.sockaddr_len); + +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, "binding to %s failed: %s", + this->myinfo.identifier, strerror(errno)); + if (errno == EADDRINUSE) { +@@ -976,7 +976,7 @@ __socket_server_bind(rpc_transport_t *this) + } + if (AF_UNIX != SA(&this->myinfo.sockaddr)->sa_family) { + if (getsockname(priv->sock, SA(&this->myinfo.sockaddr), +- &this->myinfo.sockaddr_len) == -1) { ++ &this->myinfo.sockaddr_len) != 0) { + gf_log(this->name, GF_LOG_WARNING, + "getsockname on (%d) failed (%s)", priv->sock, + strerror(errno)); +@@ -1004,7 +1004,7 @@ __socket_nonblock(int fd) + + flags = fcntl(fd, F_GETFL); + +- if (flags != -1) ++ if (flags >= 0) + ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + + return ret; +@@ -1034,7 +1034,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle, + #endif + + ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)); +- if (ret == -1) { ++ if (ret != 0) { + gf_log("socket", GF_LOG_WARNING, + "failed to set keep alive option on socket %d", fd); + goto err; +@@ -1051,7 +1051,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle, + ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &keepaliveintvl, + sizeof(keepaliveintvl)); + #endif +- if (ret == -1) { ++ if (ret != 0) { + gf_log("socket", GF_LOG_WARNING, + "failed to set keep alive interval on socket %d", fd); + goto err; +@@ -1062,7 +1062,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle, + + ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepaliveidle, + sizeof(keepaliveidle)); +- if (ret == -1) { ++ if (ret != 0) { + gf_log("socket", GF_LOG_WARNING, + "failed to set keep idle %d on socket %d, %s", keepaliveidle, fd, + strerror(errno)); +@@ -1070,7 +1070,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle, + } + ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepaliveintvl, + sizeof(keepaliveintvl)); +- if (ret == -1) { ++ if (ret != 0) { + gf_log("socket", GF_LOG_WARNING, + "failed to set keep interval %d on socket %d, %s", + keepaliveintvl, fd, strerror(errno)); +@@ -1082,7 +1082,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle, + goto done; + ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout_ms, + sizeof(timeout_ms)); +- if (ret == -1) { ++ if (ret != 0) { + gf_log("socket", GF_LOG_WARNING, + "failed to set " + "TCP_USER_TIMEOUT %d on socket %d, %s", +@@ -1093,7 +1093,7 @@ __socket_keepalive(int fd, int family, int keepaliveintvl, int keepaliveidle, + #if defined(TCP_KEEPCNT) + ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepalivecnt, + sizeof(keepalivecnt)); +- if (ret == -1) { ++ if (ret != 0) { + gf_log("socket", GF_LOG_WARNING, + "failed to set " + "TCP_KEEPCNT %d on socket %d, %s", +@@ -1366,7 +1366,7 @@ socket_event_poll_err(rpc_transport_t *this, int gen, int idx) + + pthread_mutex_lock(&priv->out_lock); + { +- if ((priv->gen == gen) && (priv->idx == idx) && (priv->sock != -1)) { ++ if ((priv->gen == gen) && (priv->idx == idx) && (priv->sock >= 0)) { + __socket_ioq_flush(this); + __socket_reset(this); + socket_closed = _gf_true; +@@ -1405,7 +1405,7 @@ socket_event_poll_out(rpc_transport_t *this) + if (priv->connected == 1) { + ret = __socket_ioq_churn(this); + +- if (ret == -1) { ++ if (ret < 0) { + gf_log(this->name, GF_LOG_TRACE, + "__socket_ioq_churn returned -1; " + "disconnecting socket"); +@@ -1463,7 +1463,7 @@ __socket_read_simple_msg(rpc_transport_t *this) + &bytes_read); + } + +- if (ret == -1) { ++ if (ret < 0) { + gf_log(this->name, GF_LOG_WARNING, + "reading from socket failed. Error (%s), " + "peer (%s)", +@@ -1661,8 +1661,8 @@ __socket_read_vectored_request(rpc_transport_t *this, + + remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read; + +- if ((ret == -1) || ((ret == 0) && (remaining_size == 0) && +- RPC_LASTFRAG(in->fraghdr))) { ++ if ((ret < 0) || ((ret == 0) && (remaining_size == 0) && ++ RPC_LASTFRAG(in->fraghdr))) { + request->vector_state = SP_STATE_VECTORED_REQUEST_INIT; + in->payload_vector.iov_len = ((unsigned long)frag->fragcurrent - + (unsigned long) +@@ -1739,8 +1739,8 @@ __socket_read_request(rpc_transport_t *this) + + remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read; + +- if ((ret == -1) || ((ret == 0) && (remaining_size == 0) && +- (RPC_LASTFRAG(in->fraghdr)))) { ++ if ((ret < 0) || ((ret == 0) && (remaining_size == 0) && ++ (RPC_LASTFRAG(in->fraghdr)))) { + request->header_state = SP_STATE_REQUEST_HEADER_INIT; + } + +@@ -1870,8 +1870,8 @@ __socket_read_accepted_successful_reply(rpc_transport_t *this) + /* now read the entire remaining msg into new iobuf */ + ret = __socket_read_simple_msg(this); + remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read; +- if ((ret == -1) || ((ret == 0) && (remaining_size == 0) && +- RPC_LASTFRAG(in->fraghdr))) { ++ if ((ret < 0) || ((ret == 0) && (remaining_size == 0) && ++ RPC_LASTFRAG(in->fraghdr))) { + frag->call_body.reply.accepted_success_state = + SP_STATE_ACCEPTED_SUCCESS_REPLY_INIT; + } +@@ -2003,8 +2003,8 @@ __socket_read_accepted_successful_reply_v2(rpc_transport_t *this) + /* now read the entire remaining msg into new iobuf */ + ret = __socket_read_simple_msg(this); + remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read; +- if ((ret == -1) || ((ret == 0) && (remaining_size == 0) && +- RPC_LASTFRAG(in->fraghdr))) { ++ if ((ret < 0) || ((ret == 0) && (remaining_size == 0) && ++ RPC_LASTFRAG(in->fraghdr))) { + frag->call_body.reply.accepted_success_state = + SP_STATE_ACCEPTED_SUCCESS_REPLY_INIT; + } +@@ -2103,8 +2103,8 @@ __socket_read_accepted_reply(rpc_transport_t *this) + + remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read; + +- if ((ret == -1) || ((ret == 0) && (remaining_size == 0) && +- (RPC_LASTFRAG(in->fraghdr)))) { ++ if ((ret < 0) || ((ret == 0) && (remaining_size == 0) && ++ (RPC_LASTFRAG(in->fraghdr)))) { + frag->call_body.reply + .accepted_state = SP_STATE_ACCEPTED_REPLY_INIT; + } +@@ -2169,8 +2169,8 @@ __socket_read_vectored_reply(rpc_transport_t *this) + + remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read; + +- if ((ret == -1) || ((ret == 0) && (remaining_size == 0) && +- (RPC_LASTFRAG(in->fraghdr)))) { ++ if ((ret < 0) || ((ret == 0) && (remaining_size == 0) && ++ (RPC_LASTFRAG(in->fraghdr)))) { + frag->call_body.reply + .status_state = SP_STATE_VECTORED_REPLY_STATUS_INIT; + in->payload_vector.iov_len = (unsigned long)frag->fragcurrent - +@@ -2237,7 +2237,7 @@ __socket_read_reply(rpc_transport_t *this) + /* Transition back to externally visible state. */ + frag->state = SP_STATE_READ_MSGTYPE; + +- if (ret == -1) { ++ if (ret < 0) { + gf_log(this->name, GF_LOG_WARNING, + "notify for event MAP_XID failed for %s", + this->peerinfo.identifier); +@@ -2315,8 +2315,8 @@ __socket_read_frag(rpc_transport_t *this) + + remaining_size = RPC_FRAGSIZE(in->fraghdr) - frag->bytes_read; + +- if ((ret == -1) || ((ret == 0) && (remaining_size == 0) && +- (RPC_LASTFRAG(in->fraghdr)))) { ++ if ((ret < 0) || ((ret == 0) && (remaining_size == 0) && ++ (RPC_LASTFRAG(in->fraghdr)))) { + /* frag->state = SP_STATE_NADA; */ + frag->state = SP_STATE_RPCFRAG_INIT; + } +@@ -2400,7 +2400,7 @@ __socket_proto_state_machine(rpc_transport_t *this, + ret = __socket_readv(this, in->pending_vector, 1, + &in->pending_vector, &in->pending_count, + NULL); +- if (ret == -1) ++ if (ret < 0) + goto out; + + if (ret > 0) { +@@ -2422,7 +2422,7 @@ __socket_proto_state_machine(rpc_transport_t *this, + in->total_bytes_read += RPC_FRAGSIZE(in->fraghdr); + + if (in->total_bytes_read >= GF_UNIT_GB) { +- ret = -ENOMEM; ++ ret = -1; + goto out; + } + +@@ -2430,7 +2430,7 @@ __socket_proto_state_machine(rpc_transport_t *this, + this->ctx->iobuf_pool, + (in->total_bytes_read + sizeof(in->fraghdr))); + if (!iobuf) { +- ret = -ENOMEM; ++ ret = -1; + goto out; + } + +@@ -2457,7 +2457,7 @@ __socket_proto_state_machine(rpc_transport_t *this, + case SP_STATE_READING_FRAG: + ret = __socket_read_frag(this); + +- if ((ret == -1) || ++ if ((ret < 0) || + (frag->bytes_read != RPC_FRAGSIZE(in->fraghdr))) { + goto out; + } +@@ -2575,7 +2575,7 @@ socket_event_poll_in(rpc_transport_t *this, gf_boolean_t notify_handled) + pthread_mutex_unlock(&priv->notify.lock); + } + +- if (notify_handled && (ret != -1)) ++ if (notify_handled && (ret >= 0)) + event_handled(ctx->event_pool, priv->sock, priv->idx, priv->gen); + + if (pollin) { +@@ -2618,10 +2618,10 @@ socket_connect_finish(rpc_transport_t *this) + + ret = __socket_connect_finish(priv->sock); + +- if (ret == -1 && errno == EINPROGRESS) ++ if ((ret < 0) && (errno == EINPROGRESS)) + ret = 1; + +- if (ret == -1 && errno != EINPROGRESS) { ++ if ((ret < 0) && (errno != EINPROGRESS)) { + if (!priv->connect_finish_log) { + gf_log(this->name, GF_LOG_ERROR, + "connection to %s failed (%s); " +@@ -2640,7 +2640,7 @@ socket_connect_finish(rpc_transport_t *this) + + ret = getsockname(priv->sock, SA(&this->myinfo.sockaddr), + &this->myinfo.sockaddr_len); +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_WARNING, + "getsockname on (%d) failed (%s) - " + "disconnecting socket", +@@ -2924,6 +2924,13 @@ socket_event_handler(int fd, int idx, int gen, void *data, int poll_in, + return; + } + ++ /* At this point we are sure no other thread is using the transport because ++ * we cannot receive more events until we call gf_event_handled(). However ++ * this function may call gf_event_handled() in some cases. When this is ++ * done, the transport may be destroyed at any moment if another thread ++ * handled an error event. To prevent that we take a reference here. */ ++ rpc_transport_ref(this); ++ + GF_VALIDATE_OR_GOTO("socket", this, out); + GF_VALIDATE_OR_GOTO("socket", this->private, out); + GF_VALIDATE_OR_GOTO("socket", this->xl, out); +@@ -2960,7 +2967,7 @@ socket_event_handler(int fd, int idx, int gen, void *data, int poll_in, + if (ret > 0) { + gf_log(this->name, GF_LOG_TRACE, + "(sock:%d) returning to wait on socket", priv->sock); +- return; ++ goto out; + } + } else { + char *sock_type = (priv->is_server ? "Server" : "Client"); +@@ -3015,7 +3022,7 @@ socket_event_handler(int fd, int idx, int gen, void *data, int poll_in, + } + + out: +- return; ++ rpc_transport_unref(this); + } + + static void +@@ -3074,7 +3081,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in, + + event_handled(ctx->event_pool, fd, idx, gen); + +- if (new_sock == -1) { ++ if (new_sock < 0) { + gf_log(this->name, GF_LOG_WARNING, "accept on %d failed (%s)", + priv->sock, strerror(errno)); + goto out; +@@ -3082,7 +3089,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in, + + if (priv->nodelay && (new_sockaddr.ss_family != AF_UNIX)) { + ret = __socket_nodelay(new_sock); +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_WARNING, + "setsockopt() failed for " + "NODELAY (%s)", +@@ -3094,7 +3101,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in, + ret = __socket_keepalive(new_sock, new_sockaddr.ss_family, + priv->keepaliveintvl, priv->keepaliveidle, + priv->keepalivecnt, priv->timeout); +- if (ret == -1) ++ if (ret != 0) + gf_log(this->name, GF_LOG_WARNING, + "Failed to set keep-alive: %s", strerror(errno)); + } +@@ -3110,7 +3117,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in, + } + + ret = pthread_mutex_init(&new_trans->lock, NULL); +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_WARNING, + "pthread_mutex_init() failed: %s; closing newly accepted " + "socket %d", +@@ -3130,7 +3137,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in, + + ret = getsockname(new_sock, SA(&new_trans->myinfo.sockaddr), + &new_trans->myinfo.sockaddr_len); +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_WARNING, + "getsockname on socket %d " + "failed (errno:%s); closing newly accepted socket", +@@ -3237,7 +3244,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in, + */ + ret = rpc_transport_notify(this, RPC_TRANSPORT_ACCEPT, new_trans); + +- if (ret != -1) { ++ if (ret >= 0) { + new_priv->idx = event_register( + ctx->event_pool, new_sock, socket_event_handler, new_trans, + 1, 0, new_trans->notify_poller_death); +@@ -3275,7 +3282,7 @@ socket_server_event_handler(int fd, int idx, int gen, void *data, int poll_in, + rpc_transport_unref(new_trans); + } + +- if (ret == -1) { ++ if (ret < 0) { + gf_log(this->name, GF_LOG_WARNING, "closing newly accepted socket"); + sys_close(new_sock); + /* this unref is to actually cause the destruction of +@@ -3406,7 +3413,7 @@ socket_connect(rpc_transport_t *this, int port) + + pthread_mutex_lock(&priv->out_lock); + { +- if (priv->sock != -1) { ++ if (priv->sock >= 0) { + gf_log_callingfn(this->name, GF_LOG_TRACE, + "connect () called on transport " + "already connected"); +@@ -3420,7 +3427,7 @@ socket_connect(rpc_transport_t *this, int port) + + ret = socket_client_get_remote_sockaddr(this, &sock_union.sa, + &sockaddr_len, &sa_family); +- if (ret == -1) { ++ if (ret < 0) { + /* logged inside client_get_remote_sockaddr */ + goto unlock; + } +@@ -3439,7 +3446,7 @@ socket_connect(rpc_transport_t *this, int port) + this->peerinfo.sockaddr_len = sockaddr_len; + + priv->sock = sys_socket(sa_family, SOCK_STREAM, 0); +- if (priv->sock == -1) { ++ if (priv->sock < 0) { + gf_log(this->name, GF_LOG_ERROR, "socket creation failed (%s)", + strerror(errno)); + ret = -1; +@@ -3451,7 +3458,7 @@ socket_connect(rpc_transport_t *this, int port) + */ + if (priv->windowsize != 0) { + if (setsockopt(priv->sock, SOL_SOCKET, SO_RCVBUF, &priv->windowsize, +- sizeof(priv->windowsize)) < 0) { ++ sizeof(priv->windowsize)) != 0) { + gf_log(this->name, GF_LOG_ERROR, + "setting receive window " + "size failed: %d: %d: %s", +@@ -3459,7 +3466,7 @@ socket_connect(rpc_transport_t *this, int port) + } + + if (setsockopt(priv->sock, SOL_SOCKET, SO_SNDBUF, &priv->windowsize, +- sizeof(priv->windowsize)) < 0) { ++ sizeof(priv->windowsize)) != 0) { + gf_log(this->name, GF_LOG_ERROR, + "setting send window size " + "failed: %d: %d: %s", +@@ -3484,7 +3491,7 @@ socket_connect(rpc_transport_t *this, int port) + if (priv->nodelay && (sa_family != AF_UNIX)) { + ret = __socket_nodelay(priv->sock); + +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, "NODELAY on %d failed (%s)", + priv->sock, strerror(errno)); + } +@@ -3494,7 +3501,7 @@ socket_connect(rpc_transport_t *this, int port) + ret = __socket_keepalive(priv->sock, sa_family, + priv->keepaliveintvl, priv->keepaliveidle, + priv->keepalivecnt, priv->timeout); +- if (ret == -1) ++ if (ret != 0) + gf_log(this->name, GF_LOG_ERROR, "Failed to set keep-alive: %s", + strerror(errno)); + } +@@ -3516,7 +3523,7 @@ socket_connect(rpc_transport_t *this, int port) + + ret = client_bind(this, SA(&this->myinfo.sockaddr), + &this->myinfo.sockaddr_len, priv->sock); +- if (ret == -1) { ++ if (ret < 0) { + gf_log(this->name, GF_LOG_WARNING, "client bind failed: %s", + strerror(errno)); + goto handler; +@@ -3525,7 +3532,7 @@ socket_connect(rpc_transport_t *this, int port) + /* make socket non-blocking for all types of sockets */ + if (!priv->bio) { + ret = __socket_nonblock(priv->sock); +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, "NBIO on %d failed (%s)", + priv->sock, strerror(errno)); + goto handler; +@@ -3552,7 +3559,7 @@ socket_connect(rpc_transport_t *this, int port) + + connect_attempted = _gf_true; + +- if (ret == -1 && errno == ENOENT && ign_enoent) { ++ if ((ret != 0) && (errno == ENOENT) && ign_enoent) { + gf_log(this->name, GF_LOG_WARNING, + "Ignore failed connection attempt on %s, (%s) ", + this->peerinfo.identifier, strerror(errno)); +@@ -3570,7 +3577,7 @@ socket_connect(rpc_transport_t *this, int port) + goto handler; + } + +- if (ret == -1 && ((errno != EINPROGRESS) && (errno != ENOENT))) { ++ if ((ret != 0) && (errno != EINPROGRESS) && (errno != ENOENT)) { + /* For unix path based sockets, the socket path is + * cryptic (md5sum of path) and may not be useful for + * the user in debugging so log it in DEBUG +@@ -3634,8 +3641,8 @@ socket_connect(rpc_transport_t *this, int port) + pthread_mutex_unlock(&priv->out_lock); + + err: +- /* if sock != -1, then cleanup is done from the event handler */ +- if (ret == -1 && sock == -1) { ++ /* if sock >= 0, then cleanup is done from the event handler */ ++ if ((ret < 0) && (sock < 0)) { + /* Cleaup requires to send notification to upper layer which + intern holds the big_lock. There can be dead-lock situation + if big_lock is already held by the current thread. +@@ -3689,20 +3696,20 @@ socket_listen(rpc_transport_t *this) + } + pthread_mutex_unlock(&priv->out_lock); + +- if (sock != -1) { ++ if (sock >= 0) { + gf_log_callingfn(this->name, GF_LOG_DEBUG, "already listening"); + return ret; + } + + ret = socket_server_get_local_sockaddr(this, SA(&sockaddr), &sockaddr_len, + &sa_family); +- if (ret == -1) { ++ if (ret < 0) { + return ret; + } + + pthread_mutex_lock(&priv->out_lock); + { +- if (priv->sock != -1) { ++ if (priv->sock >= 0) { + gf_log(this->name, GF_LOG_DEBUG, "already listening"); + goto unlock; + } +@@ -3712,7 +3719,7 @@ socket_listen(rpc_transport_t *this) + + priv->sock = sys_socket(sa_family, SOCK_STREAM, 0); + +- if (priv->sock == -1) { ++ if (priv->sock < 0) { + gf_log(this->name, GF_LOG_ERROR, "socket creation failed (%s)", + strerror(errno)); + goto unlock; +@@ -3723,7 +3730,7 @@ socket_listen(rpc_transport_t *this) + */ + if (priv->windowsize != 0) { + if (setsockopt(priv->sock, SOL_SOCKET, SO_RCVBUF, &priv->windowsize, +- sizeof(priv->windowsize)) < 0) { ++ sizeof(priv->windowsize)) != 0) { + gf_log(this->name, GF_LOG_ERROR, + "setting receive window size " + "failed: %d: %d: %s", +@@ -3731,7 +3738,7 @@ socket_listen(rpc_transport_t *this) + } + + if (setsockopt(priv->sock, SOL_SOCKET, SO_SNDBUF, &priv->windowsize, +- sizeof(priv->windowsize)) < 0) { ++ sizeof(priv->windowsize)) != 0) { + gf_log(this->name, GF_LOG_ERROR, + "setting send window size failed:" + " %d: %d: %s", +@@ -3741,7 +3748,7 @@ socket_listen(rpc_transport_t *this) + + if (priv->nodelay && (sa_family != AF_UNIX)) { + ret = __socket_nodelay(priv->sock); +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, + "setsockopt() failed for NODELAY (%s)", strerror(errno)); + } +@@ -3750,7 +3757,7 @@ socket_listen(rpc_transport_t *this) + if (!priv->bio) { + ret = __socket_nonblock(priv->sock); + +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, + "NBIO on socket %d failed " + "(errno:%s); closing socket", +@@ -3763,7 +3770,7 @@ socket_listen(rpc_transport_t *this) + + ret = __socket_server_bind(this); + +- if ((ret == -EADDRINUSE) || (ret == -1)) { ++ if (ret < 0) { + /* logged inside __socket_server_bind() */ + gf_log(this->name, GF_LOG_ERROR, + "__socket_server_bind failed;" +@@ -3779,7 +3786,7 @@ socket_listen(rpc_transport_t *this) + + ret = listen(priv->sock, priv->backlog); + +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, + "could not set socket %d to listen mode (errno:%s); " + "closing socket", +@@ -4025,7 +4032,7 @@ reconfigure(rpc_transport_t *this, dict_t *options) + priv = this->private; + + if (dict_get_str(options, "transport.socket.keepalive", &optstr) == 0) { +- if (gf_string2boolean(optstr, &tmp_bool) == -1) { ++ if (gf_string2boolean(optstr, &tmp_bool) != 0) { + gf_log(this->name, GF_LOG_ERROR, + "'transport.socket.keepalive' takes only " + "boolean options, not taking any action"); +@@ -4094,7 +4101,7 @@ reconfigure(rpc_transport_t *this, dict_t *options) + if (dict_get(options, "non-blocking-io")) { + optstr = data_to_str(dict_get(options, "non-blocking-io")); + +- if (gf_string2boolean(optstr, &tmp_bool) == -1) { ++ if (gf_string2boolean(optstr, &tmp_bool) != 0) { + gf_log(this->name, GF_LOG_ERROR, + "'non-blocking-io' takes only boolean options," + " not taking any action"); +@@ -4109,7 +4116,7 @@ reconfigure(rpc_transport_t *this, dict_t *options) + + if (!priv->bio) { + ret = __socket_nonblock(priv->sock); +- if (ret == -1) { ++ if (ret != 0) { + gf_log(this->name, GF_LOG_WARNING, "NBIO on %d failed (%s)", + priv->sock, strerror(errno)); + goto out; +@@ -4508,7 +4515,7 @@ socket_init(rpc_transport_t *this) + if (dict_get(this->options, "non-blocking-io")) { + optstr = data_to_str(dict_get(this->options, "non-blocking-io")); + +- if (gf_string2boolean(optstr, &tmp_bool) == -1) { ++ if (gf_string2boolean(optstr, &tmp_bool) != 0) { + gf_log(this->name, GF_LOG_ERROR, + "'non-blocking-io' takes only boolean options," + " not taking any action"); +@@ -4528,7 +4535,7 @@ socket_init(rpc_transport_t *this) + optstr = data_to_str( + dict_get(this->options, "transport.socket.nodelay")); + +- if (gf_string2boolean(optstr, &tmp_bool) == -1) { ++ if (gf_string2boolean(optstr, &tmp_bool) != 0) { + gf_log(this->name, GF_LOG_ERROR, + "'transport.socket.nodelay' takes only " + "boolean options, not taking any action"); +@@ -4559,7 +4566,7 @@ socket_init(rpc_transport_t *this) + priv->keepalivecnt = GF_KEEPALIVE_COUNT; + if (dict_get_str(this->options, "transport.socket.keepalive", &optstr) == + 0) { +- if (gf_string2boolean(optstr, &tmp_bool) == -1) { ++ if (gf_string2boolean(optstr, &tmp_bool) != 0) { + gf_log(this->name, GF_LOG_ERROR, + "'transport.socket.keepalive' takes only " + "boolean options, not taking any action"); +@@ -4609,7 +4616,7 @@ socket_init(rpc_transport_t *this) + if (dict_get(this->options, "transport.socket.read-fail-log")) { + optstr = data_to_str( + dict_get(this->options, "transport.socket.read-fail-log")); +- if (gf_string2boolean(optstr, &tmp_bool) == -1) { ++ if (gf_string2boolean(optstr, &tmp_bool) != 0) { + gf_log(this->name, GF_LOG_WARNING, + "'transport.socket.read-fail-log' takes only " + "boolean options; logging socket read fails"); +@@ -4646,7 +4653,7 @@ fini(rpc_transport_t *this) + + priv = this->private; + if (priv) { +- if (priv->sock != -1) { ++ if (priv->sock >= 0) { + pthread_mutex_lock(&priv->out_lock); + { + __socket_ioq_flush(this); +@@ -4683,7 +4690,7 @@ init(rpc_transport_t *this) + + ret = socket_init(this); + +- if (ret == -1) { ++ if (ret < 0) { + gf_log(this->name, GF_LOG_DEBUG, "socket_init() failed"); + } + +-- +1.8.3.1 + diff --git a/0342-Revert-hooks-remove-selinux-hooks.patch b/0342-Revert-hooks-remove-selinux-hooks.patch new file mode 100644 index 0000000..028a227 --- /dev/null +++ b/0342-Revert-hooks-remove-selinux-hooks.patch @@ -0,0 +1,120 @@ +From eb37a3b57415d2d4206ecdd2db10530366a0d1b1 Mon Sep 17 00:00:00 2001 +From: Anoop C S +Date: Fri, 13 Dec 2019 15:20:27 +0530 +Subject: [PATCH 342/344] Revert "hooks: remove selinux hooks" + +This reverts commit 421743b7cfa6a249544f6abb4cca5a612bd20ea1. + +Note:- We are not bringing back features.selinux but just the hooks for + setting SELinux context on bricks + +Label: DOWNSTREAM ONLY + +Change-Id: Iccc10428361cac59b294e1d7aa1ba8187c20029e +BUG: 1686800 +Signed-off-by: Anoop C S +Reviewed-on: https://code.engineering.redhat.com/gerrit/187691 +Tested-by: RHGS Build Bot +Reviewed-by: Niels de Vos +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + configure.ac | 4 ++++ + extras/hook-scripts/Makefile.am | 2 +- + extras/hook-scripts/create/Makefile.am | 1 + + extras/hook-scripts/create/post/Makefile.am | 6 ++++++ + extras/hook-scripts/delete/Makefile.am | 1 + + extras/hook-scripts/delete/pre/Makefile.am | 6 ++++++ + glusterfs.spec.in | 2 ++ + 7 files changed, 21 insertions(+), 1 deletion(-) + create mode 100644 extras/hook-scripts/create/Makefile.am + create mode 100644 extras/hook-scripts/create/post/Makefile.am + create mode 100644 extras/hook-scripts/delete/Makefile.am + create mode 100644 extras/hook-scripts/delete/pre/Makefile.am + +diff --git a/configure.ac b/configure.ac +index 327733e..98ee311 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -221,6 +221,10 @@ AC_CONFIG_FILES([Makefile + extras/hook-scripts/add-brick/Makefile + extras/hook-scripts/add-brick/pre/Makefile + extras/hook-scripts/add-brick/post/Makefile ++ extras/hook-scripts/create/Makefile ++ extras/hook-scripts/create/post/Makefile ++ extras/hook-scripts/delete/Makefile ++ extras/hook-scripts/delete/pre/Makefile + extras/hook-scripts/start/Makefile + extras/hook-scripts/start/post/Makefile + extras/hook-scripts/set/Makefile +diff --git a/extras/hook-scripts/Makefile.am b/extras/hook-scripts/Makefile.am +index 771b37e..26059d7 100644 +--- a/extras/hook-scripts/Makefile.am ++++ b/extras/hook-scripts/Makefile.am +@@ -1,5 +1,5 @@ + EXTRA_DIST = S40ufo-stop.py S56glusterd-geo-rep-create-post.sh +-SUBDIRS = add-brick set start stop reset ++SUBDIRS = add-brick create delete set start stop reset + + scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/gsync-create/post/ + if USE_GEOREP +diff --git a/extras/hook-scripts/create/Makefile.am b/extras/hook-scripts/create/Makefile.am +new file mode 100644 +index 0000000..b083a91 +--- /dev/null ++++ b/extras/hook-scripts/create/Makefile.am +@@ -0,0 +1 @@ ++SUBDIRS = post +diff --git a/extras/hook-scripts/create/post/Makefile.am b/extras/hook-scripts/create/post/Makefile.am +new file mode 100644 +index 0000000..919801a +--- /dev/null ++++ b/extras/hook-scripts/create/post/Makefile.am +@@ -0,0 +1,6 @@ ++EXTRA_DIST = S10selinux-label-brick.sh ++ ++scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/create/post/ ++if WITH_SERVER ++scripts_SCRIPTS = S10selinux-label-brick.sh ++endif +diff --git a/extras/hook-scripts/delete/Makefile.am b/extras/hook-scripts/delete/Makefile.am +new file mode 100644 +index 0000000..c98a05d +--- /dev/null ++++ b/extras/hook-scripts/delete/Makefile.am +@@ -0,0 +1 @@ ++SUBDIRS = pre +diff --git a/extras/hook-scripts/delete/pre/Makefile.am b/extras/hook-scripts/delete/pre/Makefile.am +new file mode 100644 +index 0000000..93a6b85 +--- /dev/null ++++ b/extras/hook-scripts/delete/pre/Makefile.am +@@ -0,0 +1,6 @@ ++EXTRA_DIST = S10selinux-del-fcontext.sh ++ ++scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/delete/pre/ ++if WITH_SERVER ++scripts_SCRIPTS = S10selinux-del-fcontext.sh ++endif +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 1b975b2..012989a 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1453,6 +1453,7 @@ exit 0 + %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/pre/S28Quota-enable-root-xattr-heal.sh + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/post ++ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/post/S10selinux-label-brick.sh + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/pre + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/copy-file + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/copy-file/post +@@ -1461,6 +1462,7 @@ exit 0 + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/post + %{_sharedstatedir}/glusterd/hooks/1/delete/post/S57glusterfind-delete-post + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/pre ++ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/pre/S10selinux-del-fcontext.sh + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/remove-brick + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/remove-brick/post + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/remove-brick/pre +-- +1.8.3.1 + diff --git a/0343-extras-hooks-syntactical-errors-in-SELinux-hooks-sci.patch b/0343-extras-hooks-syntactical-errors-in-SELinux-hooks-sci.patch new file mode 100644 index 0000000..77d2f64 --- /dev/null +++ b/0343-extras-hooks-syntactical-errors-in-SELinux-hooks-sci.patch @@ -0,0 +1,155 @@ +From 8a8c508b529f7609fc5caa10bc79ba817f5d274a Mon Sep 17 00:00:00 2001 +From: Milan Zink +Date: Mon, 5 Feb 2018 15:04:37 +0100 +Subject: [PATCH 343/344] extras/hooks: syntactical errors in SELinux hooks, + scipt logic improved + +Backport of https://review.gluster.org/c/glusterfs/+/19502 + +Change-Id: Ia5fa1df81bbaec3a84653d136a331c76b457f42c +BUG: 1686800 +Signed-off-by: Anoop C S +Reviewed-on: https://code.engineering.redhat.com/gerrit/187692 +Tested-by: RHGS Build Bot +Reviewed-by: Niels de Vos +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + .../create/post/S10selinux-label-brick.sh | 13 +++-- + .../delete/pre/S10selinux-del-fcontext.sh | 60 +++++++++++++--------- + tests/bugs/glusterfs-server/bug-877992.t | 4 +- + 3 files changed, 46 insertions(+), 31 deletions(-) + +diff --git a/extras/hook-scripts/create/post/S10selinux-label-brick.sh b/extras/hook-scripts/create/post/S10selinux-label-brick.sh +index de242d2..f9b4b1a 100755 +--- a/extras/hook-scripts/create/post/S10selinux-label-brick.sh ++++ b/extras/hook-scripts/create/post/S10selinux-label-brick.sh +@@ -34,18 +34,21 @@ parse_args () { + + set_brick_labels() + { +- volname=${1} ++ volname="${1}" + + # grab the path for each local brick +- brickpath="/var/lib/glusterd/vols/${volname}/bricks/*" +- brickdirs=$(grep '^path=' "${brickpath}" | cut -d= -f 2 | sort -u) ++ brickpath="/var/lib/glusterd/vols/${volname}/bricks/" ++ brickdirs=$( ++ find "${brickpath}" -type f -exec grep '^path=' {} \; | \ ++ cut -d= -f 2 | \ ++ sort -u ++ ) + + for b in ${brickdirs}; do + # Add a file context for each brick path and associate with the + # glusterd_brick_t SELinux type. +- pattern="${b}\(/.*\)?" ++ pattern="${b}(/.*)?" + semanage fcontext --add -t glusterd_brick_t -r s0 "${pattern}" +- + # Set the labels on the new brick path. + restorecon -R "${b}" + done +diff --git a/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh b/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh +index 6eba66f..e7f4e8f 100755 +--- a/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh ++++ b/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh +@@ -15,45 +15,55 @@ OPTSPEC="volname:" + VOL= + + function parse_args () { +- ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@") +- eval set -- "$ARGS" +- +- while true; do +- case $1 in +- --volname) +- shift +- VOL=$1 +- ;; +- *) +- shift +- break +- ;; +- esac ++ ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@") ++ eval set -- "${ARGS}" ++ ++ while true; do ++ case ${1} in ++ --volname) ++ shift ++ VOL=${1} ++ ;; ++ *) + shift +- done ++ break ++ ;; ++ esac ++ shift ++ done + } + + function delete_brick_fcontext() + { +- volname=$1 ++ volname="${1}" ++ ++ # grab the path for each local brick ++ brickpath="/var/lib/glusterd/vols/${volname}/bricks/" ++ brickdirs=$( ++ find "${brickpath}" -type f -exec grep '^path=' {} \; | \ ++ cut -d= -f 2 | \ ++ sort -u ++ ) ++ ++ for b in ${brickdirs} ++ do ++ # remove the file context associated with the brick path ++ pattern="${b}(/.*)?" ++ semanage fcontext --delete "${pattern}" + +- # grab the path for each local brick +- brickdirs=$(grep '^path=' /var/lib/glusterd/vols/${volname}/bricks/* | cut -d= -f 2) ++ # remove the labels on brick path. ++ restorecon -R "${b}" ++ done + +- for b in $brickdirs +- do +- # remove the file context associated with the brick path +- semanage fcontext --delete $b\(/.*\)? +- done + } + + SELINUX_STATE=$(which getenforce && getenforce) + [ "${SELINUX_STATE}" = 'Disabled' ] && exit 0 + + parse_args "$@" +-[ -z "$VOL" ] && exit 1 ++[ -z "${VOL}" ] && exit 1 + +-delete_brick_fcontext $VOL ++delete_brick_fcontext "${VOL}" + + # failure to delete the fcontext is not fatal + exit 0 +diff --git a/tests/bugs/glusterfs-server/bug-877992.t b/tests/bugs/glusterfs-server/bug-877992.t +index aeb73ed..300000b 100755 +--- a/tests/bugs/glusterfs-server/bug-877992.t ++++ b/tests/bugs/glusterfs-server/bug-877992.t +@@ -46,7 +46,9 @@ TEST $CLI volume create $V0 $H0:$B0/${V0}1; + EXPECT "$V0" volinfo_field $V0 'Volume Name'; + EXPECT 'Created' volinfo_field $V0 'Status'; + EXPECT 'createPre' cat /tmp/pre.out; +-EXPECT 'createPost' cat /tmp/post.out; ++# Spost.sh comes after S10selinux-label-brick.sh under create post hook script ++# list. So consider the delay in setting SELinux context on bricks ++EXPECT_WITHIN 5 'createPost' cat /tmp/post.out; + hooks_cleanup 'create' + + +-- +1.8.3.1 + diff --git a/0344-Revert-all-fixes-to-include-SELinux-hook-scripts.patch b/0344-Revert-all-fixes-to-include-SELinux-hook-scripts.patch new file mode 100644 index 0000000..341aeae --- /dev/null +++ b/0344-Revert-all-fixes-to-include-SELinux-hook-scripts.patch @@ -0,0 +1,412 @@ +From 02a93265fe4e78e7fc3fa8c6caa773cbe02f50b6 Mon Sep 17 00:00:00 2001 +From: Anoop C S +Date: Fri, 20 Dec 2019 16:01:59 +0530 +Subject: [PATCH 344/344] Revert all fixes to include SELinux hook scripts + +Following are the reverts included with this change: + +Revert "extras/hooks: syntactical errors in SELinux hooks, scipt logic improved" +Revert "Revert "hooks: remove selinux hooks"" +Revert "tests: subdir-mount.t is failing for brick_mux regrssion" +Revert "extras/hooks: Install and package newly added post add-brick hook script" +Revert "extras/hooks: Add SELinux label on new bricks during add-brick" + +Label: DOWNSTREAM ONLY + +See bug for more details. + +Change-Id: I5c9b9e0e6446568ce16af17257fa39338198a827 +BUG: 1686800 +Signed-off-by: Anoop C S +Reviewed-on: https://code.engineering.redhat.com/gerrit/188169 +Tested-by: RHGS Build Bot +Reviewed-by: Sunil Kumar Heggodu Gopala Acharya +--- + configure.ac | 4 - + extras/hook-scripts/Makefile.am | 2 +- + extras/hook-scripts/add-brick/post/Makefile.am | 4 +- + .../add-brick/post/S10selinux-label-brick.sh | 100 --------------------- + extras/hook-scripts/create/Makefile.am | 1 - + extras/hook-scripts/create/post/Makefile.am | 6 -- + .../create/post/S10selinux-label-brick.sh | 13 ++- + extras/hook-scripts/delete/Makefile.am | 1 - + extras/hook-scripts/delete/pre/Makefile.am | 6 -- + .../delete/pre/S10selinux-del-fcontext.sh | 60 ++++++------- + glusterfs.spec.in | 3 - + tests/bugs/glusterfs-server/bug-877992.t | 4 +- + tests/features/subdir-mount.t | 11 +-- + 13 files changed, 37 insertions(+), 178 deletions(-) + delete mode 100755 extras/hook-scripts/add-brick/post/S10selinux-label-brick.sh + delete mode 100644 extras/hook-scripts/create/Makefile.am + delete mode 100644 extras/hook-scripts/create/post/Makefile.am + delete mode 100644 extras/hook-scripts/delete/Makefile.am + delete mode 100644 extras/hook-scripts/delete/pre/Makefile.am + +diff --git a/configure.ac b/configure.ac +index 98ee311..327733e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -221,10 +221,6 @@ AC_CONFIG_FILES([Makefile + extras/hook-scripts/add-brick/Makefile + extras/hook-scripts/add-brick/pre/Makefile + extras/hook-scripts/add-brick/post/Makefile +- extras/hook-scripts/create/Makefile +- extras/hook-scripts/create/post/Makefile +- extras/hook-scripts/delete/Makefile +- extras/hook-scripts/delete/pre/Makefile + extras/hook-scripts/start/Makefile + extras/hook-scripts/start/post/Makefile + extras/hook-scripts/set/Makefile +diff --git a/extras/hook-scripts/Makefile.am b/extras/hook-scripts/Makefile.am +index 26059d7..771b37e 100644 +--- a/extras/hook-scripts/Makefile.am ++++ b/extras/hook-scripts/Makefile.am +@@ -1,5 +1,5 @@ + EXTRA_DIST = S40ufo-stop.py S56glusterd-geo-rep-create-post.sh +-SUBDIRS = add-brick create delete set start stop reset ++SUBDIRS = add-brick set start stop reset + + scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/gsync-create/post/ + if USE_GEOREP +diff --git a/extras/hook-scripts/add-brick/post/Makefile.am b/extras/hook-scripts/add-brick/post/Makefile.am +index 9b236df..bfc0c1c 100644 +--- a/extras/hook-scripts/add-brick/post/Makefile.am ++++ b/extras/hook-scripts/add-brick/post/Makefile.am +@@ -1,6 +1,6 @@ +-EXTRA_DIST = disabled-quota-root-xattr-heal.sh S10selinux-label-brick.sh S13create-subdir-mounts.sh ++EXTRA_DIST = disabled-quota-root-xattr-heal.sh S13create-subdir-mounts.sh + + hookdir = $(GLUSTERD_WORKDIR)/hooks/1/add-brick/post/ + if WITH_SERVER +-hook_SCRIPTS = disabled-quota-root-xattr-heal.sh S10selinux-label-brick.sh S13create-subdir-mounts.sh ++hook_SCRIPTS = disabled-quota-root-xattr-heal.sh S13create-subdir-mounts.sh + endif +diff --git a/extras/hook-scripts/add-brick/post/S10selinux-label-brick.sh b/extras/hook-scripts/add-brick/post/S10selinux-label-brick.sh +deleted file mode 100755 +index 4a17c99..0000000 +--- a/extras/hook-scripts/add-brick/post/S10selinux-label-brick.sh ++++ /dev/null +@@ -1,100 +0,0 @@ +-#!/bin/bash +-# +-# Install to hooks//add-brick/post +-# +-# Add an SELinux file context for each brick using the glusterd_brick_t type. +-# This ensures that the brick is relabeled correctly on an SELinux restart or +-# restore. Subsequently, run a restore on the brick path to set the selinux +-# labels. +-# +-### +- +-PROGNAME="Sselinux" +-OPTSPEC="volname:,version:,gd-workdir:,volume-op:" +-VOL= +- +-parse_args () { +- ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@") +- eval set -- "${ARGS}" +- +- while true; do +- case ${1} in +- --volname) +- shift +- VOL=${1} +- ;; +- --gd-workdir) +- shift +- GLUSTERD_WORKDIR=$1 +- ;; +- --version) +- shift +- ;; +- --volume-op) +- shift +- ;; +- *) +- shift +- break +- ;; +- esac +- shift +- done +-} +- +-set_brick_labels() +-{ +- local volname="${1}" +- local fctx +- local list=() +- +- fctx="$(semanage fcontext --list -C)" +- +- # wait for new brick path to be updated under +- # ${GLUSTERD_WORKDIR}/vols/${volname}/bricks/ +- sleep 5 +- +- # grab the path for each local brick +- brickpath="${GLUSTERD_WORKDIR}/vols/${volname}/bricks/" +- brickdirs=$( +- find "${brickpath}" -type f -exec grep '^path=' {} \; | \ +- cut -d= -f 2 | \ +- sort -u +- ) +- +- # create a list of bricks for which custom SELinux +- # label doesn't exist +- for b in ${brickdirs}; do +- pattern="${b}(/.*)?" +- echo "${fctx}" | grep "^${pattern}\s" >/dev/null +- if [[ $? -ne 0 ]]; then +- list+=("${pattern}") +- fi +- done +- +- # Add a file context for each brick path in the list and associate with the +- # glusterd_brick_t SELinux type. +- for p in ${list[@]} +- do +- semanage fcontext --add -t glusterd_brick_t -r s0 "${p}" +- done +- +- # Set the labels for which SELinux label was added above +- for b in ${brickdirs} +- do +- echo "${list[@]}" | grep "${b}" >/dev/null +- if [[ $? -eq 0 ]]; then +- restorecon -R "${b}" +- fi +- done +-} +- +-SELINUX_STATE=$(which getenforce && getenforce) +-[ "${SELINUX_STATE}" = 'Disabled' ] && exit 0 +- +-parse_args "$@" +-[ -z "${VOL}" ] && exit 1 +- +-set_brick_labels "${VOL}" +- +-exit 0 +diff --git a/extras/hook-scripts/create/Makefile.am b/extras/hook-scripts/create/Makefile.am +deleted file mode 100644 +index b083a91..0000000 +--- a/extras/hook-scripts/create/Makefile.am ++++ /dev/null +@@ -1 +0,0 @@ +-SUBDIRS = post +diff --git a/extras/hook-scripts/create/post/Makefile.am b/extras/hook-scripts/create/post/Makefile.am +deleted file mode 100644 +index 919801a..0000000 +--- a/extras/hook-scripts/create/post/Makefile.am ++++ /dev/null +@@ -1,6 +0,0 @@ +-EXTRA_DIST = S10selinux-label-brick.sh +- +-scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/create/post/ +-if WITH_SERVER +-scripts_SCRIPTS = S10selinux-label-brick.sh +-endif +diff --git a/extras/hook-scripts/create/post/S10selinux-label-brick.sh b/extras/hook-scripts/create/post/S10selinux-label-brick.sh +index f9b4b1a..de242d2 100755 +--- a/extras/hook-scripts/create/post/S10selinux-label-brick.sh ++++ b/extras/hook-scripts/create/post/S10selinux-label-brick.sh +@@ -34,21 +34,18 @@ parse_args () { + + set_brick_labels() + { +- volname="${1}" ++ volname=${1} + + # grab the path for each local brick +- brickpath="/var/lib/glusterd/vols/${volname}/bricks/" +- brickdirs=$( +- find "${brickpath}" -type f -exec grep '^path=' {} \; | \ +- cut -d= -f 2 | \ +- sort -u +- ) ++ brickpath="/var/lib/glusterd/vols/${volname}/bricks/*" ++ brickdirs=$(grep '^path=' "${brickpath}" | cut -d= -f 2 | sort -u) + + for b in ${brickdirs}; do + # Add a file context for each brick path and associate with the + # glusterd_brick_t SELinux type. +- pattern="${b}(/.*)?" ++ pattern="${b}\(/.*\)?" + semanage fcontext --add -t glusterd_brick_t -r s0 "${pattern}" ++ + # Set the labels on the new brick path. + restorecon -R "${b}" + done +diff --git a/extras/hook-scripts/delete/Makefile.am b/extras/hook-scripts/delete/Makefile.am +deleted file mode 100644 +index c98a05d..0000000 +--- a/extras/hook-scripts/delete/Makefile.am ++++ /dev/null +@@ -1 +0,0 @@ +-SUBDIRS = pre +diff --git a/extras/hook-scripts/delete/pre/Makefile.am b/extras/hook-scripts/delete/pre/Makefile.am +deleted file mode 100644 +index 93a6b85..0000000 +--- a/extras/hook-scripts/delete/pre/Makefile.am ++++ /dev/null +@@ -1,6 +0,0 @@ +-EXTRA_DIST = S10selinux-del-fcontext.sh +- +-scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/delete/pre/ +-if WITH_SERVER +-scripts_SCRIPTS = S10selinux-del-fcontext.sh +-endif +diff --git a/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh b/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh +index e7f4e8f..6eba66f 100755 +--- a/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh ++++ b/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh +@@ -15,55 +15,45 @@ OPTSPEC="volname:" + VOL= + + function parse_args () { +- ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@") +- eval set -- "${ARGS}" +- +- while true; do +- case ${1} in +- --volname) +- shift +- VOL=${1} +- ;; +- *) ++ ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@") ++ eval set -- "$ARGS" ++ ++ while true; do ++ case $1 in ++ --volname) ++ shift ++ VOL=$1 ++ ;; ++ *) ++ shift ++ break ++ ;; ++ esac + shift +- break +- ;; +- esac +- shift +- done ++ done + } + + function delete_brick_fcontext() + { +- volname="${1}" +- +- # grab the path for each local brick +- brickpath="/var/lib/glusterd/vols/${volname}/bricks/" +- brickdirs=$( +- find "${brickpath}" -type f -exec grep '^path=' {} \; | \ +- cut -d= -f 2 | \ +- sort -u +- ) +- +- for b in ${brickdirs} +- do +- # remove the file context associated with the brick path +- pattern="${b}(/.*)?" +- semanage fcontext --delete "${pattern}" ++ volname=$1 + +- # remove the labels on brick path. +- restorecon -R "${b}" +- done ++ # grab the path for each local brick ++ brickdirs=$(grep '^path=' /var/lib/glusterd/vols/${volname}/bricks/* | cut -d= -f 2) + ++ for b in $brickdirs ++ do ++ # remove the file context associated with the brick path ++ semanage fcontext --delete $b\(/.*\)? ++ done + } + + SELINUX_STATE=$(which getenforce && getenforce) + [ "${SELINUX_STATE}" = 'Disabled' ] && exit 0 + + parse_args "$@" +-[ -z "${VOL}" ] && exit 1 ++[ -z "$VOL" ] && exit 1 + +-delete_brick_fcontext "${VOL}" ++delete_brick_fcontext $VOL + + # failure to delete the fcontext is not fatal + exit 0 +diff --git a/glusterfs.spec.in b/glusterfs.spec.in +index 012989a..671ee27 100644 +--- a/glusterfs.spec.in ++++ b/glusterfs.spec.in +@@ -1447,13 +1447,11 @@ exit 0 + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post + %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post/disabled-quota-root-xattr-heal.sh +- %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post/S10selinux-label-brick.sh + %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post/S13create-subdir-mounts.sh + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/pre + %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/pre/S28Quota-enable-root-xattr-heal.sh + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/post +- %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/post/S10selinux-label-brick.sh + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/pre + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/copy-file + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/copy-file/post +@@ -1462,7 +1460,6 @@ exit 0 + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/post + %{_sharedstatedir}/glusterd/hooks/1/delete/post/S57glusterfind-delete-post + %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/pre +- %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/pre/S10selinux-del-fcontext.sh + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/remove-brick + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/remove-brick/post + %ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/remove-brick/pre +diff --git a/tests/bugs/glusterfs-server/bug-877992.t b/tests/bugs/glusterfs-server/bug-877992.t +index 300000b..aeb73ed 100755 +--- a/tests/bugs/glusterfs-server/bug-877992.t ++++ b/tests/bugs/glusterfs-server/bug-877992.t +@@ -46,9 +46,7 @@ TEST $CLI volume create $V0 $H0:$B0/${V0}1; + EXPECT "$V0" volinfo_field $V0 'Volume Name'; + EXPECT 'Created' volinfo_field $V0 'Status'; + EXPECT 'createPre' cat /tmp/pre.out; +-# Spost.sh comes after S10selinux-label-brick.sh under create post hook script +-# list. So consider the delay in setting SELinux context on bricks +-EXPECT_WITHIN 5 'createPost' cat /tmp/post.out; ++EXPECT 'createPost' cat /tmp/post.out; + hooks_cleanup 'create' + + +diff --git a/tests/features/subdir-mount.t b/tests/features/subdir-mount.t +index a02bd6b..8401946 100644 +--- a/tests/features/subdir-mount.t ++++ b/tests/features/subdir-mount.t +@@ -85,17 +85,12 @@ TEST $CLI volume start $V0 + TEST $GFS --subdir-mount /subdir1/subdir1.1/subdir1.2 -s $H0 --volfile-id $V0 $M2 + TEST stat $M2 + +-initcnt=`grep -i create-subdir-mounts /var/log/glusterfs/glusterd.log | wc -l` + # mount shouldn't fail even after add-brick + TEST $CLI volume add-brick $V0 replica 2 $H0:$B0/${V0}{5,6}; + +-# Wait to execute create-subdir-mounts.sh script by glusterd +-newcnt=`grep -i create-subdir-mounts /var/log/glusterfs/glusterd.log | wc -l` +-while [ $newcnt -eq $initcnt ] +-do +- newcnt=`grep -i create-subdir-mounts /var/log/glusterfs/glusterd.log | wc -l` +- sleep 1 +-done ++# Give time for client process to get notified and use the new ++# volfile after add-brick ++sleep 1 + + # Existing mount should still be active + mount_inode=$(stat --format "%i" "$M2") +-- +1.8.3.1 + diff --git a/glusterfs.spec b/glusterfs.spec index ac3915a..7f5c77c 100644 --- a/glusterfs.spec +++ b/glusterfs.spec @@ -231,7 +231,7 @@ Release: 0.1%{?prereltag:.%{prereltag}}%{?dist} %else Name: glusterfs Version: 6.0 -Release: 24%{?dist} +Release: 25%{?dist} ExcludeArch: i686 %endif License: GPLv2 or LGPLv3+ @@ -645,6 +645,14 @@ Patch0333: 0333-rpc-Synchronize-slot-allocation-code.patch Patch0334: 0334-dht-log-getxattr-failure-for-node-uuid-at-DEBUG.patch Patch0335: 0335-tests-RHEL8-test-failure-fixes-for-RHGS.patch Patch0336: 0336-spec-check-and-return-exit-code-in-rpm-scripts.patch +Patch0337: 0337-fuse-Set-limit-on-invalidate-queue-size.patch +Patch0338: 0338-glusterfs-fuse-Reduce-the-default-lru-limit-value.patch +Patch0339: 0339-geo-rep-fix-integer-config-validation.patch +Patch0340: 0340-rpc-event_slot_alloc-converted-infinite-loop-after-r.patch +Patch0341: 0341-socket-fix-error-handling.patch +Patch0342: 0342-Revert-hooks-remove-selinux-hooks.patch +Patch0343: 0343-extras-hooks-syntactical-errors-in-SELinux-hooks-sci.patch +Patch0344: 0344-Revert-all-fixes-to-include-SELinux-hook-scripts.patch %description GlusterFS is a distributed file-system capable of scaling to several @@ -1858,7 +1866,6 @@ exit 0 %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post/disabled-quota-root-xattr-heal.sh - %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post/S10selinux-label-brick.sh %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post/S13create-subdir-mounts.sh %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/pre %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/pre/S28Quota-enable-root-xattr-heal.sh @@ -2373,6 +2380,9 @@ fi %endif %changelog +* Mon Dec 23 2019 Rinku Kothiya - 6.0-25 +- fixes bugs bz#1686800 bz#1763208 bz#1779696 bz#1781444 bz#1782162 + * Thu Nov 28 2019 Rinku Kothiya - 6.0-24 - fixes bugs bz#1768786